def _writeMacroReferencesTable(theS, theFlcS): """Writes all the references to a file/line/col in a rowspan/colspan HTML table with links to the position in the HTML representation of the file that references something. This uses a particular design pattern that uses a DictTree to sort out the rows and columns. In this case the DictTree values are lists of pairs (href, nav_text) where nav_text is the line-col of the referencing file.""" myFileLineColS = [] # This removes duplicates, it is a list of (fileId, lineNum, colNum). # If an include file is included N times there will be N-1 duplicate entries # for the header guard macro otherwise. hasSeen = [] for aFlc in theFlcS: ident = (aFlc.fileId, aFlc.lineNum, aFlc.colNum) if ident not in hasSeen: myFileLineColS.append(( aFlc.fileId, ( HtmlUtils.retHtmlFileLink(aFlc.fileId, aFlc.lineNum), # Navigation text '%d-%d' % (aFlc.lineNum, aFlc.colNum), ), )) hasSeen.append(ident) if len(myFileLineColS) > 0: HtmlUtils.writeFilePathsAsTable('list', theS, myFileLineColS, 'filetable', _tdFilePathCallback)
def writeTuIndexHtml(theOutDir, theTuPath, theLexer, theFileCountMap, theTokenCntr, hasIncDot, macroHistoryIndexName): with XmlWrite.XhtmlStream( os.path.join(theOutDir, tuIndexFileName(theTuPath)), mustIndent=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('CPIP Processing of %s' % theTuPath) with XmlWrite.Element(myS, 'body'): with XmlWrite.Element(myS, 'h1'): myS.characters('CPIP Processing of %s' % theTuPath) with XmlWrite.Element(myS, 'p'): myS.characters("""This has links to individual pages about the pre-processing of this file.""") # ## # Translation unit # ## with XmlWrite.Element(myS, 'h2'): myS.characters('1. Source Code') _writeParagraphWithBreaks(myS, SOURCE_CODE_INTRO) with XmlWrite.Element(myS, 'h3'): # 'p'): myS.characters('The ') with XmlWrite.Element( myS, 'a', { 'href': HtmlUtils.retHtmlFileName(theTuPath), }): myS.characters('source file') myS.characters(' and ') with XmlWrite.Element(myS, 'a', { 'href': tuFileName(theTuPath), }): myS.characters('as a translation unit') # ## # Include graph # ## with XmlWrite.Element(myS, 'h2'): myS.characters('2. Include Graphs') _writeParagraphWithBreaks(myS, INCLUDE_GRAPH_INTRO) with XmlWrite.Element(myS, 'h3'): # 'p'): myS.characters('A ') with XmlWrite.Element( myS, 'a', { 'href': includeGraphFileNameSVG(theTuPath), }): myS.characters('visual #include tree in SVG') # If we have successfully written a .dot file then link to it if hasIncDot: myS.characters(', ') with XmlWrite.Element( myS, 'a', { 'href': includeGraphFileNameDotSVG(theTuPath), }): myS.characters('Dot dependency [SVG]') myS.characters(' or ') with XmlWrite.Element( myS, 'a', { 'href': includeGraphFileNameText(theTuPath), }): myS.characters('as Text') # ## # Conditional compilation # ## with XmlWrite.Element(myS, 'h2'): myS.characters('3. Conditional Compilation') _writeParagraphWithBreaks(myS, CONDITIONAL_COMPILATION_INTRO) with XmlWrite.Element(myS, 'h3'): # 'p'): myS.characters('The ') with XmlWrite.Element( myS, 'a', { 'href': includeGraphFileNameCcg(theTuPath), }): myS.characters('conditional compilation graph') # ## # Macro history # ## with XmlWrite.Element(myS, 'h2'): myS.characters('4. Macros') _writeParagraphWithBreaks(myS, MACROS_INTRO) with XmlWrite.Element(myS, 'h3'): myS.characters('The ') with XmlWrite.Element(myS, 'a', { 'href': macroHistoryIndexName, }): myS.characters('Macro Environment') # ## # Write out token counter as a table # ## with XmlWrite.Element(myS, 'h2'): myS.characters('5. Token Count') _writeParagraphWithBreaks(myS, TOKEN_COUNT_INTRO) with XmlWrite.Element(myS, 'table', {'class': "monospace"}): with XmlWrite.Element(myS, 'tr'): with XmlWrite.Element(myS, 'th', {'class': "monospace"}): myS.characters('Token Type') with XmlWrite.Element(myS, 'th', {'class': "monospace"}): myS.characters('Count') myTotal = 0 for tokType, tokCount in theTokenCntr.tokenTypesAndCounts( isAll=True, allPossibleTypes=True): with XmlWrite.Element(myS, 'tr'): with XmlWrite.Element(myS, 'td', {'class': "monospace"}): myS.characters(tokType) with XmlWrite.Element(myS, 'td', {'class': "monospace"}): # <tt> does not preserve space so force it to myStr = '%10d' % tokCount myStr = myStr.replace(' ', ' ') myS.literal(myStr) myTotal += tokCount with XmlWrite.Element(myS, 'tr'): with XmlWrite.Element(myS, 'td', {'class': "monospace"}): with XmlWrite.Element(myS, 'b'): myS.characters('Total:') with XmlWrite.Element(myS, 'td', {'class': "monospace"}): with XmlWrite.Element(myS, 'b'): # <tt> does not preserve space so force it to myStr = '%10d' % myTotal myStr = myStr.replace(' ', ' ') myS.literal(myStr) with XmlWrite.Element(myS, 'br'): pass with XmlWrite.Element(myS, 'h2'): myS.characters('6. Files Included and Count') _writeParagraphWithBreaks(myS, FILES_INCLUDED_INTRO) with XmlWrite.Element(myS, 'p'): myS.characters('Total number of unique files: %d' % len(theFileCountMap)) # TODO: Value count # with XmlWrite.Element(myS, 'p'): # myS.characters('Total files processed: %d' % sum(theFileCountMap.values())) myItuFileS = sorted(theFileCountMap.keys()) # Create a list for the DictTree myFileLinkS = [ ( p, # Value is a tripple (href, basename, count) (HtmlUtils.retHtmlFileName(p), os.path.basename(p), theFileCountMap[p]), ) for p in myItuFileS if p != PpLexer.UNNAMED_FILE_NAME ] HtmlUtils.writeFilePathsAsTable(None, myS, myFileLinkS, 'filetable', _tdCallback) with XmlWrite.Element(myS, 'br'): pass # TODO... with XmlWrite.Element(myS, 'p'): myS.characters('Produced by %s version: %s' % ('CPIPMain', __version__)) # Back link with XmlWrite.Element(myS, 'p'): myS.characters('Back to: ') with XmlWrite.Element(myS, 'a', { 'href': 'index.html', }): myS.characters('Index Page')
def test_02(self): """Test_writeFilePathsAsTable.test_01(): writeFilePathsAsTable() - With header""" myF = io.StringIO() myFileNameValueS = [ # filename, (href, navText, file_data) where file data is count_inc, count_lines, count_bytes ('spam/chips.lis', ('chips.html', 'Chips', (1, 2, 3))), ('spam/eggs.lis', ('eggs.html', 'Eggs', (10, 11, 12))), ('spam/fishfingers/beans.lis', ('fishfingers/beans.html', 'Beans', (100, 101, 102))), ('spam/fishfingers/peas.lis', ('fishfingers/peas.html', 'Peas', (1000, 1001, 1002))), ] def _tdCallback(theS, attrs, _k, href_nav_text_file_data): """Callback function for the file count table. This comes from CPIPMain.py""" attrs['class'] = 'filetable' href, navText, file_data = href_nav_text_file_data with XmlWrite.Element(theS, 'td', attrs): with XmlWrite.Element(theS, 'a', {'href': href}): # Write the nav text theS.characters(navText) td_attrs = { 'width': "36px", 'class': 'filetable', 'align': "right", } count_inc, count_lines, count_bytes = file_data with XmlWrite.Element(theS, 'td', td_attrs): # Write the file count of inclusions theS.characters('%d' % count_inc) with XmlWrite.Element(theS, 'td', td_attrs): # Write the file count of lines theS.characters('{:,d}'.format(count_lines)) with XmlWrite.Element(theS, 'td', td_attrs): # Write the file count of bytes theS.characters('{:,d}'.format(count_bytes)) with XmlWrite.Element(theS, 'td', td_attrs): # Write the file count of lines * inclusions theS.characters('{:,d}'.format(count_lines * count_inc)) with XmlWrite.Element(theS, 'td', td_attrs): # Write the file count of bytes * inclusions theS.characters('{:,d}'.format(count_bytes * count_inc)) def _trThCallback(theS, theDepth): """This comes from CPIPMain.py. Create the table header: <tr> <th class="filetable" colspan="9">File Path </th> <th class="filetable">Include Count</th> <th class="filetable">Lines</th> <th class="filetable">Bytes</th> <th class="filetable">Total Lines</th> <th class="filetable">Total Bytes</th> </tr> """ with XmlWrite.Element(theS, 'tr', {}): with XmlWrite.Element(theS, 'th', { 'colspan': '%d' % theDepth, 'class': 'filetable', }): theS.characters('File Path') with XmlWrite.Element(theS, 'th', {'class': 'filetable'}): theS.characters('Include Count') with XmlWrite.Element(theS, 'th', {'class': 'filetable'}): theS.characters('Lines') with XmlWrite.Element(theS, 'th', {'class': 'filetable'}): theS.characters('Bytes') with XmlWrite.Element(theS, 'th', {'class': 'filetable'}): theS.characters('Total Lines') with XmlWrite.Element(theS, 'th', {'class': 'filetable'}): theS.characters('Total Bytes') with XmlWrite.XhtmlStream(myF) as myS: HtmlUtils.writeFilePathsAsTable(None, myS, myFileNameValueS, 'table_style', fnTd=_tdCallback, fnTrTh=_trThCallback) # print() # print(myF.getvalue()) # self.maxDiff = None # print(myFileLinkS) self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <table class="table_style"> <tr> <th class="filetable" colspan="3">File Path</th> <th class="filetable">Include Count</th> <th class="filetable">Lines</th> <th class="filetable">Bytes</th> <th class="filetable">Total Lines</th> <th class="filetable">Total Bytes</th> </tr> <tr> <td class="table_style" rowspan="4">spam/</td> <td class="filetable" colspan="2"> <a href="chips.html">Chips</a> </td> <td align="right" class="filetable" width="36px">1</td> <td align="right" class="filetable" width="36px">2</td> <td align="right" class="filetable" width="36px">3</td> <td align="right" class="filetable" width="36px">2</td> <td align="right" class="filetable" width="36px">3</td> </tr> <tr> <td class="filetable" colspan="2"> <a href="eggs.html">Eggs</a> </td> <td align="right" class="filetable" width="36px">10</td> <td align="right" class="filetable" width="36px">11</td> <td align="right" class="filetable" width="36px">12</td> <td align="right" class="filetable" width="36px">110</td> <td align="right" class="filetable" width="36px">120</td> </tr> <tr> <td class="table_style" rowspan="2">fishfingers/</td> <td class="filetable"> <a href="fishfingers/beans.html">Beans</a> </td> <td align="right" class="filetable" width="36px">100</td> <td align="right" class="filetable" width="36px">101</td> <td align="right" class="filetable" width="36px">102</td> <td align="right" class="filetable" width="36px">10,100</td> <td align="right" class="filetable" width="36px">10,200</td> </tr> <tr> <td class="filetable"> <a href="fishfingers/peas.html">Peas</a> </td> <td align="right" class="filetable" width="36px">1000</td> <td align="right" class="filetable" width="36px">1,001</td> <td align="right" class="filetable" width="36px">1,002</td> <td align="right" class="filetable" width="36px">1,001,000</td> <td align="right" class="filetable" width="36px">1,002,000</td> </tr> </table> </html> """)