def _handleToken(self, theS, t, tt): logging.debug('_handleToken(): "%s", %s', t, tt) if tt == 'whitespace': self._writeTextWithNewlines(theS, t, None) elif tt in ('C comment', 'C++ comment'): self._writeTextWithNewlines(theS, t, TokenCss.retClass(tt)) elif False and tt == 'preprocessing-op-or-punc': theS.characters(t) else: if tt == 'identifier' and t in self._macroRefMap: # As we can not definitively determine which particular # definition of the macro is relevant for this source file # we just use the last definition in the list. assert len(self._macroRefMap[t]) > 0 href = self._macroRefMap[t][-1][2] with XmlWrite.Element(theS, 'a', {'href' : href}): with XmlWrite.Element(theS, 'span', {'class' : '%s' % TokenCss.retClass(tt)}): theS.characters(t) else: with XmlWrite.Element(theS, 'span', {'class' : '%s' % TokenCss.retClass(tt)}): self._lineNum += t.count('\n') theS.characters(t)
def processTuToHtml(theLex, theHtmlPath, theTitle, theCondLevel, theIdxPath, incItuAnchors=True): """Processes the PpLexer and writes the tokens to the HTML file. *theHtmlPath* The path to the HTML file to write. *theTitle* A string to go into the <title> element. *theCondLevel* The Conditional level to pass to theLex.ppTokens() *theIdxPath* Path to link back to the index page. *incItuAnchors* boolean, if True will write anchors for lines in the ITU that are in this TU. If True then setItuLineNumbers returned is likely to be non-empty. Returns a pair of (PpTokenCount.PpTokenCount(), set(int)) The latter is a set of integer line numbers in the ITU that are in the TU, these line numbers with have anchors in this HTML file of the form: <a name="%d" />.""" if not os.path.exists(os.path.dirname(theHtmlPath)): os.makedirs(os.path.dirname(theHtmlPath)) LINE_FIELD_WIDTH = 8 LINE_BREAK_LENGTH = 100 # Make a global token counter (this could be got from the file include graph # but this is simpler. myTokCntr = PpTokenCount.PpTokenCount() # Write CSS TokenCss.writeCssToDir(os.path.dirname(theHtmlPath)) # Set of active lines of the ITU (only) that made it into the TU setItuLineNumbers = set() # Process the TU with XmlWrite.XhtmlStream(theHtmlPath, mustIndent=cpip.INDENT_ML) as myS: with XmlWrite.Element(myS, 'head'): with XmlWrite.Element( myS, 'link', { 'href' : TokenCss.TT_CSS_FILE, 'type' : "text/css", 'rel' : "stylesheet", } ): pass with XmlWrite.Element(myS, 'title'): myS.characters(theTitle) myIntId = 0 with XmlWrite.Element(myS, 'body'): with XmlWrite.Element(myS, 'h1'): myS.characters('Translation Unit: %s' % theLex.tuFileId) with XmlWrite.Element(myS, 'p'): myS.characters("""An annotated version of the translation unit with minimal whitespace. Indentation is according to the depth of the #include stack. Line numbers are linked to the original source code. """) with XmlWrite.Element(myS, 'p'): myS.characters("""Highlighted filenames take you forward to the next occasion in the include graph of the file being pre-processed, in this case: %s""" % theLex.tuFileId) linkToIndex(myS, theIdxPath) with XmlWrite.Element(myS, 'pre'): # My copy of the file stack for annotating the output myFileStack = [] indentStr = '' colNum = 1 for t in theLex.ppTokens(incWs=True, minWs=True, condLevel=theCondLevel): #print t logging.debug('Token: %s', str(t)) myTokCntr.inc(t, isUnCond=t.isUnCond, num=1) if t.isUnCond: # Adjust the prefix depending on how deep we are in the file stack myIntId = _adjustFileStack(myS, theLex.fileStack, myFileStack, myIntId) indentStr = '.' * len(myFileStack) # Write the token if t.tt == 'whitespace': if t.t != '\n' and colNum > LINE_BREAK_LENGTH: myS.characters(' \\\n') myS.characters(indentStr) myS.characters(' ' * (LINE_FIELD_WIDTH + 8)) colNum = 1 else: # Line break myS.characters(t.t) ## NOTE: This is removed as the cost to the ## browser is enormous. ## Set a marker #with XmlWrite.Element(myS, # 'a', # {'name' : myTuI.add(theLex.tuIndex)}): # pass else: if colNum > LINE_BREAK_LENGTH: # Force a break myS.characters('\\\n') myS.characters(indentStr) myS.characters(' ' * (LINE_FIELD_WIDTH + 8)) colNum = 1 with XmlWrite.Element(myS, 'span', {'class' : TokenCss.retClass(t.tt)}): myS.characters(t.t) colNum += len(t.t) if t.t == '\n' and len(myFileStack) != 0: # Write an ID for the ITU only if incItuAnchors and len(myFileStack) == 1: with XmlWrite.Element(myS, 'a', {'name' : '%d' % theLex.lineNum}): setItuLineNumbers.add(theLex.lineNum) # Write the line prefix myS.characters(indentStr) myS.characters('[') myS.characters(' ' * \ (LINE_FIELD_WIDTH - len('%d' % theLex.lineNum))) HtmlUtils.writeHtmlFileLink( myS, theLex.fileName, theLex.lineNum, '%d' % theLex.lineNum, theClass=None, ) myS.characters(']: ') colNum = 1 linkToIndex(myS, theIdxPath) return myTokCntr, setItuLineNumbers