Given a document tree, this function finds all the literate program elements, attempts to open output files for them if they are not already open, and writes the code fragments to those files.
# - - - p r o c e s s D o c
def processDoc ( fileMap, doc ):
"""Process one document tree
[ (fileMap is a dictionary whose keys are file names and
each corresponding value is a writeable file handle
for that file) and
(doc is an etree.ElementTree) ->
fileMap := fileMap with new output files added from
lit-elts in doc whose lit-dests can be opened anew
files named in fileMap := lit-content of those files
sys.stderr +:= error messages for lit-dests that
cannot be opened for output, if any ]
"""
To find the root element of doc, we use
its .getroot() method. Then we use an
XPath expression to find all the PROG_ELT
elements. The XPath expression "//programlisting" means to find all programlisting elements no matter where they are
in the tree; it returns a list of matching elements.
#-- 1 --
# [ eltList := a list of all the PROG_ELT elements in doc,
# in document order ]
root = doc.getroot()
eltList = root.xpath ( "//" + PROG_ELT )
For each potentially literate element, we look to see if
it has a ROLE_ATTR attribute, and if so,
whether that attribute's value starts with ROLE_PREFIX. If so, it is a literate element,
and is sent for processing to Section 4.9, “processElt(): Process one literate
element”.
#-- 2 --
# [ fileMap := fileMap with new file names added from lit-dests
# in eltList whose lit-dest files could be opened
# files named in fileMap := lit-content of those files
# sys.stderr +:= error messages from failures to open
# those files, if any ]
for elt in eltList:
#-- 2 body --
# [ if (elt is a lit-elt) and
# (lit-dest(elt) is a key in fileMap) ->
# that value from fileMap +:= lit-content(elt)
# else if (elt is a lit-elt) and
# (lit-dest(elt) is not a key in fileMap) and
# (a new file named lit-dest(elt) can be opened for
# writing) ->
# fileMap[lit-dest(elt)] := that new file
# that new file +:= lit-content(elt)
# else if (elt is a lit-elt) and
# (lit-dest(elt) is not a key in fileMap) and
# (a new file named lit-dest(elt) cannot be opened for
# writing) ->
# sys.stderr +:= error message
# else -> I ]
Several conditions must be met for a literate element.
There must be a ROLE_ATTR attribute; if
not, trying to extract the element's .attrib dictionary's value will raise KeyError.
If there is such an attribute, it must start with ROLE_PREFIX; if it does, the output file name is
the rest of the attribute after that prefix.
try:
attrValue = elt.attrib[ROLE_ATTR]
if attrValue.startswith ( ROLE_PREFIX ):
outName = attrValue[len(ROLE_PREFIX):]
processElt ( fileMap, outName, elt )
except KeyError:
pass