def _writeMacrosTestedButNotDefined(theS, theMacroId, theEnv): """Writes out the macro history for macros tested but not defined. :param theS: The HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param theMacroId: Macro name. :type theMacroId: ``str`` :param theEnv: Macro environment. :type theEnv: :py:class:`cpip.core.MacroEnv.MacroEnv` :returns: ``NoneType`` """ anchorName = XmlWrite.nameFromString( _macroIdTestedWhenNotDefined(theMacroId)) # This is a list of [class FileLineColumn, ...] myRefS = theEnv.macroNotDefinedDependencyReferences(theMacroId) # Write out the macro title with XmlWrite.Element(theS, 'h3'): with XmlWrite.Element(theS, 'a', {'name': anchorName}): theS.characters('%s [References: %d]' \ % ( theMacroId, len(myRefS), ) ) _writeMacroReferencesTable(theS, myRefS)
def test_01(self): """TestXhtmlWrite.test_01(): simple example.""" myF = io.StringIO() with XmlWrite.XhtmlStream(myF) as xS: with XmlWrite.Element(xS, 'head'): with XmlWrite.Element(xS, 'title'): xS.characters(u'Virtual Library') with XmlWrite.Element(xS, 'body'): with XmlWrite.Element(xS, 'p'): xS.characters(u'Moved to ') with XmlWrite.Element(xS, 'a', {'href': 'http://example.org/'}): xS.characters(u'example.org') xS.characters(u'.') #print #print myF.getvalue() 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"> <head> <title>Virtual Library</title> </head> <body> <p>Moved to <a href="http://example.org/">example.org</a>.</p> </body> </html> """)
def _writeTrMacro(theS, theHtmlPath, theMacro, theIntOccurence, theStartLetter, retMap): """Write the macro as a row in the general table. theMacro is a PpDefine object. theStartLetter is the current letter we are writing ['A', 'B', ...] which writes an anchor at the beginning of each letter section.""" with XmlWrite.Element(theS, 'tr'): if theMacro.identifier[0] != theStartLetter: theStartLetter = theMacro.identifier[0] _writeTdMacro(theS, theMacro, theStartLetter, theIntOccurence) else: _writeTdMacro(theS, theMacro, '', theIntOccurence) if theMacro.identifier not in retMap: # Add to the return value retMap[theMacro.identifier] = '%s#%s' \ % ( os.path.basename(theHtmlPath), _retMacroId(theMacro, theIntOccurence), ) with XmlWrite.Element(theS, 'td'): HtmlUtils.writeHtmlFileLink( theS, theMacro.fileId, theMacro.line, '%s#%d' % (theMacro.fileId, theMacro.line), 'file_decl') _writeTdRefCount(theS, theMacro) _writeTdMonospace(theS, str(theMacro.isCurrentlyDefined)) return theStartLetter
def test_06(self): """TestXmlWrite.test_06(): encoded text in 'latin-1'.""" myF = io.StringIO() with XmlWrite.XmlStream(myF, 'latin-1') as xS: with XmlWrite.Element(xS, 'Root'): with XmlWrite.Element(xS, 'A'): xS.characters("""<&>"'""")
def test_08(self): """TestXmlWrite.test_08(): raise during write.""" myF = io.StringIO() try: with XmlWrite.XmlStream(myF) as xS: with XmlWrite.Element(xS, 'Root', {'version': '12.0'}): self.assertRaises(XmlWrite.ExceptionXmlEndElement, xS.endElement, 'NotRoot') with XmlWrite.Element(xS, 'E', {'attr_1': '1'}): xS._elemStk.pop() xS._elemStk.append('F') raise Exception('Some exception') except Exception as e: print(e) else: print('No exception raised') # print() # print(myF.getvalue()) self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <Root version="12.0"> <E attr_1="1" /> </Root> """)
def _writeTextWithNewlines(self, theS, theText, spanClass): """Splits text by newlines and writes it out. :param theS: The HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param theText: The text to write. :type theText: ``str`` :param spanClass: CSS class. :type spanClass: ``NoneType, str`` :returns: ``NoneType`` """ # Whitespace, line breaks myL = theText.split('\n') if len(myL) > 1: # Do all up to the last for s in myL[:-1]: if spanClass is not None: with XmlWrite.Element(theS, 'span', {'class': spanClass}): theS.characters(s.replace('\t', ' ')) else: theS.characters(s.replace('\t', ' ')) theS.characters('\n') self._incAndWriteLine(theS) # Now the last if spanClass is not None: with XmlWrite.Element(theS, 'span', {'class': spanClass}): theS.characters(myL[-1].replace('\t', ' ')) else: theS.characters(myL[-1].replace('\t', ' '))
def _tdFilePathCallback(theS, attrs, k, v): """Callback function for the file reference table. :param theS: HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param attrs: Element attributes. :type attrs: ``dict({str : [str]})`` :param k: Keys. :type k: ``list([str])`` :param v: Values. :type v: ``list([tuple([str, str])])`` :returns: ``NoneType`` """ attrs['class'] = 'filetable' with XmlWrite.Element(theS, 'td', attrs): theS.characters('%s:' % k[-1]) # Get the href/navtext from the value for h, n in v: theS.characters(' ') with XmlWrite.Element(theS, 'a', {'href': h}): # Write the nav text theS.characters('%s' % n)
def _writeMacroDependencies(theS, theEnv, theMacro, theMacroAdjList, theItu): """Writes out the macro dependencies. :param theS: HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param theEnv: The macro environment. :type theEnv: :py:class:`cpip.core.MacroEnv.MacroEnv` :param theMacro: The macro definition. :type theMacro: :py:class:`cpip.core.PpDefine.PpDefine` :param theMacroAdjList: Dependency adjacency list. :type theMacroAdjList: ``cpip.util.Tree.DuplexAdjacencyList`` :param theItu: The Initial Translation Unit (ITU). :type theItu: ``str`` :returns: ``NoneType`` """ pcTree, cpTree = _getMacroDependencyTrees(theMacroAdjList, theMacro) if pcTree is not None: with XmlWrite.Element(theS, 'p', {}): theS.characters('I depend on these macros:') _writeMacroDependenciesTable(theS, theEnv, pcTree, theItu) if cpTree is not None: with XmlWrite.Element(theS, 'p', {}): theS.characters('These macros depend on me:') _writeMacroDependenciesTable(theS, theEnv, cpTree, theItu)
def _writeMacroDefinitionAndAnchor(theS, theDef, theIntOccurence): """Writes a definition of the macro with an anchor that can be linked to. This also writes an anchor based on the first character of the macro name so that alphabetic links can reference it. """ macroAnchorName = _retMacroId(theDef, theIntOccurence) if len(theDef.strReplacements()): rStr = splitLine(' '.join( [theDef.strIdentPlusParam(), theDef.strReplacements()]), splitLen=80, splitLenHard=132) myReplStr = rStr[len(theDef.strIdentPlusParam()):] else: myReplStr = '' # Write the enclosing <span> element depending on the macro properties spanClass = 'macro' if theDef.isCurrentlyDefined: spanClass += '_s_t' else: spanClass += '_s_f' if theDef.refCount > 0: spanClass += '_r_t' else: spanClass += '_r_f' # Now definition and replacement list with XmlWrite.Element(theS, 'span', {'class': spanClass + '_name'}): theS.characters('#define ') theS.characters(theDef.strIdentPlusParam()) if myReplStr: with XmlWrite.Element(theS, 'span', {'class': spanClass + '_repl'}): theS.charactersWithBr(myReplStr) return macroAnchorName
def _writeMacroDependencies(theS, theEnv, theMacro, theMacroAdjList, theItu): pcTree, cpTree = _getMacroDependencyTrees(theMacroAdjList, theMacro) if pcTree is not None: with XmlWrite.Element(theS, 'p', {}): theS.characters('I depend on these macros:') _writeMacroDependenciesTable(theS, theEnv, pcTree, theItu) if cpTree is not None: with XmlWrite.Element(theS, 'p', {}): theS.characters('These macros depend on me:') _writeMacroDependenciesTable(theS, theEnv, cpTree, theItu)
def _tdFilePathCallback(theS, attrs, k, v): """Callback function for the file reference table.""" attrs['class'] = 'filetable' with XmlWrite.Element(theS, 'td', attrs): theS.characters('%s:' % k[-1]) # Get the href/navtext from the value for h, n in v: theS.characters(' ') with XmlWrite.Element(theS, 'a', {'href': h}): # Write the nav text theS.characters('%s' % n)
def _writeTdRefCount(theS, theMacro): with XmlWrite.Element(theS, 'td'): with XmlWrite.Element(theS, 'span', {'class': 'monospace'}): if theMacro.refCount > 0: # Write a link to the history with XmlWrite.Element(theS, 'a', { 'href': '#%s' % XmlWrite.nameFromString(_macroId(theMacro)) }): theS.characters(str(theMacro.refCount)) else: theS.characters(str(theMacro.refCount))
def linkToIndex(theS, theIdxPath): """Write a link to the index. :param theS: HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param theIdxPath: Path to the index. :type theIdxPath: ``str`` :returns: ``NoneType`` """ with XmlWrite.Element(theS, 'p'): theS.characters('Return to ') with XmlWrite.Element(theS, 'a', {'href': theIdxPath}): theS.characters('Index')
def test_03(self): """TestXmlWrite.test_03(): processing instruction.""" myF = io.StringIO() with XmlWrite.XmlStream(myF) as xS: with XmlWrite.Element(xS, 'Root', {'version': '12.0'}): with XmlWrite.Element(xS, 'A', {'attr_1': '1'}): xS.pI('Do <&> this') #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <Root version="12.0"> <A attr_1="1"><?Do <&> this?></A> </Root> """)
def test_02(self): """TestXmlWrite.test_02(): mixed content.""" myF = io.StringIO() with XmlWrite.XmlStream(myF) as xS: with XmlWrite.Element(xS, 'Root', {'version': '12.0'}): with XmlWrite.Element(xS, 'A', {'attr_1': '1'}): xS.characters(u'<&>') #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <Root version="12.0"> <A attr_1="1"><&></A> </Root> """)
def test_01(self): """TestXmlWrite.test_01(): simple elements.""" myF = io.StringIO() with XmlWrite.XmlStream(myF) as xS: with XmlWrite.Element(xS, 'Root', {'version': '12.0'}): with XmlWrite.Element(xS, 'A', {'attr_1': '1'}): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <Root version="12.0"> <A attr_1="1" /> </Root> """)
def linkToIndex(theS, theIdxPath): """Write a back link to the index page. :param theS: The HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param theIdxPath: <insert documentation for argument> :type theIdxPath: ``str`` :returns: ``NoneType`` """ with XmlWrite.Element(theS, 'p'): theS.characters('Return to ') with XmlWrite.Element(theS, 'a', {'href': theIdxPath}): theS.characters('Index')
def _tdCallback(theS, attrs, k, v): """Callback function for the file count table.""" attrs['class'] = 'filetable' href, navText, count = v with XmlWrite.Element(theS, 'td', attrs): with XmlWrite.Element(theS, 'a', {'href': href}): # Write the nav text theS.characters(navText) with XmlWrite.Element(theS, 'td', { 'width': "36px", 'class': 'filetable', 'align': "right", }): # Write the nav text theS.characters('%d' % count)
def visitPre(self, theCcgNode, theDepth): """Pre-traversal call with a CppCondGraphNode and the integer depth in the tree.""" self._hs.characters(self.PAD_STR * theDepth) if theCcgNode.state: myCssClass = 'CcgNodeTrue' else: myCssClass = 'CcgNodeFalse' with XmlWrite.Element(self._hs, 'span', {'class' : myCssClass}): self._hs.characters('#%s' % theCcgNode.cppDirective) if theCcgNode.constExpr is not None: self._hs.characters(' %s' % theCcgNode.constExpr) self._hs.characters(' ') self._hs.characters(' /* ') HtmlUtils.writeHtmlFileLink( self._hs, theCcgNode.fileId, theCcgNode.lineNum, os.path.basename(theCcgNode.fileId), theClass=None, ) self._hs.characters(' */') #with XmlWrite.Element(self._hs, 'span', {'class' : 'file'}): # self._hs.characters(' [%s]' % theCcgNode.fileId) self._hs.characters('\n')
def _writeParagraphWithBreaks(theS, theParas): for i, p in enumerate(theParas): # if i > 0: # with XmlWrite.Element(theS, 'br'): # pass with XmlWrite.Element(theS, 'p'): theS.characters(p)
def _writeMacrosTestedButNotDefined(theS, theMacroId, theEnv): """Writes out the macro history for macros tested but not defined.""" anchorName = XmlWrite.nameFromString( _macroIdTestedWhenNotDefined(theMacroId)) # This is a list of [class FileLineColumn, ...] myRefS = theEnv.macroNotDefinedDependencyReferences(theMacroId) # Write out the macro title with XmlWrite.Element(theS, 'h3'): with XmlWrite.Element(theS, 'a', {'name': anchorName}): theS.characters('%s [References: %d]' \ % ( theMacroId, len(myRefS), ) ) _writeMacroReferencesTable(theS, myRefS)
def test_07(self): """TestSVGlWriter.test_07(): text. Based on http://www.w3.org/TR/2003/REC-SVG11-20030114/text.html#TextElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort, {'viewBox': "0 0 1000 300"}) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters("Example text01 - 'Hello, out there' in blue") myPt = Coord.Pt(Coord.baseUnitsDim(250), Coord.baseUnitsDim(150)) with SVGWriter.SVGText(xS, myPt, "Verdans", 55, {'fill': "blue"}): xS.characters('Hello, out there') #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(998), Coord.baseUnitsDim(298)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" viewBox="0 0 1000 300" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example text01 - 'Hello, out there' in blue</desc> <text fill="blue" font-family="Verdans" font-size="55" x="250px" y="150px">Hello, out there</text> <rect fill="none" height="298px" stroke="blue" stroke-width="2" width="998px" x="1px" y="1px" /> </svg> """)
def _writeTokenCounter(self, theS, theCntr, isAll): for aType in PpToken.LEX_PPTOKEN_TYPES: myAttrs = { 'type': aType, 'count': '%d' % theCntr.tokenCount(aType, isAll), } with XmlWrite.Element(theS, 'Tokens', myAttrs): pass
def _writeTocLetterLinks(theS, theSet): if len(theSet) > 0: letterList = list(theSet) letterList.sort() for aL in letterList: theS.literal(' ') with XmlWrite.Element( theS, 'a', { 'href' : '#%s.%s' \ % (ANCHOR_MACRO_ALPHA, aL), } ): with XmlWrite.Element(theS, 'tt'): theS.characters('%s' % aL) theS.characters('...')
def _writeFileName(theS, lenIndent, theFileStack, theAction, theFile, theIntId): """ :param theS: HTML stream. :type theS: :py:class:`cpip.util.XmlWrite.XhtmlStream` :param lenIndent: Size of indent. :type lenIndent: ``int`` :param theFileStack: File stack. :type theFileStack: ``list([str])`` :param theAction: One of ``('Starting', 'Holding', 'Back in', 'Ending')`` :type theAction: ``str`` :param theFile: File ID such as a path. :type theFile: ``str`` :param theIntId: ??? :type theIntId: ``int`` :returns: ``int`` -- ``theIntId`` """ assert (theAction in FILE_SHIFT_ACTIONS) if lenIndent > 0: theS.characters('\n%s' % ('.' * lenIndent)) if len(theFileStack) == 1: with XmlWrite.Element(theS, 'a', {'name': '_%d' % theIntId}): pass theIntId += 1 with XmlWrite.Element(theS, 'a', {'href': '#_%d' % theIntId}): with XmlWrite.Element(theS, 'span', {'class': 'file'}): theS.characters( '# %s FILE: %s' \ % ('%*s' % (FILE_SHIFT_ACTION_WIDTH, theAction), os.path.normpath(theFile)) ) else: with XmlWrite.Element(theS, 'span', {'class': 'file'}): theS.characters( '# %s FILE: %s' \ % ('%*s' % (FILE_SHIFT_ACTION_WIDTH, theAction), os.path.normpath(theFile)) ) return theIntId
def writeIndexHtml(theItuS, theOutDir, theJobSpec): """Writes the top level index.html page for a pre-processed file. theOutDir - The output directory. theTuS - The list of translation units processed. theCmdLine - The command line as a string. theOptMap is a map of {opt_name : (value, help), ...} from the command line options. TODO: This is fine but has too many levels of indent. """ indexPath = os.path.join(theOutDir, 'index.html') assert len(theItuS) == 1, 'Can only process one TU to an output directory.' with XmlWrite.XhtmlStream(indexPath, 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') with XmlWrite.Element(myS, 'body'): with XmlWrite.Element(myS, 'h1'): myS.characters('CPIP Processing in output location: %s' % theOutDir) # List of links to TU index pages with XmlWrite.Element(myS, 'h2'): myS.characters('Files Processed as Translation Units:') with XmlWrite.Element(myS, 'ul'): for anItu in theItuS: with XmlWrite.Element(myS, 'li'): with XmlWrite.Element(myS, 'tt'): with XmlWrite.Element( myS, 'a', {'href': tuIndexFileName(anItu)}, ): myS.characters(anItu) _writeCommandLineInvocationToHTML(myS, theJobSpec) return indexPath
def writeIncludeGraphAsText(theOutDir, theItu, theLexer): def _linkToIndex(theS, theItu): with XmlWrite.Element(theS, 'p'): theS.characters('Return to ') with XmlWrite.Element(theS, 'a', {'href': tuIndexFileName(theItu)}): theS.characters('Index') outPath = os.path.join(theOutDir, includeGraphFileNameText(theItu)) with XmlWrite.XhtmlStream(outPath, 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('Included graph for %s' % theItu) with XmlWrite.Element(myS, 'body'): with XmlWrite.Element(myS, 'h1'): myS.characters('File include graph for: %s' % theItu) with XmlWrite.Element(myS, 'p'): myS.characters('A text dump of the include graph.') _linkToIndex(myS, theItu) with XmlWrite.Element(myS, 'pre'): myS.characters(str(theLexer.fileIncludeGraphRoot)) _linkToIndex(myS, theItu)
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')
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 _writeTableOfMacros(theS, theEnv, theHtmlPath): """Writes the table of macros, where they are defined, their ref count etc.""" # Return value is a map of {identifier : href_text, ...) to link to macro # definitions. retVal = {} # Write table of all macros myMacroMap = theEnv.macroHistoryMap() myMacroNameS = list(myMacroMap.keys()) if len(myMacroNameS) == 0: return retVal myMacroNameS.sort() # Now write tables of information with XmlWrite.Element(theS, 'a', {'name': TITLE_ANCHOR_LINKTEXT_MACROS_TABLE[1]}): pass with XmlWrite.Element(theS, 'h1'): theS.characters(TITLE_ANCHOR_LINKTEXT_MACROS_TABLE[0]) with XmlWrite.Element(theS, 'table', { 'border': "4", 'cellspacing': "2", 'cellpadding': "8", }): with XmlWrite.Element(theS, 'tr'): _writeTh(theS, 'Declaration') _writeTh(theS, 'Declared In') _writeTh(theS, 'Ref. Count') _writeTh(theS, 'Defined?') startLetter = '' for aMacroName in myMacroNameS: myUndefIdxS, isDefined = myMacroMap[aMacroName] # Write the undefined ones for anIndex in myUndefIdxS: myMacro = theEnv.getUndefMacro(anIndex) startLetter = _writeTrMacro(theS, theHtmlPath, myMacro, anIndex, startLetter, retVal) # Now the defined one if isDefined: myMacro = theEnv.macro(aMacroName) startLetter = _writeTrMacro(theS, theHtmlPath, myMacro, len(myUndefIdxS), startLetter, retVal) with XmlWrite.Element(theS, 'br'): pass # End: write table of all macros return retVal