mirror of
https://github.com/kastdeur/dotfiles.git
synced 2024-11-18 01:13:31 +01:00
761 lines
23 KiB
Python
Executable file
761 lines
23 KiB
Python
Executable file
#!/usr/bin/python
|
|
r"""
|
|
db2vim [options] file.xml
|
|
|
|
SHORT OPTIONS
|
|
|
|
-d Prints some debugging information on stderr.
|
|
|
|
-s If given, the db2vim operates in a 'stict' conversion mode, i.e, any
|
|
element which does not have a handler defined for them it be
|
|
completeley ignored including all its children. Otherwise, db2vim will
|
|
recurse into an unknown tag and process any of its children it
|
|
recognizes. Since db2vim always recognizes text nodes, not using this
|
|
option has the effect that all text will be printed out, even if
|
|
somewhat incorrectly.
|
|
|
|
LONG OPTIONS
|
|
|
|
--prefix=<prefix>
|
|
This is a string like "ls_" which will be prepended to the section
|
|
numbers. Default to 'ls_' if unsupplied.
|
|
"""
|
|
|
|
|
|
import xml.dom.minidom
|
|
import getopt
|
|
import string
|
|
import re
|
|
import sys
|
|
|
|
# Okay. so I import *. Shoot me.
|
|
from textutils import *
|
|
from domutils import *
|
|
|
|
# define a bunch of constants for formatting.
|
|
TEXT_WIDTH = 80
|
|
BLOCK_QUOTE = 4
|
|
COL_SPACE = 2
|
|
|
|
# a bunch of globals used in creating the Table of contents.
|
|
#
|
|
# TOC_HASH['section 1.1 label'] = 'ls_1_1'
|
|
#
|
|
# LEVEL_HASH['section 1.1 label'] = 1
|
|
# (top level article has level 0)
|
|
#
|
|
# TITLE_HASH['section 1.1 label'] = 'Title of section 1.1'
|
|
#
|
|
# FILENAME = the name of the file being processed with the last extension
|
|
# changed to .txt
|
|
#
|
|
# TOC_PREFIX = 'ls_' (the prefix used to create the section labels).
|
|
TOC_HASH = {}
|
|
LEVEL_HASH = {}
|
|
TITLE_HASH = {}
|
|
FILENAME = ''
|
|
TOC_PREFIX = ''
|
|
|
|
ANCHOR_HASH = {}
|
|
URL_HASH = {}
|
|
|
|
# STDERR for printing debugging info.
|
|
DEBUG = 0
|
|
STDERR = sys.stderr
|
|
STRICT = 0
|
|
NUM_ANCHORS = {0:1}
|
|
|
|
################################################################################
|
|
# Miscellaneous utility functions
|
|
################################################################################
|
|
# encodeTo52(num) {{{
|
|
def encodeTo52(num):
|
|
ret = ''
|
|
|
|
if num < 26:
|
|
return unichr(ord('a') + num)
|
|
elif num < 52:
|
|
return unichr(ord('A') + num - 26)
|
|
else:
|
|
return encodeTo52(int(num/52)) + encodeTo52(num % 52)
|
|
# }}}
|
|
# makeTocHash(rootElement) {{{
|
|
def makeTocHash(rootElement, width, prefix='', level=0):
|
|
retText = ""
|
|
sectionsTable = []
|
|
lastLabelUsed = 0
|
|
|
|
for section in rootElement.getChildrenByTagName('section'):
|
|
title = section.getChildrenByTagName('title')[0]
|
|
titleText = handleElement(title, width)
|
|
lastLabelUsed += 1
|
|
thisLabel = TOC_PREFIX + prefix + str(lastLabelUsed)
|
|
|
|
sectionid = section.getAttribute('id')
|
|
if not sectionid:
|
|
section.setAttribute('id', thisLabel)
|
|
sectionid = thisLabel
|
|
|
|
NUM_ANCHORS[0] += 1
|
|
ANCHOR_HASH[sectionid] = TOC_PREFIX + 'a_' + encodeTo52(NUM_ANCHORS[0] + 52)
|
|
|
|
TOC_HASH[sectionid] = thisLabel
|
|
LEVEL_HASH[sectionid] = level
|
|
TITLE_HASH[sectionid] = titleText
|
|
|
|
if section.getChildrenByTagName('section'):
|
|
childText = makeTocHash(section, width - 5,
|
|
prefix = prefix+str(lastLabelUsed) + '_',
|
|
level = level + 1)
|
|
|
|
# }}}
|
|
# makeAnchorHash(rootElement) {{{
|
|
def makeAnchorHash(rootElement):
|
|
anchors = rootElement.getElementsByTagName('anchor') + rootElement.getElementsByTagName('note')
|
|
numAnchors = 0
|
|
for anchor in anchors:
|
|
if not anchor.getAttribute('id'):
|
|
continue
|
|
|
|
NUM_ANCHORS[0] += 1
|
|
if ANCHOR_HASH.has_key(anchor.getAttribute('id')) or TOC_HASH.has_key(anchor.getAttribute('id')):
|
|
print >> STDERR, "Warning: anchor [%s] multiply defined" % anchor.getAttribute('id')
|
|
|
|
ANCHOR_HASH[anchor.getAttribute('id')] = TOC_PREFIX + 'a_' + encodeTo52(NUM_ANCHORS[0] + 52)
|
|
|
|
# }}}
|
|
# makeURLHash(rootElement) {{{
|
|
def makeURLHash(rootElement):
|
|
urls = rootElement.getElementsByTagName('ulink')
|
|
numURLs = 0
|
|
for url in urls:
|
|
if not url.getAttribute('url') or URL_HASH.has_key(url.getAttribute('url')):
|
|
continue
|
|
numURLs += 1
|
|
URL_HASH[url.getAttribute('url')] = TOC_PREFIX + 'u_' + str(numURLs)
|
|
|
|
# }}}
|
|
# makeTOC(node, width, prefix='', level=0, maxleve=1): {{{
|
|
def makeTOC(node, width, maxlevel=1):
|
|
retText = ""
|
|
sectionsTable = []
|
|
lastLabelUsed = 0
|
|
|
|
for section in node.getChildrenByTagName('section'):
|
|
|
|
sectionid = section.getAttribute('id')
|
|
thisLabel = TOC_HASH.get(sectionid, '')
|
|
titleText = TITLE_HASH.get(sectionid, '')
|
|
level = LEVEL_HASH.get(sectionid, 10)
|
|
|
|
if level <= maxlevel:
|
|
retText += '|' + thisLabel + '| ' + titleText + '\n'
|
|
|
|
if level < maxlevel and section.getChildrenByTagName('section'):
|
|
childText = makeTOC(section, width-5)
|
|
retText += VertCatString(" ", 4, childText) + '\n'
|
|
|
|
retText = re.sub(r'\s+$', r'\n', retText)
|
|
|
|
return retText
|
|
# }}}
|
|
|
|
################################################################################
|
|
# Generalized function for handling dom elements.
|
|
################################################################################
|
|
# IsInlineTag(self): {{{
|
|
def IsInlineTag(self):
|
|
if self.nodeType == self.TEXT_NODE:
|
|
return 1
|
|
elif inlineTags.get(self.tagName, 0):
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
|
|
# }}}
|
|
# getChildrenByTagName(self, name): {{{
|
|
# Description: extension to the xml.dom.minidom.Element class.
|
|
# returns all direct descendants of this Element.
|
|
def getChildrenByTagName(self, name):
|
|
nodeList = []
|
|
|
|
child = self.firstChild
|
|
while not child is None:
|
|
if child.nodeType == child.ELEMENT_NODE and child.nodeName == name:
|
|
nodeList.append(child)
|
|
|
|
child = child.nextSibling
|
|
|
|
return nodeList
|
|
|
|
xml.dom.minidom.Element.getChildrenByTagName = getChildrenByTagName
|
|
|
|
|
|
# }}}
|
|
# handleElement(rootElement, width=TEXT_WIDTH): {{{
|
|
def handleElement(rootElement, width=TEXT_WIDTH):
|
|
"""
|
|
handleElement(rootElement, width=TEXT_WIDTH):
|
|
|
|
Generalized function to handle an Element node in a DOM tree.
|
|
"""
|
|
|
|
retText = ""
|
|
child = rootElement.firstChild
|
|
while not child is None:
|
|
|
|
printerr('node type = %d' % child.nodeType)
|
|
if child.nodeType == child.ELEMENT_NODE:
|
|
printerr('processing [%s]' % child.tagName)
|
|
|
|
isinline = IsInlineTag(child)
|
|
|
|
# if the child is an Element and if a handler exists, then call it.
|
|
if not isinline \
|
|
and child.nodeType == child.ELEMENT_NODE \
|
|
and handlerMaps.has_key(child.tagName):
|
|
# offset the child text by the current indentation value
|
|
printerr('making recursive call to known child.')
|
|
retText += handlerMaps[child.tagName](child, width)
|
|
child = child.nextSibling
|
|
|
|
elif not isinline \
|
|
and child.nodeType == child.PROCESSING_INSTRUCTION_NODE \
|
|
and child.target == 'vimhelp':
|
|
|
|
if handlerMaps.has_key(child.data):
|
|
retText += handlerMaps[child.data](child, width)
|
|
|
|
child = child.nextSibling
|
|
|
|
# if its a text node or an inline element node, collect consecutive
|
|
# text nodes into a single paragraph and indent it.
|
|
elif isinline:
|
|
|
|
text = ""
|
|
while not child is None and IsInlineTag(child):
|
|
if child.nodeType == child.TEXT_NODE:
|
|
text += child.data
|
|
elif child.nodeType == child.ELEMENT_NODE:
|
|
if handlerMaps.has_key(child.tagName):
|
|
text += handlerMaps[child.tagName](child, width)
|
|
else:
|
|
text += GetText(child.childNodes)
|
|
child = child.nextSibling
|
|
|
|
retText += IndentParagraphs(text, width)
|
|
|
|
# If we cannot understand _anything_ about the element, then just
|
|
# handle its children hoping we have something to gather from
|
|
# there.
|
|
elif not STRICT:
|
|
printerr('making recursive call for unkown child')
|
|
retText += handleElement(child, width)
|
|
child = child.nextSibling
|
|
|
|
else:
|
|
child = child.nextSibling
|
|
|
|
return retText
|
|
|
|
# }}}
|
|
|
|
################################################################################
|
|
# Functions for handling various xml tags
|
|
################################################################################
|
|
# handleArticleInfo(articleinfo, width): {{{
|
|
def handleArticleInfo(articleinfo, width):
|
|
|
|
makeTocHash(articleinfo.parentNode, width)
|
|
makeAnchorHash(articleinfo.parentNode)
|
|
makeURLHash(articleinfo.parentNode)
|
|
|
|
title = articleinfo.getChildrenByTagName('title')
|
|
if title is None:
|
|
print("Article should have a title!")
|
|
sys.exit(1)
|
|
|
|
name = GetText(title[0].childNodes)
|
|
authors = articleinfo.getChildrenByTagName('author')
|
|
|
|
authorText = ''
|
|
for author in authors:
|
|
firstname = ''
|
|
surname = ''
|
|
if author.getElementsByTagName('firstname'):
|
|
firstname = GetTextFromElementNode(author, 'firstname')[0]
|
|
if author.getChildrenByTagName('surname'):
|
|
surname = GetTextFromElementNode(author, 'surname')[0]
|
|
if author.getElementsByTagName('email'):
|
|
email = GetTextFromElementNode(author, 'email')[0]
|
|
authorText = authorText + firstname + ' ' + surname + ' <' + email + '>\n'
|
|
|
|
|
|
abstractText = ''
|
|
abstract = articleinfo.getChildrenByTagName('abstract')
|
|
if abstract is not None:
|
|
abstractText = '\n\n' + CenterText('Abstract\n========', width)
|
|
abstractText += handleElement(abstract[0], width) + '\n'
|
|
|
|
|
|
retText = CenterText(name + '\n*' + FILENAME + '*\n' + authorText, width)
|
|
retText += abstractText
|
|
|
|
toc = makeTOC(articleinfo.parentNode, width)
|
|
|
|
foldwarn = r'''
|
|
================================================================================
|
|
Viewing this file
|
|
|
|
This file can be viewed with all the sections and subsections folded to ease
|
|
navigation. By default, vim does not fold help documents. To create the folds,
|
|
press za now. The folds are created via a foldexpr which can be seen in the
|
|
last section of this file.
|
|
|
|
See |usr_28.txt| for an introduction to folding and |fold-commands| for key
|
|
sequences and commands to work with folds.
|
|
'''
|
|
|
|
return retText + '\n' + RightJustify('*' + FILENAME + '-toc*', width) + '\n' + toc + foldwarn
|
|
|
|
# }}}
|
|
# handleOption(option, width): {{{
|
|
def handleOption(option, width):
|
|
retText = ""
|
|
names = GetTextFromElementNode(option, "name")
|
|
|
|
for name in names:
|
|
retText += string.rjust("*"+name+"*", width) + "\n"
|
|
|
|
nameTexts = ""
|
|
maxNameLen = -1
|
|
for name in names:
|
|
maxNameLen = max(maxNameLen, len(name + " "))
|
|
nameTexts += name + " \n"
|
|
|
|
desc = option.getChildrenByTagName("desc")[0]
|
|
descText = handleElement(desc, width=width-maxNameLen)
|
|
|
|
retText += VertCatString(nameTexts + " ", None, descText)
|
|
|
|
return retText + "\n"
|
|
|
|
# }}}
|
|
# handleOptionDefault(default, width): {{{
|
|
def handleOptionDefault(default, width):
|
|
type = string.join(GetTextFromElementNode(default, "type"), "\n")
|
|
extra = string.join(GetTextFromElementNode(default, "extra"), "\n")
|
|
return type + "\t(" + extra + ")"
|
|
|
|
# }}}
|
|
# handleTableRoot(root, width): {{{
|
|
def handleTableRoot(root, width):
|
|
tgroup = root.getChildrenByTagName('tgroup')[0]
|
|
if tgroup is None:
|
|
return ''
|
|
|
|
rows = []
|
|
numHeadRows = 0
|
|
if tgroup.getChildrenByTagName('thead'):
|
|
thead = tgroup.getChildrenByTagName('thead')[0]
|
|
rows = thead.getChildrenByTagName('row')
|
|
numHeadRows = len(rows)
|
|
|
|
tbody = tgroup.getChildrenByTagName('tbody')[0]
|
|
rows += tbody.getChildrenByTagName('row')
|
|
|
|
widths, text = calculateColumnWidthsDoublePass(rows, width)
|
|
|
|
headText = text[0:numHeadRows]
|
|
bodyText = text[numHeadRows:]
|
|
|
|
headTable = FormatTable(headText, ROW_SPACE = 1, COL_SPACE =
|
|
COL_SPACE, justify = 0, widths = widths)
|
|
if headTable:
|
|
headTable = re.sub(r'\n|$', '\g<0>~', headTable)
|
|
bodyTable = FormatTable(bodyText, ROW_SPACE = 1, COL_SPACE =
|
|
COL_SPACE, justify = 0, widths = widths)
|
|
|
|
return headTable + '\n'+ re.sub(r'\n+$', '', bodyTable) + '\n\n'
|
|
|
|
# calculateColumnWidths(rows, width): {{{
|
|
def calculateColumnWidths(rows, alloc_widths):
|
|
widths = {}
|
|
text = []
|
|
for row in rows:
|
|
cols = row.getChildrenByTagName("entry")
|
|
if len(alloc_widths) == 1:
|
|
alloc_widths *= len(cols)
|
|
|
|
colwidths = []
|
|
rowtext = []
|
|
for col, width in zip(cols, alloc_widths):
|
|
coltext = handleElement(col, width)
|
|
|
|
rowtext.append(coltext)
|
|
# This is the 'width' of the current cell including the
|
|
# whitespace padding.
|
|
colwidths.append(max(map(len, coltext.split("\n"))) \
|
|
+ COL_SPACE)
|
|
|
|
text.append(rowtext)
|
|
|
|
# update the widths of the columns by finding the maximum
|
|
# width of all cells in this column.
|
|
for i in range(len(colwidths)):
|
|
widths[i] = max(colwidths[i], widths.get(i, -1))
|
|
|
|
return widths, text
|
|
|
|
# }}}
|
|
# calculateColumnWidthsDoublePass(rows, width): {{{
|
|
def calculateColumnWidthsDoublePass(rows, width):
|
|
maxwidths, text = calculateColumnWidths(rows, [width])
|
|
if reduce(lambda x, y: x+y, maxwidths.values()) <= width:
|
|
return maxwidths, text
|
|
|
|
# now find out how many columns exceed the maximum permitted width.
|
|
# nlarge: number of columns which are too wide.
|
|
# remainingWidth: width which these large columns can share.
|
|
nlarge = 0
|
|
remainingWidth = width
|
|
for colwidth in maxwidths.values():
|
|
if colwidth > width/len(maxwidths):
|
|
nlarge += 1
|
|
else:
|
|
remainingWidth += -colwidth
|
|
|
|
# newmaxwidth: width which each of the large columns is allowed.
|
|
newmaxwidth = remainingWidth/max(nlarge, 1)
|
|
|
|
newcolwidths = []
|
|
for colwidth in maxwidths.values():
|
|
newcolwidths += [min(colwidth, newmaxwidth)]
|
|
|
|
# make another run and this time ask each cell to restrict itself to
|
|
# newmaxwidth as calculated above.
|
|
newmaxwidth, newtext = calculateColumnWidths(rows, newcolwidths)
|
|
|
|
return newmaxwidth, newtext
|
|
|
|
# }}}
|
|
# }}}
|
|
# handleCode(code, width): {{{
|
|
def handleCode(code, width):
|
|
retText = GetText(code.childNodes)
|
|
return " &codebegin;\n" + VertCatString(" ", 4, retText) + "&codeend;"
|
|
|
|
|
|
# }}}
|
|
# handleList(list, width, marker=0): {{{
|
|
def handleList(list, width, marker=0):
|
|
if list.tagName == 'simplelist':
|
|
child = 'member'
|
|
decoration = ''
|
|
elif list.tagName == 'orderedlist':
|
|
child = 'listitem'
|
|
else:
|
|
child = 'member'
|
|
decoration = '- '
|
|
|
|
retText = ""
|
|
items = list.getChildrenByTagName(child)
|
|
i = 1
|
|
|
|
for item in items:
|
|
if list.tagName == 'orderedlist':
|
|
decoration = str(i) + '. '
|
|
i = i + 1
|
|
itemText = handleElement(item, width - len(decoration))
|
|
itemText = VertCatString(decoration, None, itemText)
|
|
|
|
retText += '\n' + re.sub(r'\s+$', '', itemText) + "\n"
|
|
|
|
return retText
|
|
|
|
# }}}
|
|
# handleNote(note, width): {{{
|
|
def handleNote(note, width):
|
|
title = None
|
|
if note.getChildrenByTagName('title'):
|
|
title = note.getChildrenByTagName('title')[0]
|
|
name = GetText(title.childNodes)
|
|
note.removeChild(title)
|
|
|
|
noteid = ''
|
|
if note.getAttribute('id'):
|
|
noteTagText = '*' + note.getAttribute('id') + '* '
|
|
noteTagText += '*' + ANCHOR_HASH[note.getAttribute('id')] + '*'
|
|
noteTagText = IndentParagraphs(noteTagText, width/2)
|
|
noteid = RightJustify(noteTagText, width) + '\n'
|
|
|
|
noteText = handleElement(note, width-len("NOTE: "))
|
|
if title is not None:
|
|
noteText = name + '\n' +('-' * len(name)) + '\n' + noteText
|
|
|
|
noteText = noteid + VertCatString("NOTE: ", None, noteText)
|
|
|
|
return noteText + "\n"
|
|
|
|
# }}}
|
|
# handleParagraph(paragraph, width): {{{
|
|
def handleParagraph(paragraph, width):
|
|
partext = handleElement(paragraph, width)
|
|
|
|
partext = re.sub(r'\n+$', '', partext)
|
|
partext = re.sub(r'^\n+', '', partext)
|
|
|
|
return partext + "\n\n"
|
|
|
|
# }}}
|
|
# handleFormalParagraph(paragraph, width): {{{
|
|
def handleFormalParagraph(formalparagraph, width):
|
|
title = None
|
|
if formalparagraph.getChildrenByTagName('title'):
|
|
title = formalparagraph.getChildrenByTagName('title')[0]
|
|
name = GetText(title.childNodes)
|
|
formalparagraph.removeChild(title)
|
|
|
|
partext = handleElement(formalparagraph, width)
|
|
|
|
partext = re.sub(r'\n+$', '', partext)
|
|
partext = re.sub(r'^\n+', '', partext)
|
|
if title is not None:
|
|
partext = name + '\n' + ('-' * len(name)) + '\n' + partext
|
|
|
|
return partext + "\n\n"
|
|
|
|
# }}}
|
|
# handleBlockQuote(block, width): {{{
|
|
def handleBlockQuote(block, width):
|
|
text = handleElement(block, width - BLOCK_QUOTE)
|
|
text = VertCatString(" "*BLOCK_QUOTE, \
|
|
BLOCK_QUOTE, text)
|
|
|
|
return text + "\n"
|
|
|
|
# }}}
|
|
# handleLink(link, width): {{{
|
|
def handleLink(link, width):
|
|
linkend = link.getAttribute('linkend')
|
|
if not ANCHOR_HASH.has_key(linkend):
|
|
print >> STDERR, "Warning: Link ID [%s] not found in TOC" % linkend
|
|
text = handleElement(link, width)
|
|
anchorpt = ANCHOR_HASH.get(linkend)
|
|
if not anchorpt:
|
|
anchorpt = ''
|
|
|
|
return text + ' [|' + anchorpt + '|]'
|
|
|
|
# }}}
|
|
# handleAnchor(anchor, width): {{{
|
|
def handleAnchor(anchor, width):
|
|
anchorText = '*'+anchor.getAttribute('id')+'* '
|
|
anchorText += '*'+ANCHOR_HASH[anchor.getAttribute('id')]+'*'
|
|
return RightJustify(anchorText, width) \
|
|
+ "\n"
|
|
|
|
# }}}
|
|
# handleSection(section, width): {{{
|
|
def handleSection(section, width):
|
|
title = section.getChildrenByTagName('title')[0]
|
|
name = handleElement(title, width)
|
|
|
|
sectionid = section.getAttribute('id')
|
|
tagsformatted = ''
|
|
if TOC_HASH.has_key(sectionid):
|
|
tagsformatted = '*%s* ' % TOC_HASH[sectionid]
|
|
|
|
if ANCHOR_HASH.has_key(sectionid):
|
|
tagsformatted += '*%s* ' % ANCHOR_HASH[sectionid]
|
|
|
|
if sectionid and TOC_HASH.has_key(sectionid) and sectionid != TOC_HASH[sectionid]:
|
|
tagsformatted += '*%s*' % sectionid
|
|
|
|
# try to indent to a width of 20
|
|
tagsformatted = RightJustify(IndentParagraphs(tagsformatted, 30), 0)
|
|
tagswidth = TextWidth(tagsformatted)
|
|
|
|
# width(name) + nspaces + width(tags) = 80
|
|
if len(tagsformatted) > 2:
|
|
header = VertCatString(name, 80-tagswidth, tagsformatted)
|
|
else:
|
|
header = name
|
|
|
|
section.removeChild(title)
|
|
text = handleElement(section, width)
|
|
|
|
thislevel = LEVEL_HASH.get(sectionid, -1)
|
|
if thislevel == 0:
|
|
delim = '='
|
|
newlines = '\n\n'
|
|
elif thislevel == 1:
|
|
delim = '-'
|
|
newlines = '\n'
|
|
else:
|
|
delim = ''
|
|
newlines = '\n'
|
|
|
|
thisTOC = ''
|
|
if thislevel <= 1:
|
|
thisTOC = makeTOC(section, width, maxlevel=1)
|
|
|
|
return "\n" + (delim * TEXT_WIDTH) + \
|
|
"\n" + header + newlines + thisTOC + newlines + re.sub(r'\n+$', '', text) + "\n"
|
|
|
|
# }}}
|
|
# handleUlink(ulink, width) {{{
|
|
def handleUlink(ulink, width):
|
|
url = ulink.getAttribute('url')
|
|
text = handleElement(ulink)
|
|
# URL_HASH is created at the very beginning
|
|
if url:
|
|
return text + ' |%s|' % URL_HASH[url]
|
|
else:
|
|
print >> STDERR, "Warning: url attribute empty for [%s]" % text
|
|
return text
|
|
|
|
# }}}
|
|
# handleIndexTerm(indexterm, width) {{{
|
|
def handleIndexTerm(indexterm, width) :
|
|
return ''
|
|
# }}}
|
|
# handleEmphasis(emphasis, width) {{{
|
|
def handleEmphasis(emphasis, width):
|
|
return '_' + GetText(emphasis.childNodes) + '_'
|
|
# }}}
|
|
|
|
################################################################################
|
|
# A dictionary for mapping xml tags to functions.
|
|
################################################################################
|
|
# {{{
|
|
handlerMaps = {
|
|
'articleinfo': handleArticleInfo,
|
|
'table': handleTableRoot,
|
|
'informaltable': handleTableRoot,
|
|
'code': handleCode,
|
|
'programlisting': handleCode,
|
|
'list': handleList,
|
|
'simplelist': handleList,
|
|
'orderedlist': handleList,
|
|
'para': handleParagraph,
|
|
'formalpara': handleFormalParagraph,
|
|
'note': handleNote,
|
|
'link': handleLink,
|
|
'anchor': handleAnchor,
|
|
'section': handleSection,
|
|
'blockquote': handleBlockQuote,
|
|
'ulink': handleUlink,
|
|
'emphasis': handleEmphasis,
|
|
'indexterm': handleIndexTerm
|
|
}
|
|
inlineTags = {'tag':1, 'literal':1, 'link':1,
|
|
'ulink':1, 'citetitle':1, 'indexterm':1,
|
|
'emphasis':1, 'filename':1 }
|
|
# }}}
|
|
|
|
# helper functions for usage() and printerr() {{{
|
|
def usage():
|
|
print __doc__
|
|
|
|
def printerr(statement):
|
|
if DEBUG:
|
|
print >> STDERR, statement
|
|
|
|
# }}}
|
|
# replaceComment(matchobj) {{{
|
|
def replaceComment(matchobj):
|
|
initspace = matchobj.group(1)
|
|
firstsent = matchobj.group(2)
|
|
code = matchobj.group(3)
|
|
|
|
if len(initspace) > 0:
|
|
if initspace[0] == '<':
|
|
lastspace = initspace
|
|
else:
|
|
lastspace = '<' + initspace[:-1]
|
|
else:
|
|
lastspace = initspace
|
|
|
|
return '\n' + initspace + firstsent + ' >\n' + code + '\n' + lastspace
|
|
|
|
# }}}
|
|
# main function {{{
|
|
if __name__ == "__main__":
|
|
option = {}
|
|
try:
|
|
opts, args = getopt.getopt(sys.argv[1:], 'ds', ['prefix=', 'help'])
|
|
for oa, ov in opts:
|
|
option[oa] = ov
|
|
|
|
except getopt.GetoptError:
|
|
print >> STDERR, "Usage error: db2vim --help for usage"
|
|
sys.exit(1)
|
|
|
|
if option.has_key('--help'):
|
|
usage();
|
|
sys.exit(0);
|
|
|
|
TOC_PREFIX = option.get('--prefix', 'ls_')
|
|
DEBUG = option.has_key('-d')
|
|
|
|
if len(args) != 1:
|
|
print >> STDERR, "Usage error: db2vim --help for usage"
|
|
sys.exit(1)
|
|
|
|
fileName = args[0]
|
|
FILENAME = re.sub(r'\.\w+$', r'.txt', fileName)
|
|
|
|
try:
|
|
fp = open(fileName)
|
|
except:
|
|
print "Error opening xml file"
|
|
|
|
dom = xml.dom.minidom.parse(fp)
|
|
|
|
modeline = r'''
|
|
================================================================================
|
|
About this file
|
|
|
|
This file was created automatically from its XML variant using db2vim. db2vim is
|
|
a python script which understands a very limited subset of the Docbook XML 4.2
|
|
DTD and outputs a plain text file in vim help format.
|
|
|
|
db2vim can be obtained via anonymous CVS from sourceforge.net. Use
|
|
|
|
cvs -d:pserver:anonymous@cvs.vim-latex.sf.net:/cvsroot/vim-latex co db2vim
|
|
|
|
Or you can visit the web-interface to sourceforge CVS at:
|
|
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/vim-latex/db2vim/
|
|
|
|
The following modelines should nicely fold up this help manual.
|
|
|
|
vim:ft=help:fdm=expr:nowrap
|
|
vim:foldexpr=getline(v\:lnum-1)=~'-\\{80}'?'>2'\:getline(v\:lnum-1)=~'=\\{80}'?'>1'\:getline(v\:lnum)=~'=\\{80}'?'0'\:getline(v\:lnum)=~'-\\{80}'?'1'\:'='
|
|
vim:foldtext=substitute(v\:folddashes.substitute(getline(v\:foldstart),'\\s*\\*.*',"",""),'^--','\ \ \ \ \ \ ','')
|
|
================================================================================'''
|
|
|
|
STRICT = option.has_key('-s')
|
|
|
|
pattern = re.compile(r'\n([< ]*)([^\n]+)&codebegin;\n(.*?)&codeend;', re.DOTALL)
|
|
|
|
processedDoc = handleElement(dom.documentElement)
|
|
while re.search('&codebegin;', processedDoc):
|
|
processedDoc = re.sub(pattern, replaceComment, processedDoc)
|
|
|
|
urlsection = r"""
|
|
================================================================================
|
|
URLs used in this file
|
|
|
|
"""
|
|
labels = zip(URL_HASH.values(), URL_HASH.keys())
|
|
labels.sort()
|
|
for label, url in labels:
|
|
urlsection += '*%s* : %s\n' % (label, url)
|
|
|
|
processedDoc = processedDoc + urlsection + modeline
|
|
print processedDoc.encode('iso-8859-1')
|
|
|
|
# }}}
|
|
# vim:et:sts=4:fdm=marker
|