Skip to content

Instantly share code, notes, and snippets.

@rwinch
Created October 4, 2013 21:16
Show Gist options
  • Save rwinch/7f16a88727b6646eceeb to your computer and use it in GitHub Desktop.
Save rwinch/7f16a88727b6646eceeb to your computer and use it in GitHub Desktop.
Script for approximate conversion of Docbook to Asciidoctor modified for Spring
import javax.xml.parsers.SAXParserFactory
import org.xml.sax.helpers.DefaultHandler
import org.xml.sax.*
String EOL = "---EOL---"
File doc = new File("/home/rwinch/git/spring-framework/src/reference/docbook/index.xml")
class Docbook5Handler extends DefaultHandler {
File doc
def ignored = ['firstname','term','lastname','example','lineannotation','caption','surname','copyright','year','legalnotice','book','title','subtitle', 'authorgroup', 'author','personname','productname','releaseinfo','toc','partintro','itemizedlist','tgroup','colspec','thead','tbody','mediaobject','imageobject','info']
def sections = []
def currentSection = new Section()
def qName
def attrs
def sectionIndent = 0
def EOL = "\n"
def calloutNumber = 0
Docbook5Handler(File doc) {
this.doc = doc
}
void startElement(String ns, String localName, String qName, Attributes attrs) {
if(isSection(qName)) {
/*def space = (" " * sectionIndent)
println space + "<$qName>"*/
def removeLast = currentSection.title.contains("TBD")
if(removeLast) {
def lastSection = currentSection
sections.remove(lastSection)
currentSection = new Section(id: lastSection.id)
} else {
currentSection = new Section()
}
sectionIndent++
currentSection.id = attrs.getValue('xml:id') ?: 'TBD'
currentSection.indent = sectionIndent
sections.add(currentSection)
} else if(isCode(qName)) {
currentSection.content += "`"
} else if(qName == "anchor") {
def id = attrs.getValue("id")
currentSection.content += "${EOL}${EOL}[["+id+"]]${EOL}"
} else if(qName == "co") {
calloutNumber++
currentSection.content += " <<$calloutNumber>>$EOL"
} else if(qName == "calloutlist") {
calloutNumber = 0
} else if(qName == "callout") {
calloutNumber++
currentSection.content += "$EOL<<$calloutNumber>> "
} else if(qName == "quote") {
currentSection.content += '"'
} else if(qName == "note") {
currentSection.content += """${EOL}[NOTE]${EOL}====${EOL}"""
} else if(qName == "para") {
if(!currentSection.content.endsWith("* ") && !currentSection.content.endsWith("* ")) {
// currentSection.content += """${EOL}"""
}
} else if(qName == "tip") {
currentSection.content += """${EOL}[TIP]${EOL}====${EOL}"""
} else if(qName == "remark") {
currentSection.content += """${EOL}[INFO]${EOL}====${EOL}"""
} else if(qName == "warning") {
currentSection.content += """${EOL}[WARN]${EOL}====${EOL}"""
} else if(qName == "important") {
currentSection.content += """${EOL}[IMPORTANT]${EOL}====${EOL}"""
} else if(qName == "literallayout") {
currentSection.content += """${EOL}----${EOL}"""
} else if(qName == "sidebar") {
currentSection.content += """${EOL}****${EOL}"""
} else if(qName == "footnote") {
currentSection.content += " footnote:["
} else if(isItalic(qName)) {
currentSection.content += "__"
} else if(qName == "programlisting") {
def language = attrs.getValue("language")
def codeStyle = language ? "," + language : ""
currentSection.content += """${EOL}${EOL}[source${codeStyle}]${EOL}----${EOL}"""
} else if(qName == "computeroutput") {
currentSection.content += """${EOL}${EOL}[source]${EOL}----${EOL}"""
} else if(["variablelist","itemizedlist","orderedlist"].contains(qName)) {
currentSection.content += "${EOL}${EOL}"
} else if(["listitem","varlistentry"].contains(qName)) {
if(!currentSection.content.endsWith("* ")) {
currentSection.content += "* "
}
} else if(qName == "figure") {
currentSection.content += "${EOL}"
} else if(qName == "imagedata") {
def href = attrs.getValue("fileref")
currentSection.content += "image::$href[]${EOL}${EOL}"
}else if(["table","informaltable"].contains(qName)) {
currentSection.content += "${EOL}${EOL}|==="
} else if(qName == "row") {
// currentSection.content += "${EOL}"
} else if(qName == "entry") {
currentSection.content += "${EOL}| "
} else if(qName == "xi:include") {
def name = attrs.getValue("href")
def handler = new Docbook5Handler(new File(doc.parent, name))
handler.sectionIndent = sectionIndent
sections += handler.parseSections()
// currentSection.content += "${EOL}include::"+name+"[]${EOL}"
} else if(isLink(qName)) {
def crossRef = attrs.getValue("linkend")
if(crossRef) {
currentSection.content += "<<${crossRef},"
} else {
def href = attrs.getValue("xlink:href")
currentSection.content += "$href["
}
} else if (ignored.contains(qName)) {
// ignore
} else {
throw new RuntimeException("Unhandled in "+doc+ " at "+qName)
}
this.attrs = attrs
this.qName = qName
}
void characters(char[] chars, int offset, int length) {
def content = new String(chars, offset, length)
if(!" ".equals(content) && content.trim().equals("")) {
return
}
if(qName != 'programlisting' && qName != 'computeroutput' && qName != 'literallayout') {
content = content.replaceAll("\\n\\s+", " ")
}
if (qName == "title") {
currentSection.title += content
} else {
currentSection.content += content
}
}
void endElement(String ns, String localName, String qName) {
if(isSection(qName)) {
/*def space = (" " * sectionIndent)
println space + "</$qName>"*/
/*sections.add(currentSection)
currentSection = new Section()
currentSection.indent = sectionIndent*/
sectionIndent--
} else if(isCode(qName)) {
currentSection.content += "`"
} else if(qName == "para") {
currentSection.content += """${EOL}"""
} else if(qName == "calloutlist") {
calloutNumber = 0
currentSection.content += "$EOL"
} else if(qName == "quote") {
currentSection.content += '"'
} else if(qName == "note") {
currentSection.content += """${EOL}====${EOL}"""
} else if(qName == "tip") {
currentSection.content += """${EOL}====${EOL}"""
} else if(qName == "warning") {
currentSection.content += """${EOL}====${EOL}"""
} else if(qName == "important") {
currentSection.content += """${EOL}====${EOL}"""
} else if(qName == "remark") {
currentSection.content += """${EOL}====${EOL}"""
} else if(qName == "literallayout") {
currentSection.content += """${EOL}----${EOL}"""
} else if(qName == "sidebar") {
currentSection.content += """${EOL}****${EOL}"""
} else if(qName == "footnote") {
currentSection.content += "]"
} else if(isItalic(qName)) {
currentSection.content += "__"
} else if(["itemizedlist","orderedlist"].contains(qName)) {
currentSection.content += "${EOL}"
} else if(qName == "listitem") {
currentSection.content += "${EOL}"
} else if(qName == "row") {
currentSection.content += "${EOL}"
} else if(qName == "table") {
currentSection.content += "|===${EOL}${EOL}"
} else if(qName == "programlisting") {
currentSection.content += "${EOL}----${EOL}${EOL}"
qName = "dummy"
} else if(qName == "computeroutput") {
currentSection.content += "${EOL}----${EOL}${EOL}"
qName = "dummy"
} else if(qName == "figure") {
currentSection.content += "${EOL}"
} else if(isLink(qName)) {
def crossRef = attrs.getValue("linkend")
if(crossRef) {
if(currentSection.content.endsWith(",")) {
currentSection.content = currentSection.content.substring(0, currentSection.content.length() - 1)
}
currentSection.content += ">>"
} else {
def href = attrs.getValue("xlink:href")
if(!href) {
href = attrs.getValue("url")
}
currentSection.content += "]"
}
}
}
def isItalic(qName) {
["citetitle","emphasis",'firstterm'].contains(qName)
}
def isLink(qName) {
["link","xref","uri",'ulink'].contains(qName)
}
def isCode(qName) {
["classname","screen","command","type","constant","varname","function","interfacename",'filename','literal','methodname','code','exceptionname','package','property','parameter'].contains(qName)
}
def isSection(qName) {
return ['formalpara','part','preface','chapter', 'section','appendix'].contains(qName)
}
def isTitle(qName) {
return ['title'].contains(qName)
}
def parseSections() {
def reader = SAXParserFactory.newInstance().newSAXParser().XMLReader
reader.setContentHandler(this)
reader.parse(new InputSource(new FileInputStream(doc)))
sections
}
}
class Section {
def id = ""
def indent
def title = ""
def content = ""
def getFormattedTitle() {
def t = title ?: "TBD"
("=" * indent) + " " + t.replaceAll("\\n","")
}
def getFormattedContent() {
content.replaceFirst("^\\s+", "")
}
}
def handler = new Docbook5Handler(doc)
println """= Spring Security Reference
:author: Ben Alex, Luke Taylor, Rob Winch
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
"""
handler.parseSections().each { section->
if(section.id != "TBD") {
println "[[$section.id]]"
}
println section.formattedTitle
println section.formattedContent
println ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment