Next / Previous / Contents / Shipman's homepage

4.8. processDoc(): Process one document tree

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.

litlxml
# - - -   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.

litlxml
    #-- 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”.

litlxml
    #-- 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.

litlxml
        try:
            attrValue  =  elt.attrib[ROLE_ATTR]
            if  attrValue.startswith ( ROLE_PREFIX ):
                outName  =  attrValue[len(ROLE_PREFIX):]
                processElt ( fileMap, outName, elt )
        except KeyError:
            pass