17db96d56Sopenharmony_ci#! /usr/bin/env python3 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci# Convert GNU texinfo files into HTML, one file per node. 47db96d56Sopenharmony_ci# Based on Texinfo 2.14. 57db96d56Sopenharmony_ci# Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory 67db96d56Sopenharmony_ci# The input file must be a complete texinfo file, e.g. emacs.texi. 77db96d56Sopenharmony_ci# This creates many files (one per info node) in the output directory, 87db96d56Sopenharmony_ci# overwriting existing files of the same name. All files created have 97db96d56Sopenharmony_ci# ".html" as their extension. 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci# XXX To do: 137db96d56Sopenharmony_ci# - handle @comment*** correctly 147db96d56Sopenharmony_ci# - handle @xref {some words} correctly 157db96d56Sopenharmony_ci# - handle @ftable correctly (items aren't indexed?) 167db96d56Sopenharmony_ci# - handle @itemx properly 177db96d56Sopenharmony_ci# - handle @exdent properly 187db96d56Sopenharmony_ci# - add links directly to the proper line from indices 197db96d56Sopenharmony_ci# - check against the definitive list of @-cmds; we still miss (among others): 207db96d56Sopenharmony_ci# - @defindex (hard) 217db96d56Sopenharmony_ci# - @c(omment) in the middle of a line (rarely used) 227db96d56Sopenharmony_ci# - @this* (not really needed, only used in headers anyway) 237db96d56Sopenharmony_ci# - @today{} (ever used outside title page?) 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci# More consistent handling of chapters/sections/etc. 267db96d56Sopenharmony_ci# Lots of documentation 277db96d56Sopenharmony_ci# Many more options: 287db96d56Sopenharmony_ci# -top designate top node 297db96d56Sopenharmony_ci# -links customize which types of links are included 307db96d56Sopenharmony_ci# -split split at chapters or sections instead of nodes 317db96d56Sopenharmony_ci# -name Allow different types of filename handling. Non unix systems 327db96d56Sopenharmony_ci# will have problems with long node names 337db96d56Sopenharmony_ci# ... 347db96d56Sopenharmony_ci# Support the most recent texinfo version and take a good look at HTML 3.0 357db96d56Sopenharmony_ci# More debugging output (customizable) and more flexible error handling 367db96d56Sopenharmony_ci# How about icons ? 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci# rpyron 2002-05-07 397db96d56Sopenharmony_ci# Robert Pyron <rpyron@alum.mit.edu> 407db96d56Sopenharmony_ci# 1. BUGFIX: In function makefile(), strip blanks from the nodename. 417db96d56Sopenharmony_ci# This is necessary to match the behavior of parser.makeref() and 427db96d56Sopenharmony_ci# parser.do_node(). 437db96d56Sopenharmony_ci# 2. BUGFIX fixed KeyError in end_ifset (well, I may have just made 447db96d56Sopenharmony_ci# it go away, rather than fix it) 457db96d56Sopenharmony_ci# 3. BUGFIX allow @menu and menu items inside @ifset or @ifclear 467db96d56Sopenharmony_ci# 4. Support added for: 477db96d56Sopenharmony_ci# @uref URL reference 487db96d56Sopenharmony_ci# @image image file reference (see note below) 497db96d56Sopenharmony_ci# @multitable output an HTML table 507db96d56Sopenharmony_ci# @vtable 517db96d56Sopenharmony_ci# 5. Partial support for accents, to match MAKEINFO output 527db96d56Sopenharmony_ci# 6. I added a new command-line option, '-H basename', to specify 537db96d56Sopenharmony_ci# HTML Help output. This will cause three files to be created 547db96d56Sopenharmony_ci# in the current directory: 557db96d56Sopenharmony_ci# `basename`.hhp HTML Help Workshop project file 567db96d56Sopenharmony_ci# `basename`.hhc Contents file for the project 577db96d56Sopenharmony_ci# `basename`.hhk Index file for the project 587db96d56Sopenharmony_ci# When fed into HTML Help Workshop, the resulting file will be 597db96d56Sopenharmony_ci# named `basename`.chm. 607db96d56Sopenharmony_ci# 7. A new class, HTMLHelp, to accomplish item 6. 617db96d56Sopenharmony_ci# 8. Various calls to HTMLHelp functions. 627db96d56Sopenharmony_ci# A NOTE ON IMAGES: Just as 'outputdirectory' must exist before 637db96d56Sopenharmony_ci# running this program, all referenced images must already exist 647db96d56Sopenharmony_ci# in outputdirectory. 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ciimport os 677db96d56Sopenharmony_ciimport sys 687db96d56Sopenharmony_ciimport string 697db96d56Sopenharmony_ciimport re 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ciMAGIC = '\\input texinfo' 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_cicmprog = re.compile('^@([a-z]+)([ \t]|$)') # Command (line-oriented) 747db96d56Sopenharmony_ciblprog = re.compile('^[ \t]*$') # Blank line 757db96d56Sopenharmony_cikwprog = re.compile('@[a-z]+') # Keyword (embedded, usually 767db96d56Sopenharmony_ci # with {} args) 777db96d56Sopenharmony_cispprog = re.compile('[\n@{}&<>]') # Special characters in 787db96d56Sopenharmony_ci # running text 797db96d56Sopenharmony_ci # 807db96d56Sopenharmony_ci # menu item (Yuck!) 817db96d56Sopenharmony_cimiprog = re.compile(r'^\* ([^:]*):(:|[ \t]*([^\t,\n.]+)([^ \t\n]*))[ \t\n]*') 827db96d56Sopenharmony_ci# 0 1 1 2 3 34 42 0 837db96d56Sopenharmony_ci# ----- ---------- --------- 847db96d56Sopenharmony_ci# -|----------------------------- 857db96d56Sopenharmony_ci# ----------------------------------------------------- 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ciclass HTMLNode: 917db96d56Sopenharmony_ci """Some of the parser's functionality is separated into this class. 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci A Node accumulates its contents, takes care of links to other Nodes 947db96d56Sopenharmony_ci and saves itself when it is finished and all links are resolved. 957db96d56Sopenharmony_ci """ 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">' 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci type = 0 1007db96d56Sopenharmony_ci cont = '' 1017db96d56Sopenharmony_ci epilogue = '</BODY></HTML>\n' 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci def __init__(self, dir, name, topname, title, next, prev, up): 1047db96d56Sopenharmony_ci self.dirname = dir 1057db96d56Sopenharmony_ci self.name = name 1067db96d56Sopenharmony_ci if topname: 1077db96d56Sopenharmony_ci self.topname = topname 1087db96d56Sopenharmony_ci else: 1097db96d56Sopenharmony_ci self.topname = name 1107db96d56Sopenharmony_ci self.title = title 1117db96d56Sopenharmony_ci self.next = next 1127db96d56Sopenharmony_ci self.prev = prev 1137db96d56Sopenharmony_ci self.up = up 1147db96d56Sopenharmony_ci self.lines = [] 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci def write(self, *lines): 1177db96d56Sopenharmony_ci for line in lines: 1187db96d56Sopenharmony_ci self.lines.append(line) 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci def flush(self): 1217db96d56Sopenharmony_ci with open(self.dirname + '/' + makefile(self.name), 'w') as fp: 1227db96d56Sopenharmony_ci fp.write(self.prologue) 1237db96d56Sopenharmony_ci fp.write(self.text) 1247db96d56Sopenharmony_ci fp.write(self.epilogue) 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci def link(self, label, nodename, rel=None, rev=None): 1277db96d56Sopenharmony_ci if nodename: 1287db96d56Sopenharmony_ci if nodename.lower() == '(dir)': 1297db96d56Sopenharmony_ci addr = '../dir.html' 1307db96d56Sopenharmony_ci title = '' 1317db96d56Sopenharmony_ci else: 1327db96d56Sopenharmony_ci addr = makefile(nodename) 1337db96d56Sopenharmony_ci title = ' TITLE="%s"' % nodename 1347db96d56Sopenharmony_ci self.write(label, ': <A HREF="', addr, '"', \ 1357db96d56Sopenharmony_ci rel and (' REL=' + rel) or "", \ 1367db96d56Sopenharmony_ci rev and (' REV=' + rev) or "", \ 1377db96d56Sopenharmony_ci title, '>', nodename, '</A> \n') 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci def finalize(self): 1407db96d56Sopenharmony_ci length = len(self.lines) 1417db96d56Sopenharmony_ci self.text = ''.join(self.lines) 1427db96d56Sopenharmony_ci self.lines = [] 1437db96d56Sopenharmony_ci self.open_links() 1447db96d56Sopenharmony_ci self.output_links() 1457db96d56Sopenharmony_ci self.close_links() 1467db96d56Sopenharmony_ci links = ''.join(self.lines) 1477db96d56Sopenharmony_ci self.lines = [] 1487db96d56Sopenharmony_ci self.prologue = ( 1497db96d56Sopenharmony_ci self.DOCTYPE + 1507db96d56Sopenharmony_ci '\n<HTML><HEAD>\n' 1517db96d56Sopenharmony_ci ' <!-- Converted with texi2html and Python -->\n' 1527db96d56Sopenharmony_ci ' <TITLE>' + self.title + '</TITLE>\n' 1537db96d56Sopenharmony_ci ' <LINK REL=Next HREF="' 1547db96d56Sopenharmony_ci + makefile(self.next) + '" TITLE="' + self.next + '">\n' 1557db96d56Sopenharmony_ci ' <LINK REL=Previous HREF="' 1567db96d56Sopenharmony_ci + makefile(self.prev) + '" TITLE="' + self.prev + '">\n' 1577db96d56Sopenharmony_ci ' <LINK REL=Up HREF="' 1587db96d56Sopenharmony_ci + makefile(self.up) + '" TITLE="' + self.up + '">\n' 1597db96d56Sopenharmony_ci '</HEAD><BODY>\n' + 1607db96d56Sopenharmony_ci links) 1617db96d56Sopenharmony_ci if length > 20: 1627db96d56Sopenharmony_ci self.epilogue = '<P>\n%s</BODY></HTML>\n' % links 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci def open_links(self): 1657db96d56Sopenharmony_ci self.write('<HR>\n') 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci def close_links(self): 1687db96d56Sopenharmony_ci self.write('<HR>\n') 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci def output_links(self): 1717db96d56Sopenharmony_ci if self.cont != self.next: 1727db96d56Sopenharmony_ci self.link(' Cont', self.cont) 1737db96d56Sopenharmony_ci self.link(' Next', self.next, rel='Next') 1747db96d56Sopenharmony_ci self.link(' Prev', self.prev, rel='Previous') 1757db96d56Sopenharmony_ci self.link(' Up', self.up, rel='Up') 1767db96d56Sopenharmony_ci if self.name != self.topname: 1777db96d56Sopenharmony_ci self.link(' Top', self.topname) 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ciclass HTML3Node(HTMLNode): 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ci DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML Level 3//EN//3.0">' 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci def open_links(self): 1857db96d56Sopenharmony_ci self.write('<DIV CLASS=Navigation>\n <HR>\n') 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ci def close_links(self): 1887db96d56Sopenharmony_ci self.write(' <HR>\n</DIV>\n') 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ciclass TexinfoParser: 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci COPYRIGHT_SYMBOL = "©" 1947db96d56Sopenharmony_ci FN_ID_PATTERN = "(%(id)s)" 1957db96d56Sopenharmony_ci FN_SOURCE_PATTERN = '<A NAME=footnoteref%(id)s' \ 1967db96d56Sopenharmony_ci ' HREF="#footnotetext%(id)s">' \ 1977db96d56Sopenharmony_ci + FN_ID_PATTERN + '</A>' 1987db96d56Sopenharmony_ci FN_TARGET_PATTERN = '<A NAME=footnotetext%(id)s' \ 1997db96d56Sopenharmony_ci ' HREF="#footnoteref%(id)s">' \ 2007db96d56Sopenharmony_ci + FN_ID_PATTERN + '</A>\n%(text)s<P>\n' 2017db96d56Sopenharmony_ci FN_HEADER = '\n<P>\n<HR NOSHADE SIZE=1 WIDTH=200>\n' \ 2027db96d56Sopenharmony_ci '<STRONG><EM>Footnotes</EM></STRONG>\n<P>' 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci Node = HTMLNode 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci # Initialize an instance 2087db96d56Sopenharmony_ci def __init__(self): 2097db96d56Sopenharmony_ci self.unknown = {} # statistics about unknown @-commands 2107db96d56Sopenharmony_ci self.filenames = {} # Check for identical filenames 2117db96d56Sopenharmony_ci self.debugging = 0 # larger values produce more output 2127db96d56Sopenharmony_ci self.print_headers = 0 # always print headers? 2137db96d56Sopenharmony_ci self.nodefp = None # open file we're writing to 2147db96d56Sopenharmony_ci self.nodelineno = 0 # Linenumber relative to node 2157db96d56Sopenharmony_ci self.links = None # Links from current node 2167db96d56Sopenharmony_ci self.savetext = None # If not None, save text head instead 2177db96d56Sopenharmony_ci self.savestack = [] # If not None, save text head instead 2187db96d56Sopenharmony_ci self.htmlhelp = None # html help data 2197db96d56Sopenharmony_ci self.dirname = 'tmp' # directory where files are created 2207db96d56Sopenharmony_ci self.includedir = '.' # directory to search @include files 2217db96d56Sopenharmony_ci self.nodename = '' # name of current node 2227db96d56Sopenharmony_ci self.topname = '' # name of top node (first node seen) 2237db96d56Sopenharmony_ci self.title = '' # title of this whole Texinfo tree 2247db96d56Sopenharmony_ci self.resetindex() # Reset all indices 2257db96d56Sopenharmony_ci self.contents = [] # Reset table of contents 2267db96d56Sopenharmony_ci self.numbering = [] # Reset section numbering counters 2277db96d56Sopenharmony_ci self.nofill = 0 # Normal operation: fill paragraphs 2287db96d56Sopenharmony_ci self.values={'html': 1} # Names that should be parsed in ifset 2297db96d56Sopenharmony_ci self.stackinfo={} # Keep track of state in the stack 2307db96d56Sopenharmony_ci # XXX The following should be reset per node?! 2317db96d56Sopenharmony_ci self.footnotes = [] # Reset list of footnotes 2327db96d56Sopenharmony_ci self.itemarg = None # Reset command used by @item 2337db96d56Sopenharmony_ci self.itemnumber = None # Reset number for @item in @enumerate 2347db96d56Sopenharmony_ci self.itemindex = None # Reset item index name 2357db96d56Sopenharmony_ci self.node = None 2367db96d56Sopenharmony_ci self.nodestack = [] 2377db96d56Sopenharmony_ci self.cont = 0 2387db96d56Sopenharmony_ci self.includedepth = 0 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci # Set htmlhelp helper class 2417db96d56Sopenharmony_ci def sethtmlhelp(self, htmlhelp): 2427db96d56Sopenharmony_ci self.htmlhelp = htmlhelp 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci # Set (output) directory name 2457db96d56Sopenharmony_ci def setdirname(self, dirname): 2467db96d56Sopenharmony_ci self.dirname = dirname 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci # Set include directory name 2497db96d56Sopenharmony_ci def setincludedir(self, includedir): 2507db96d56Sopenharmony_ci self.includedir = includedir 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci # Parse the contents of an entire file 2537db96d56Sopenharmony_ci def parse(self, fp): 2547db96d56Sopenharmony_ci line = fp.readline() 2557db96d56Sopenharmony_ci lineno = 1 2567db96d56Sopenharmony_ci while line and (line[0] == '%' or blprog.match(line)): 2577db96d56Sopenharmony_ci line = fp.readline() 2587db96d56Sopenharmony_ci lineno = lineno + 1 2597db96d56Sopenharmony_ci if line[:len(MAGIC)] != MAGIC: 2607db96d56Sopenharmony_ci raise SyntaxError('file does not begin with %r' % (MAGIC,)) 2617db96d56Sopenharmony_ci self.parserest(fp, lineno) 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci # Parse the contents of a file, not expecting a MAGIC header 2647db96d56Sopenharmony_ci def parserest(self, fp, initial_lineno): 2657db96d56Sopenharmony_ci lineno = initial_lineno 2667db96d56Sopenharmony_ci self.done = 0 2677db96d56Sopenharmony_ci self.skip = 0 2687db96d56Sopenharmony_ci self.stack = [] 2697db96d56Sopenharmony_ci accu = [] 2707db96d56Sopenharmony_ci while not self.done: 2717db96d56Sopenharmony_ci line = fp.readline() 2727db96d56Sopenharmony_ci self.nodelineno = self.nodelineno + 1 2737db96d56Sopenharmony_ci if not line: 2747db96d56Sopenharmony_ci if accu: 2757db96d56Sopenharmony_ci if not self.skip: self.process(accu) 2767db96d56Sopenharmony_ci accu = [] 2777db96d56Sopenharmony_ci if initial_lineno > 0: 2787db96d56Sopenharmony_ci print('*** EOF before @bye') 2797db96d56Sopenharmony_ci break 2807db96d56Sopenharmony_ci lineno = lineno + 1 2817db96d56Sopenharmony_ci mo = cmprog.match(line) 2827db96d56Sopenharmony_ci if mo: 2837db96d56Sopenharmony_ci a, b = mo.span(1) 2847db96d56Sopenharmony_ci cmd = line[a:b] 2857db96d56Sopenharmony_ci if cmd in ('noindent', 'refill'): 2867db96d56Sopenharmony_ci accu.append(line) 2877db96d56Sopenharmony_ci else: 2887db96d56Sopenharmony_ci if accu: 2897db96d56Sopenharmony_ci if not self.skip: 2907db96d56Sopenharmony_ci self.process(accu) 2917db96d56Sopenharmony_ci accu = [] 2927db96d56Sopenharmony_ci self.command(line, mo) 2937db96d56Sopenharmony_ci elif blprog.match(line) and \ 2947db96d56Sopenharmony_ci 'format' not in self.stack and \ 2957db96d56Sopenharmony_ci 'example' not in self.stack: 2967db96d56Sopenharmony_ci if accu: 2977db96d56Sopenharmony_ci if not self.skip: 2987db96d56Sopenharmony_ci self.process(accu) 2997db96d56Sopenharmony_ci if self.nofill: 3007db96d56Sopenharmony_ci self.write('\n') 3017db96d56Sopenharmony_ci else: 3027db96d56Sopenharmony_ci self.write('<P>\n') 3037db96d56Sopenharmony_ci accu = [] 3047db96d56Sopenharmony_ci else: 3057db96d56Sopenharmony_ci # Append the line including trailing \n! 3067db96d56Sopenharmony_ci accu.append(line) 3077db96d56Sopenharmony_ci # 3087db96d56Sopenharmony_ci if self.skip: 3097db96d56Sopenharmony_ci print('*** Still skipping at the end') 3107db96d56Sopenharmony_ci if self.stack: 3117db96d56Sopenharmony_ci print('*** Stack not empty at the end') 3127db96d56Sopenharmony_ci print('***', self.stack) 3137db96d56Sopenharmony_ci if self.includedepth == 0: 3147db96d56Sopenharmony_ci while self.nodestack: 3157db96d56Sopenharmony_ci self.nodestack[-1].finalize() 3167db96d56Sopenharmony_ci self.nodestack[-1].flush() 3177db96d56Sopenharmony_ci del self.nodestack[-1] 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci # Start saving text in a buffer instead of writing it to a file 3207db96d56Sopenharmony_ci def startsaving(self): 3217db96d56Sopenharmony_ci if self.savetext is not None: 3227db96d56Sopenharmony_ci self.savestack.append(self.savetext) 3237db96d56Sopenharmony_ci # print '*** Recursively saving text, expect trouble' 3247db96d56Sopenharmony_ci self.savetext = '' 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci # Return the text saved so far and start writing to file again 3277db96d56Sopenharmony_ci def collectsavings(self): 3287db96d56Sopenharmony_ci savetext = self.savetext 3297db96d56Sopenharmony_ci if len(self.savestack) > 0: 3307db96d56Sopenharmony_ci self.savetext = self.savestack[-1] 3317db96d56Sopenharmony_ci del self.savestack[-1] 3327db96d56Sopenharmony_ci else: 3337db96d56Sopenharmony_ci self.savetext = None 3347db96d56Sopenharmony_ci return savetext or '' 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ci # Write text to file, or save it in a buffer, or ignore it 3377db96d56Sopenharmony_ci def write(self, *args): 3387db96d56Sopenharmony_ci try: 3397db96d56Sopenharmony_ci text = ''.join(args) 3407db96d56Sopenharmony_ci except: 3417db96d56Sopenharmony_ci print(args) 3427db96d56Sopenharmony_ci raise TypeError 3437db96d56Sopenharmony_ci if self.savetext is not None: 3447db96d56Sopenharmony_ci self.savetext = self.savetext + text 3457db96d56Sopenharmony_ci elif self.nodefp: 3467db96d56Sopenharmony_ci self.nodefp.write(text) 3477db96d56Sopenharmony_ci elif self.node: 3487db96d56Sopenharmony_ci self.node.write(text) 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ci # Complete the current node -- write footnotes and close file 3517db96d56Sopenharmony_ci def endnode(self): 3527db96d56Sopenharmony_ci if self.savetext is not None: 3537db96d56Sopenharmony_ci print('*** Still saving text at end of node') 3547db96d56Sopenharmony_ci dummy = self.collectsavings() 3557db96d56Sopenharmony_ci if self.footnotes: 3567db96d56Sopenharmony_ci self.writefootnotes() 3577db96d56Sopenharmony_ci if self.nodefp: 3587db96d56Sopenharmony_ci if self.nodelineno > 20: 3597db96d56Sopenharmony_ci self.write('<HR>\n') 3607db96d56Sopenharmony_ci [name, next, prev, up] = self.nodelinks[:4] 3617db96d56Sopenharmony_ci self.link('Next', next) 3627db96d56Sopenharmony_ci self.link('Prev', prev) 3637db96d56Sopenharmony_ci self.link('Up', up) 3647db96d56Sopenharmony_ci if self.nodename != self.topname: 3657db96d56Sopenharmony_ci self.link('Top', self.topname) 3667db96d56Sopenharmony_ci self.write('<HR>\n') 3677db96d56Sopenharmony_ci self.write('</BODY>\n') 3687db96d56Sopenharmony_ci self.nodefp.close() 3697db96d56Sopenharmony_ci self.nodefp = None 3707db96d56Sopenharmony_ci elif self.node: 3717db96d56Sopenharmony_ci if not self.cont and \ 3727db96d56Sopenharmony_ci (not self.node.type or \ 3737db96d56Sopenharmony_ci (self.node.next and self.node.prev and self.node.up)): 3747db96d56Sopenharmony_ci self.node.finalize() 3757db96d56Sopenharmony_ci self.node.flush() 3767db96d56Sopenharmony_ci else: 3777db96d56Sopenharmony_ci self.nodestack.append(self.node) 3787db96d56Sopenharmony_ci self.node = None 3797db96d56Sopenharmony_ci self.nodename = '' 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci # Process a list of lines, expanding embedded @-commands 3827db96d56Sopenharmony_ci # This mostly distinguishes between menus and normal text 3837db96d56Sopenharmony_ci def process(self, accu): 3847db96d56Sopenharmony_ci if self.debugging > 1: 3857db96d56Sopenharmony_ci print('!'*self.debugging, 'process:', self.skip, self.stack, end=' ') 3867db96d56Sopenharmony_ci if accu: print(accu[0][:30], end=' ') 3877db96d56Sopenharmony_ci if accu[0][30:] or accu[1:]: print('...', end=' ') 3887db96d56Sopenharmony_ci print() 3897db96d56Sopenharmony_ci if self.inmenu(): 3907db96d56Sopenharmony_ci # XXX should be done differently 3917db96d56Sopenharmony_ci for line in accu: 3927db96d56Sopenharmony_ci mo = miprog.match(line) 3937db96d56Sopenharmony_ci if not mo: 3947db96d56Sopenharmony_ci line = line.strip() + '\n' 3957db96d56Sopenharmony_ci self.expand(line) 3967db96d56Sopenharmony_ci continue 3977db96d56Sopenharmony_ci bgn, end = mo.span(0) 3987db96d56Sopenharmony_ci a, b = mo.span(1) 3997db96d56Sopenharmony_ci c, d = mo.span(2) 4007db96d56Sopenharmony_ci e, f = mo.span(3) 4017db96d56Sopenharmony_ci g, h = mo.span(4) 4027db96d56Sopenharmony_ci label = line[a:b] 4037db96d56Sopenharmony_ci nodename = line[c:d] 4047db96d56Sopenharmony_ci if nodename[0] == ':': nodename = label 4057db96d56Sopenharmony_ci else: nodename = line[e:f] 4067db96d56Sopenharmony_ci punct = line[g:h] 4077db96d56Sopenharmony_ci self.write(' <LI><A HREF="', 4087db96d56Sopenharmony_ci makefile(nodename), 4097db96d56Sopenharmony_ci '">', nodename, 4107db96d56Sopenharmony_ci '</A>', punct, '\n') 4117db96d56Sopenharmony_ci self.htmlhelp.menuitem(nodename) 4127db96d56Sopenharmony_ci self.expand(line[end:]) 4137db96d56Sopenharmony_ci else: 4147db96d56Sopenharmony_ci text = ''.join(accu) 4157db96d56Sopenharmony_ci self.expand(text) 4167db96d56Sopenharmony_ci 4177db96d56Sopenharmony_ci # find 'menu' (we might be inside 'ifset' or 'ifclear') 4187db96d56Sopenharmony_ci def inmenu(self): 4197db96d56Sopenharmony_ci #if 'menu' in self.stack: 4207db96d56Sopenharmony_ci # print 'inmenu :', self.skip, self.stack, self.stackinfo 4217db96d56Sopenharmony_ci stack = self.stack 4227db96d56Sopenharmony_ci while stack and stack[-1] in ('ifset','ifclear'): 4237db96d56Sopenharmony_ci try: 4247db96d56Sopenharmony_ci if self.stackinfo[len(stack)]: 4257db96d56Sopenharmony_ci return 0 4267db96d56Sopenharmony_ci except KeyError: 4277db96d56Sopenharmony_ci pass 4287db96d56Sopenharmony_ci stack = stack[:-1] 4297db96d56Sopenharmony_ci return (stack and stack[-1] == 'menu') 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_ci # Write a string, expanding embedded @-commands 4327db96d56Sopenharmony_ci def expand(self, text): 4337db96d56Sopenharmony_ci stack = [] 4347db96d56Sopenharmony_ci i = 0 4357db96d56Sopenharmony_ci n = len(text) 4367db96d56Sopenharmony_ci while i < n: 4377db96d56Sopenharmony_ci start = i 4387db96d56Sopenharmony_ci mo = spprog.search(text, i) 4397db96d56Sopenharmony_ci if mo: 4407db96d56Sopenharmony_ci i = mo.start() 4417db96d56Sopenharmony_ci else: 4427db96d56Sopenharmony_ci self.write(text[start:]) 4437db96d56Sopenharmony_ci break 4447db96d56Sopenharmony_ci self.write(text[start:i]) 4457db96d56Sopenharmony_ci c = text[i] 4467db96d56Sopenharmony_ci i = i+1 4477db96d56Sopenharmony_ci if c == '\n': 4487db96d56Sopenharmony_ci self.write('\n') 4497db96d56Sopenharmony_ci continue 4507db96d56Sopenharmony_ci if c == '<': 4517db96d56Sopenharmony_ci self.write('<') 4527db96d56Sopenharmony_ci continue 4537db96d56Sopenharmony_ci if c == '>': 4547db96d56Sopenharmony_ci self.write('>') 4557db96d56Sopenharmony_ci continue 4567db96d56Sopenharmony_ci if c == '&': 4577db96d56Sopenharmony_ci self.write('&') 4587db96d56Sopenharmony_ci continue 4597db96d56Sopenharmony_ci if c == '{': 4607db96d56Sopenharmony_ci stack.append('') 4617db96d56Sopenharmony_ci continue 4627db96d56Sopenharmony_ci if c == '}': 4637db96d56Sopenharmony_ci if not stack: 4647db96d56Sopenharmony_ci print('*** Unmatched }') 4657db96d56Sopenharmony_ci self.write('}') 4667db96d56Sopenharmony_ci continue 4677db96d56Sopenharmony_ci cmd = stack[-1] 4687db96d56Sopenharmony_ci del stack[-1] 4697db96d56Sopenharmony_ci try: 4707db96d56Sopenharmony_ci method = getattr(self, 'close_' + cmd) 4717db96d56Sopenharmony_ci except AttributeError: 4727db96d56Sopenharmony_ci self.unknown_close(cmd) 4737db96d56Sopenharmony_ci continue 4747db96d56Sopenharmony_ci method() 4757db96d56Sopenharmony_ci continue 4767db96d56Sopenharmony_ci if c != '@': 4777db96d56Sopenharmony_ci # Cannot happen unless spprog is changed 4787db96d56Sopenharmony_ci raise RuntimeError('unexpected funny %r' % c) 4797db96d56Sopenharmony_ci start = i 4807db96d56Sopenharmony_ci while i < n and text[i] in string.ascii_letters: i = i+1 4817db96d56Sopenharmony_ci if i == start: 4827db96d56Sopenharmony_ci # @ plus non-letter: literal next character 4837db96d56Sopenharmony_ci i = i+1 4847db96d56Sopenharmony_ci c = text[start:i] 4857db96d56Sopenharmony_ci if c == ':': 4867db96d56Sopenharmony_ci # `@:' means no extra space after 4877db96d56Sopenharmony_ci # preceding `.', `?', `!' or `:' 4887db96d56Sopenharmony_ci pass 4897db96d56Sopenharmony_ci else: 4907db96d56Sopenharmony_ci # `@.' means a sentence-ending period; 4917db96d56Sopenharmony_ci # `@@', `@{', `@}' quote `@', `{', `}' 4927db96d56Sopenharmony_ci self.write(c) 4937db96d56Sopenharmony_ci continue 4947db96d56Sopenharmony_ci cmd = text[start:i] 4957db96d56Sopenharmony_ci if i < n and text[i] == '{': 4967db96d56Sopenharmony_ci i = i+1 4977db96d56Sopenharmony_ci stack.append(cmd) 4987db96d56Sopenharmony_ci try: 4997db96d56Sopenharmony_ci method = getattr(self, 'open_' + cmd) 5007db96d56Sopenharmony_ci except AttributeError: 5017db96d56Sopenharmony_ci self.unknown_open(cmd) 5027db96d56Sopenharmony_ci continue 5037db96d56Sopenharmony_ci method() 5047db96d56Sopenharmony_ci continue 5057db96d56Sopenharmony_ci try: 5067db96d56Sopenharmony_ci method = getattr(self, 'handle_' + cmd) 5077db96d56Sopenharmony_ci except AttributeError: 5087db96d56Sopenharmony_ci self.unknown_handle(cmd) 5097db96d56Sopenharmony_ci continue 5107db96d56Sopenharmony_ci method() 5117db96d56Sopenharmony_ci if stack: 5127db96d56Sopenharmony_ci print('*** Stack not empty at para:', stack) 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci # --- Handle unknown embedded @-commands --- 5157db96d56Sopenharmony_ci 5167db96d56Sopenharmony_ci def unknown_open(self, cmd): 5177db96d56Sopenharmony_ci print('*** No open func for @' + cmd + '{...}') 5187db96d56Sopenharmony_ci cmd = cmd + '{' 5197db96d56Sopenharmony_ci self.write('@', cmd) 5207db96d56Sopenharmony_ci if cmd not in self.unknown: 5217db96d56Sopenharmony_ci self.unknown[cmd] = 1 5227db96d56Sopenharmony_ci else: 5237db96d56Sopenharmony_ci self.unknown[cmd] = self.unknown[cmd] + 1 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_ci def unknown_close(self, cmd): 5267db96d56Sopenharmony_ci print('*** No close func for @' + cmd + '{...}') 5277db96d56Sopenharmony_ci cmd = '}' + cmd 5287db96d56Sopenharmony_ci self.write('}') 5297db96d56Sopenharmony_ci if cmd not in self.unknown: 5307db96d56Sopenharmony_ci self.unknown[cmd] = 1 5317db96d56Sopenharmony_ci else: 5327db96d56Sopenharmony_ci self.unknown[cmd] = self.unknown[cmd] + 1 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci def unknown_handle(self, cmd): 5357db96d56Sopenharmony_ci print('*** No handler for @' + cmd) 5367db96d56Sopenharmony_ci self.write('@', cmd) 5377db96d56Sopenharmony_ci if cmd not in self.unknown: 5387db96d56Sopenharmony_ci self.unknown[cmd] = 1 5397db96d56Sopenharmony_ci else: 5407db96d56Sopenharmony_ci self.unknown[cmd] = self.unknown[cmd] + 1 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci # XXX The following sections should be ordered as the texinfo docs 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_ci # --- Embedded @-commands without {} argument list -- 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_ci def handle_noindent(self): pass 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci def handle_refill(self): pass 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci # --- Include file handling --- 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_ci def do_include(self, args): 5537db96d56Sopenharmony_ci file = args 5547db96d56Sopenharmony_ci file = os.path.join(self.includedir, file) 5557db96d56Sopenharmony_ci try: 5567db96d56Sopenharmony_ci fp = open(file, 'r') 5577db96d56Sopenharmony_ci except IOError as msg: 5587db96d56Sopenharmony_ci print('*** Can\'t open include file', repr(file)) 5597db96d56Sopenharmony_ci return 5607db96d56Sopenharmony_ci with fp: 5617db96d56Sopenharmony_ci print('!'*self.debugging, '--> file', repr(file)) 5627db96d56Sopenharmony_ci save_done = self.done 5637db96d56Sopenharmony_ci save_skip = self.skip 5647db96d56Sopenharmony_ci save_stack = self.stack 5657db96d56Sopenharmony_ci self.includedepth = self.includedepth + 1 5667db96d56Sopenharmony_ci self.parserest(fp, 0) 5677db96d56Sopenharmony_ci self.includedepth = self.includedepth - 1 5687db96d56Sopenharmony_ci self.done = save_done 5697db96d56Sopenharmony_ci self.skip = save_skip 5707db96d56Sopenharmony_ci self.stack = save_stack 5717db96d56Sopenharmony_ci print('!'*self.debugging, '<-- file', repr(file)) 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ci # --- Special Insertions --- 5747db96d56Sopenharmony_ci 5757db96d56Sopenharmony_ci def open_dmn(self): pass 5767db96d56Sopenharmony_ci def close_dmn(self): pass 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ci def open_dots(self): self.write('...') 5797db96d56Sopenharmony_ci def close_dots(self): pass 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ci def open_bullet(self): pass 5827db96d56Sopenharmony_ci def close_bullet(self): pass 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_ci def open_TeX(self): self.write('TeX') 5857db96d56Sopenharmony_ci def close_TeX(self): pass 5867db96d56Sopenharmony_ci 5877db96d56Sopenharmony_ci def handle_copyright(self): self.write(self.COPYRIGHT_SYMBOL) 5887db96d56Sopenharmony_ci def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL) 5897db96d56Sopenharmony_ci def close_copyright(self): pass 5907db96d56Sopenharmony_ci 5917db96d56Sopenharmony_ci def open_minus(self): self.write('-') 5927db96d56Sopenharmony_ci def close_minus(self): pass 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ci # --- Accents --- 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_ci # rpyron 2002-05-07 5977db96d56Sopenharmony_ci # I would like to do at least as well as makeinfo when 5987db96d56Sopenharmony_ci # it is producing HTML output: 5997db96d56Sopenharmony_ci # 6007db96d56Sopenharmony_ci # input output 6017db96d56Sopenharmony_ci # @"o @"o umlaut accent 6027db96d56Sopenharmony_ci # @'o 'o acute accent 6037db96d56Sopenharmony_ci # @,{c} @,{c} cedilla accent 6047db96d56Sopenharmony_ci # @=o @=o macron/overbar accent 6057db96d56Sopenharmony_ci # @^o @^o circumflex accent 6067db96d56Sopenharmony_ci # @`o `o grave accent 6077db96d56Sopenharmony_ci # @~o @~o tilde accent 6087db96d56Sopenharmony_ci # @dotaccent{o} @dotaccent{o} overdot accent 6097db96d56Sopenharmony_ci # @H{o} @H{o} long Hungarian umlaut 6107db96d56Sopenharmony_ci # @ringaccent{o} @ringaccent{o} ring accent 6117db96d56Sopenharmony_ci # @tieaccent{oo} @tieaccent{oo} tie-after accent 6127db96d56Sopenharmony_ci # @u{o} @u{o} breve accent 6137db96d56Sopenharmony_ci # @ubaraccent{o} @ubaraccent{o} underbar accent 6147db96d56Sopenharmony_ci # @udotaccent{o} @udotaccent{o} underdot accent 6157db96d56Sopenharmony_ci # @v{o} @v{o} hacek or check accent 6167db96d56Sopenharmony_ci # @exclamdown{} ¡ upside-down ! 6177db96d56Sopenharmony_ci # @questiondown{} ¿ upside-down ? 6187db96d56Sopenharmony_ci # @aa{},@AA{} å,Å a,A with circle 6197db96d56Sopenharmony_ci # @ae{},@AE{} æ,Æ ae,AE ligatures 6207db96d56Sopenharmony_ci # @dotless{i} @dotless{i} dotless i 6217db96d56Sopenharmony_ci # @dotless{j} @dotless{j} dotless j 6227db96d56Sopenharmony_ci # @l{},@L{} l/,L/ suppressed-L,l 6237db96d56Sopenharmony_ci # @o{},@O{} ø,Ø O,o with slash 6247db96d56Sopenharmony_ci # @oe{},@OE{} oe,OE oe,OE ligatures 6257db96d56Sopenharmony_ci # @ss{} ß es-zet or sharp S 6267db96d56Sopenharmony_ci # 6277db96d56Sopenharmony_ci # The following character codes and approximations have been 6287db96d56Sopenharmony_ci # copied from makeinfo's HTML output. 6297db96d56Sopenharmony_ci 6307db96d56Sopenharmony_ci def open_exclamdown(self): self.write('¡') # upside-down ! 6317db96d56Sopenharmony_ci def close_exclamdown(self): pass 6327db96d56Sopenharmony_ci def open_questiondown(self): self.write('¿') # upside-down ? 6337db96d56Sopenharmony_ci def close_questiondown(self): pass 6347db96d56Sopenharmony_ci def open_aa(self): self.write('å') # a with circle 6357db96d56Sopenharmony_ci def close_aa(self): pass 6367db96d56Sopenharmony_ci def open_AA(self): self.write('Å') # A with circle 6377db96d56Sopenharmony_ci def close_AA(self): pass 6387db96d56Sopenharmony_ci def open_ae(self): self.write('æ') # ae ligatures 6397db96d56Sopenharmony_ci def close_ae(self): pass 6407db96d56Sopenharmony_ci def open_AE(self): self.write('Æ') # AE ligatures 6417db96d56Sopenharmony_ci def close_AE(self): pass 6427db96d56Sopenharmony_ci def open_o(self): self.write('ø') # o with slash 6437db96d56Sopenharmony_ci def close_o(self): pass 6447db96d56Sopenharmony_ci def open_O(self): self.write('Ø') # O with slash 6457db96d56Sopenharmony_ci def close_O(self): pass 6467db96d56Sopenharmony_ci def open_ss(self): self.write('ß') # es-zet or sharp S 6477db96d56Sopenharmony_ci def close_ss(self): pass 6487db96d56Sopenharmony_ci def open_oe(self): self.write('oe') # oe ligatures 6497db96d56Sopenharmony_ci def close_oe(self): pass 6507db96d56Sopenharmony_ci def open_OE(self): self.write('OE') # OE ligatures 6517db96d56Sopenharmony_ci def close_OE(self): pass 6527db96d56Sopenharmony_ci def open_l(self): self.write('l/') # suppressed-l 6537db96d56Sopenharmony_ci def close_l(self): pass 6547db96d56Sopenharmony_ci def open_L(self): self.write('L/') # suppressed-L 6557db96d56Sopenharmony_ci def close_L(self): pass 6567db96d56Sopenharmony_ci 6577db96d56Sopenharmony_ci # --- Special Glyphs for Examples --- 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci def open_result(self): self.write('=>') 6607db96d56Sopenharmony_ci def close_result(self): pass 6617db96d56Sopenharmony_ci 6627db96d56Sopenharmony_ci def open_expansion(self): self.write('==>') 6637db96d56Sopenharmony_ci def close_expansion(self): pass 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_ci def open_print(self): self.write('-|') 6667db96d56Sopenharmony_ci def close_print(self): pass 6677db96d56Sopenharmony_ci 6687db96d56Sopenharmony_ci def open_error(self): self.write('error-->') 6697db96d56Sopenharmony_ci def close_error(self): pass 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci def open_equiv(self): self.write('==') 6727db96d56Sopenharmony_ci def close_equiv(self): pass 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ci def open_point(self): self.write('-!-') 6757db96d56Sopenharmony_ci def close_point(self): pass 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci # --- Cross References --- 6787db96d56Sopenharmony_ci 6797db96d56Sopenharmony_ci def open_pxref(self): 6807db96d56Sopenharmony_ci self.write('see ') 6817db96d56Sopenharmony_ci self.startsaving() 6827db96d56Sopenharmony_ci def close_pxref(self): 6837db96d56Sopenharmony_ci self.makeref() 6847db96d56Sopenharmony_ci 6857db96d56Sopenharmony_ci def open_xref(self): 6867db96d56Sopenharmony_ci self.write('See ') 6877db96d56Sopenharmony_ci self.startsaving() 6887db96d56Sopenharmony_ci def close_xref(self): 6897db96d56Sopenharmony_ci self.makeref() 6907db96d56Sopenharmony_ci 6917db96d56Sopenharmony_ci def open_ref(self): 6927db96d56Sopenharmony_ci self.startsaving() 6937db96d56Sopenharmony_ci def close_ref(self): 6947db96d56Sopenharmony_ci self.makeref() 6957db96d56Sopenharmony_ci 6967db96d56Sopenharmony_ci def open_inforef(self): 6977db96d56Sopenharmony_ci self.write('See info file ') 6987db96d56Sopenharmony_ci self.startsaving() 6997db96d56Sopenharmony_ci def close_inforef(self): 7007db96d56Sopenharmony_ci text = self.collectsavings() 7017db96d56Sopenharmony_ci args = [s.strip() for s in text.split(',')] 7027db96d56Sopenharmony_ci while len(args) < 3: args.append('') 7037db96d56Sopenharmony_ci node = args[0] 7047db96d56Sopenharmony_ci file = args[2] 7057db96d56Sopenharmony_ci self.write('`', file, '\', node `', node, '\'') 7067db96d56Sopenharmony_ci 7077db96d56Sopenharmony_ci def makeref(self): 7087db96d56Sopenharmony_ci text = self.collectsavings() 7097db96d56Sopenharmony_ci args = [s.strip() for s in text.split(',')] 7107db96d56Sopenharmony_ci while len(args) < 5: args.append('') 7117db96d56Sopenharmony_ci nodename = label = args[0] 7127db96d56Sopenharmony_ci if args[2]: label = args[2] 7137db96d56Sopenharmony_ci file = args[3] 7147db96d56Sopenharmony_ci title = args[4] 7157db96d56Sopenharmony_ci href = makefile(nodename) 7167db96d56Sopenharmony_ci if file: 7177db96d56Sopenharmony_ci href = '../' + file + '/' + href 7187db96d56Sopenharmony_ci self.write('<A HREF="', href, '">', label, '</A>') 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_ci # rpyron 2002-05-07 uref support 7217db96d56Sopenharmony_ci def open_uref(self): 7227db96d56Sopenharmony_ci self.startsaving() 7237db96d56Sopenharmony_ci def close_uref(self): 7247db96d56Sopenharmony_ci text = self.collectsavings() 7257db96d56Sopenharmony_ci args = [s.strip() for s in text.split(',')] 7267db96d56Sopenharmony_ci while len(args) < 2: args.append('') 7277db96d56Sopenharmony_ci href = args[0] 7287db96d56Sopenharmony_ci label = args[1] 7297db96d56Sopenharmony_ci if not label: label = href 7307db96d56Sopenharmony_ci self.write('<A HREF="', href, '">', label, '</A>') 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci # rpyron 2002-05-07 image support 7337db96d56Sopenharmony_ci # GNU makeinfo producing HTML output tries `filename.png'; if 7347db96d56Sopenharmony_ci # that does not exist, it tries `filename.jpg'. If that does 7357db96d56Sopenharmony_ci # not exist either, it complains. GNU makeinfo does not handle 7367db96d56Sopenharmony_ci # GIF files; however, I include GIF support here because 7377db96d56Sopenharmony_ci # MySQL documentation uses GIF files. 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci def open_image(self): 7407db96d56Sopenharmony_ci self.startsaving() 7417db96d56Sopenharmony_ci def close_image(self): 7427db96d56Sopenharmony_ci self.makeimage() 7437db96d56Sopenharmony_ci def makeimage(self): 7447db96d56Sopenharmony_ci text = self.collectsavings() 7457db96d56Sopenharmony_ci args = [s.strip() for s in text.split(',')] 7467db96d56Sopenharmony_ci while len(args) < 5: args.append('') 7477db96d56Sopenharmony_ci filename = args[0] 7487db96d56Sopenharmony_ci width = args[1] 7497db96d56Sopenharmony_ci height = args[2] 7507db96d56Sopenharmony_ci alt = args[3] 7517db96d56Sopenharmony_ci ext = args[4] 7527db96d56Sopenharmony_ci 7537db96d56Sopenharmony_ci # The HTML output will have a reference to the image 7547db96d56Sopenharmony_ci # that is relative to the HTML output directory, 7557db96d56Sopenharmony_ci # which is what 'filename' gives us. However, we need 7567db96d56Sopenharmony_ci # to find it relative to our own current directory, 7577db96d56Sopenharmony_ci # so we construct 'imagename'. 7587db96d56Sopenharmony_ci imagelocation = self.dirname + '/' + filename 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_ci if os.path.exists(imagelocation+'.png'): 7617db96d56Sopenharmony_ci filename += '.png' 7627db96d56Sopenharmony_ci elif os.path.exists(imagelocation+'.jpg'): 7637db96d56Sopenharmony_ci filename += '.jpg' 7647db96d56Sopenharmony_ci elif os.path.exists(imagelocation+'.gif'): # MySQL uses GIF files 7657db96d56Sopenharmony_ci filename += '.gif' 7667db96d56Sopenharmony_ci else: 7677db96d56Sopenharmony_ci print("*** Cannot find image " + imagelocation) 7687db96d56Sopenharmony_ci #TODO: what is 'ext'? 7697db96d56Sopenharmony_ci self.write('<IMG SRC="', filename, '"', \ 7707db96d56Sopenharmony_ci width and (' WIDTH="' + width + '"') or "", \ 7717db96d56Sopenharmony_ci height and (' HEIGHT="' + height + '"') or "", \ 7727db96d56Sopenharmony_ci alt and (' ALT="' + alt + '"') or "", \ 7737db96d56Sopenharmony_ci '/>' ) 7747db96d56Sopenharmony_ci self.htmlhelp.addimage(imagelocation) 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci 7777db96d56Sopenharmony_ci # --- Marking Words and Phrases --- 7787db96d56Sopenharmony_ci 7797db96d56Sopenharmony_ci # --- Other @xxx{...} commands --- 7807db96d56Sopenharmony_ci 7817db96d56Sopenharmony_ci def open_(self): pass # Used by {text enclosed in braces} 7827db96d56Sopenharmony_ci def close_(self): pass 7837db96d56Sopenharmony_ci 7847db96d56Sopenharmony_ci open_asis = open_ 7857db96d56Sopenharmony_ci close_asis = close_ 7867db96d56Sopenharmony_ci 7877db96d56Sopenharmony_ci def open_cite(self): self.write('<CITE>') 7887db96d56Sopenharmony_ci def close_cite(self): self.write('</CITE>') 7897db96d56Sopenharmony_ci 7907db96d56Sopenharmony_ci def open_code(self): self.write('<CODE>') 7917db96d56Sopenharmony_ci def close_code(self): self.write('</CODE>') 7927db96d56Sopenharmony_ci 7937db96d56Sopenharmony_ci def open_t(self): self.write('<TT>') 7947db96d56Sopenharmony_ci def close_t(self): self.write('</TT>') 7957db96d56Sopenharmony_ci 7967db96d56Sopenharmony_ci def open_dfn(self): self.write('<DFN>') 7977db96d56Sopenharmony_ci def close_dfn(self): self.write('</DFN>') 7987db96d56Sopenharmony_ci 7997db96d56Sopenharmony_ci def open_emph(self): self.write('<EM>') 8007db96d56Sopenharmony_ci def close_emph(self): self.write('</EM>') 8017db96d56Sopenharmony_ci 8027db96d56Sopenharmony_ci def open_i(self): self.write('<I>') 8037db96d56Sopenharmony_ci def close_i(self): self.write('</I>') 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci def open_footnote(self): 8067db96d56Sopenharmony_ci # if self.savetext is not None: 8077db96d56Sopenharmony_ci # print '*** Recursive footnote -- expect weirdness' 8087db96d56Sopenharmony_ci id = len(self.footnotes) + 1 8097db96d56Sopenharmony_ci self.write(self.FN_SOURCE_PATTERN % {'id': repr(id)}) 8107db96d56Sopenharmony_ci self.startsaving() 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci def close_footnote(self): 8137db96d56Sopenharmony_ci id = len(self.footnotes) + 1 8147db96d56Sopenharmony_ci self.footnotes.append((id, self.collectsavings())) 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ci def writefootnotes(self): 8177db96d56Sopenharmony_ci self.write(self.FN_HEADER) 8187db96d56Sopenharmony_ci for id, text in self.footnotes: 8197db96d56Sopenharmony_ci self.write(self.FN_TARGET_PATTERN 8207db96d56Sopenharmony_ci % {'id': repr(id), 'text': text}) 8217db96d56Sopenharmony_ci self.footnotes = [] 8227db96d56Sopenharmony_ci 8237db96d56Sopenharmony_ci def open_file(self): self.write('<CODE>') 8247db96d56Sopenharmony_ci def close_file(self): self.write('</CODE>') 8257db96d56Sopenharmony_ci 8267db96d56Sopenharmony_ci def open_kbd(self): self.write('<KBD>') 8277db96d56Sopenharmony_ci def close_kbd(self): self.write('</KBD>') 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci def open_key(self): self.write('<KEY>') 8307db96d56Sopenharmony_ci def close_key(self): self.write('</KEY>') 8317db96d56Sopenharmony_ci 8327db96d56Sopenharmony_ci def open_r(self): self.write('<R>') 8337db96d56Sopenharmony_ci def close_r(self): self.write('</R>') 8347db96d56Sopenharmony_ci 8357db96d56Sopenharmony_ci def open_samp(self): self.write('`<SAMP>') 8367db96d56Sopenharmony_ci def close_samp(self): self.write('</SAMP>\'') 8377db96d56Sopenharmony_ci 8387db96d56Sopenharmony_ci def open_sc(self): self.write('<SMALLCAPS>') 8397db96d56Sopenharmony_ci def close_sc(self): self.write('</SMALLCAPS>') 8407db96d56Sopenharmony_ci 8417db96d56Sopenharmony_ci def open_strong(self): self.write('<STRONG>') 8427db96d56Sopenharmony_ci def close_strong(self): self.write('</STRONG>') 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci def open_b(self): self.write('<B>') 8457db96d56Sopenharmony_ci def close_b(self): self.write('</B>') 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_ci def open_var(self): self.write('<VAR>') 8487db96d56Sopenharmony_ci def close_var(self): self.write('</VAR>') 8497db96d56Sopenharmony_ci 8507db96d56Sopenharmony_ci def open_w(self): self.write('<NOBREAK>') 8517db96d56Sopenharmony_ci def close_w(self): self.write('</NOBREAK>') 8527db96d56Sopenharmony_ci 8537db96d56Sopenharmony_ci def open_url(self): self.startsaving() 8547db96d56Sopenharmony_ci def close_url(self): 8557db96d56Sopenharmony_ci text = self.collectsavings() 8567db96d56Sopenharmony_ci self.write('<A HREF="', text, '">', text, '</A>') 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci def open_email(self): self.startsaving() 8597db96d56Sopenharmony_ci def close_email(self): 8607db96d56Sopenharmony_ci text = self.collectsavings() 8617db96d56Sopenharmony_ci self.write('<A HREF="mailto:', text, '">', text, '</A>') 8627db96d56Sopenharmony_ci 8637db96d56Sopenharmony_ci open_titlefont = open_ 8647db96d56Sopenharmony_ci close_titlefont = close_ 8657db96d56Sopenharmony_ci 8667db96d56Sopenharmony_ci def open_small(self): pass 8677db96d56Sopenharmony_ci def close_small(self): pass 8687db96d56Sopenharmony_ci 8697db96d56Sopenharmony_ci def command(self, line, mo): 8707db96d56Sopenharmony_ci a, b = mo.span(1) 8717db96d56Sopenharmony_ci cmd = line[a:b] 8727db96d56Sopenharmony_ci args = line[b:].strip() 8737db96d56Sopenharmony_ci if self.debugging > 1: 8747db96d56Sopenharmony_ci print('!'*self.debugging, 'command:', self.skip, self.stack, \ 8757db96d56Sopenharmony_ci '@' + cmd, args) 8767db96d56Sopenharmony_ci try: 8777db96d56Sopenharmony_ci func = getattr(self, 'do_' + cmd) 8787db96d56Sopenharmony_ci except AttributeError: 8797db96d56Sopenharmony_ci try: 8807db96d56Sopenharmony_ci func = getattr(self, 'bgn_' + cmd) 8817db96d56Sopenharmony_ci except AttributeError: 8827db96d56Sopenharmony_ci # don't complain if we are skipping anyway 8837db96d56Sopenharmony_ci if not self.skip: 8847db96d56Sopenharmony_ci self.unknown_cmd(cmd, args) 8857db96d56Sopenharmony_ci return 8867db96d56Sopenharmony_ci self.stack.append(cmd) 8877db96d56Sopenharmony_ci func(args) 8887db96d56Sopenharmony_ci return 8897db96d56Sopenharmony_ci if not self.skip or cmd == 'end': 8907db96d56Sopenharmony_ci func(args) 8917db96d56Sopenharmony_ci 8927db96d56Sopenharmony_ci def unknown_cmd(self, cmd, args): 8937db96d56Sopenharmony_ci print('*** unknown', '@' + cmd, args) 8947db96d56Sopenharmony_ci if cmd not in self.unknown: 8957db96d56Sopenharmony_ci self.unknown[cmd] = 1 8967db96d56Sopenharmony_ci else: 8977db96d56Sopenharmony_ci self.unknown[cmd] = self.unknown[cmd] + 1 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci def do_end(self, args): 9007db96d56Sopenharmony_ci words = args.split() 9017db96d56Sopenharmony_ci if not words: 9027db96d56Sopenharmony_ci print('*** @end w/o args') 9037db96d56Sopenharmony_ci else: 9047db96d56Sopenharmony_ci cmd = words[0] 9057db96d56Sopenharmony_ci if not self.stack or self.stack[-1] != cmd: 9067db96d56Sopenharmony_ci print('*** @end', cmd, 'unexpected') 9077db96d56Sopenharmony_ci else: 9087db96d56Sopenharmony_ci del self.stack[-1] 9097db96d56Sopenharmony_ci try: 9107db96d56Sopenharmony_ci func = getattr(self, 'end_' + cmd) 9117db96d56Sopenharmony_ci except AttributeError: 9127db96d56Sopenharmony_ci self.unknown_end(cmd) 9137db96d56Sopenharmony_ci return 9147db96d56Sopenharmony_ci func() 9157db96d56Sopenharmony_ci 9167db96d56Sopenharmony_ci def unknown_end(self, cmd): 9177db96d56Sopenharmony_ci cmd = 'end ' + cmd 9187db96d56Sopenharmony_ci print('*** unknown', '@' + cmd) 9197db96d56Sopenharmony_ci if cmd not in self.unknown: 9207db96d56Sopenharmony_ci self.unknown[cmd] = 1 9217db96d56Sopenharmony_ci else: 9227db96d56Sopenharmony_ci self.unknown[cmd] = self.unknown[cmd] + 1 9237db96d56Sopenharmony_ci 9247db96d56Sopenharmony_ci # --- Comments --- 9257db96d56Sopenharmony_ci 9267db96d56Sopenharmony_ci def do_comment(self, args): pass 9277db96d56Sopenharmony_ci do_c = do_comment 9287db96d56Sopenharmony_ci 9297db96d56Sopenharmony_ci # --- Conditional processing --- 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ci def bgn_ifinfo(self, args): pass 9327db96d56Sopenharmony_ci def end_ifinfo(self): pass 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_ci def bgn_iftex(self, args): self.skip = self.skip + 1 9357db96d56Sopenharmony_ci def end_iftex(self): self.skip = self.skip - 1 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci def bgn_ignore(self, args): self.skip = self.skip + 1 9387db96d56Sopenharmony_ci def end_ignore(self): self.skip = self.skip - 1 9397db96d56Sopenharmony_ci 9407db96d56Sopenharmony_ci def bgn_tex(self, args): self.skip = self.skip + 1 9417db96d56Sopenharmony_ci def end_tex(self): self.skip = self.skip - 1 9427db96d56Sopenharmony_ci 9437db96d56Sopenharmony_ci def do_set(self, args): 9447db96d56Sopenharmony_ci fields = args.split(' ') 9457db96d56Sopenharmony_ci key = fields[0] 9467db96d56Sopenharmony_ci if len(fields) == 1: 9477db96d56Sopenharmony_ci value = 1 9487db96d56Sopenharmony_ci else: 9497db96d56Sopenharmony_ci value = ' '.join(fields[1:]) 9507db96d56Sopenharmony_ci self.values[key] = value 9517db96d56Sopenharmony_ci 9527db96d56Sopenharmony_ci def do_clear(self, args): 9537db96d56Sopenharmony_ci self.values[args] = None 9547db96d56Sopenharmony_ci 9557db96d56Sopenharmony_ci def bgn_ifset(self, args): 9567db96d56Sopenharmony_ci if args not in self.values or self.values[args] is None: 9577db96d56Sopenharmony_ci self.skip = self.skip + 1 9587db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = 1 9597db96d56Sopenharmony_ci else: 9607db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = 0 9617db96d56Sopenharmony_ci def end_ifset(self): 9627db96d56Sopenharmony_ci try: 9637db96d56Sopenharmony_ci if self.stackinfo[len(self.stack) + 1]: 9647db96d56Sopenharmony_ci self.skip = self.skip - 1 9657db96d56Sopenharmony_ci del self.stackinfo[len(self.stack) + 1] 9667db96d56Sopenharmony_ci except KeyError: 9677db96d56Sopenharmony_ci print('*** end_ifset: KeyError :', len(self.stack) + 1) 9687db96d56Sopenharmony_ci 9697db96d56Sopenharmony_ci def bgn_ifclear(self, args): 9707db96d56Sopenharmony_ci if args in self.values and self.values[args] is not None: 9717db96d56Sopenharmony_ci self.skip = self.skip + 1 9727db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = 1 9737db96d56Sopenharmony_ci else: 9747db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = 0 9757db96d56Sopenharmony_ci def end_ifclear(self): 9767db96d56Sopenharmony_ci try: 9777db96d56Sopenharmony_ci if self.stackinfo[len(self.stack) + 1]: 9787db96d56Sopenharmony_ci self.skip = self.skip - 1 9797db96d56Sopenharmony_ci del self.stackinfo[len(self.stack) + 1] 9807db96d56Sopenharmony_ci except KeyError: 9817db96d56Sopenharmony_ci print('*** end_ifclear: KeyError :', len(self.stack) + 1) 9827db96d56Sopenharmony_ci 9837db96d56Sopenharmony_ci def open_value(self): 9847db96d56Sopenharmony_ci self.startsaving() 9857db96d56Sopenharmony_ci 9867db96d56Sopenharmony_ci def close_value(self): 9877db96d56Sopenharmony_ci key = self.collectsavings() 9887db96d56Sopenharmony_ci if key in self.values: 9897db96d56Sopenharmony_ci self.write(self.values[key]) 9907db96d56Sopenharmony_ci else: 9917db96d56Sopenharmony_ci print('*** Undefined value: ', key) 9927db96d56Sopenharmony_ci 9937db96d56Sopenharmony_ci # --- Beginning a file --- 9947db96d56Sopenharmony_ci 9957db96d56Sopenharmony_ci do_finalout = do_comment 9967db96d56Sopenharmony_ci do_setchapternewpage = do_comment 9977db96d56Sopenharmony_ci do_setfilename = do_comment 9987db96d56Sopenharmony_ci 9997db96d56Sopenharmony_ci def do_settitle(self, args): 10007db96d56Sopenharmony_ci self.startsaving() 10017db96d56Sopenharmony_ci self.expand(args) 10027db96d56Sopenharmony_ci self.title = self.collectsavings() 10037db96d56Sopenharmony_ci def do_parskip(self, args): pass 10047db96d56Sopenharmony_ci 10057db96d56Sopenharmony_ci # --- Ending a file --- 10067db96d56Sopenharmony_ci 10077db96d56Sopenharmony_ci def do_bye(self, args): 10087db96d56Sopenharmony_ci self.endnode() 10097db96d56Sopenharmony_ci self.done = 1 10107db96d56Sopenharmony_ci 10117db96d56Sopenharmony_ci # --- Title page --- 10127db96d56Sopenharmony_ci 10137db96d56Sopenharmony_ci def bgn_titlepage(self, args): self.skip = self.skip + 1 10147db96d56Sopenharmony_ci def end_titlepage(self): self.skip = self.skip - 1 10157db96d56Sopenharmony_ci def do_shorttitlepage(self, args): pass 10167db96d56Sopenharmony_ci 10177db96d56Sopenharmony_ci def do_center(self, args): 10187db96d56Sopenharmony_ci # Actually not used outside title page... 10197db96d56Sopenharmony_ci self.write('<H1>') 10207db96d56Sopenharmony_ci self.expand(args) 10217db96d56Sopenharmony_ci self.write('</H1>\n') 10227db96d56Sopenharmony_ci do_title = do_center 10237db96d56Sopenharmony_ci do_subtitle = do_center 10247db96d56Sopenharmony_ci do_author = do_center 10257db96d56Sopenharmony_ci 10267db96d56Sopenharmony_ci do_vskip = do_comment 10277db96d56Sopenharmony_ci do_vfill = do_comment 10287db96d56Sopenharmony_ci do_smallbook = do_comment 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_ci do_paragraphindent = do_comment 10317db96d56Sopenharmony_ci do_setchapternewpage = do_comment 10327db96d56Sopenharmony_ci do_headings = do_comment 10337db96d56Sopenharmony_ci do_footnotestyle = do_comment 10347db96d56Sopenharmony_ci 10357db96d56Sopenharmony_ci do_evenheading = do_comment 10367db96d56Sopenharmony_ci do_evenfooting = do_comment 10377db96d56Sopenharmony_ci do_oddheading = do_comment 10387db96d56Sopenharmony_ci do_oddfooting = do_comment 10397db96d56Sopenharmony_ci do_everyheading = do_comment 10407db96d56Sopenharmony_ci do_everyfooting = do_comment 10417db96d56Sopenharmony_ci 10427db96d56Sopenharmony_ci # --- Nodes --- 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_ci def do_node(self, args): 10457db96d56Sopenharmony_ci self.endnode() 10467db96d56Sopenharmony_ci self.nodelineno = 0 10477db96d56Sopenharmony_ci parts = [s.strip() for s in args.split(',')] 10487db96d56Sopenharmony_ci while len(parts) < 4: parts.append('') 10497db96d56Sopenharmony_ci self.nodelinks = parts 10507db96d56Sopenharmony_ci [name, next, prev, up] = parts[:4] 10517db96d56Sopenharmony_ci file = self.dirname + '/' + makefile(name) 10527db96d56Sopenharmony_ci if file in self.filenames: 10537db96d56Sopenharmony_ci print('*** Filename already in use: ', file) 10547db96d56Sopenharmony_ci else: 10557db96d56Sopenharmony_ci if self.debugging: print('!'*self.debugging, '--- writing', file) 10567db96d56Sopenharmony_ci self.filenames[file] = 1 10577db96d56Sopenharmony_ci # self.nodefp = open(file, 'w') 10587db96d56Sopenharmony_ci self.nodename = name 10597db96d56Sopenharmony_ci if self.cont and self.nodestack: 10607db96d56Sopenharmony_ci self.nodestack[-1].cont = self.nodename 10617db96d56Sopenharmony_ci if not self.topname: self.topname = name 10627db96d56Sopenharmony_ci title = name 10637db96d56Sopenharmony_ci if self.title: title = title + ' -- ' + self.title 10647db96d56Sopenharmony_ci self.node = self.Node(self.dirname, self.nodename, self.topname, 10657db96d56Sopenharmony_ci title, next, prev, up) 10667db96d56Sopenharmony_ci self.htmlhelp.addnode(self.nodename,next,prev,up,file) 10677db96d56Sopenharmony_ci 10687db96d56Sopenharmony_ci def link(self, label, nodename): 10697db96d56Sopenharmony_ci if nodename: 10707db96d56Sopenharmony_ci if nodename.lower() == '(dir)': 10717db96d56Sopenharmony_ci addr = '../dir.html' 10727db96d56Sopenharmony_ci else: 10737db96d56Sopenharmony_ci addr = makefile(nodename) 10747db96d56Sopenharmony_ci self.write(label, ': <A HREF="', addr, '" TYPE="', 10757db96d56Sopenharmony_ci label, '">', nodename, '</A> \n') 10767db96d56Sopenharmony_ci 10777db96d56Sopenharmony_ci # --- Sectioning commands --- 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_ci def popstack(self, type): 10807db96d56Sopenharmony_ci if (self.node): 10817db96d56Sopenharmony_ci self.node.type = type 10827db96d56Sopenharmony_ci while self.nodestack: 10837db96d56Sopenharmony_ci if self.nodestack[-1].type > type: 10847db96d56Sopenharmony_ci self.nodestack[-1].finalize() 10857db96d56Sopenharmony_ci self.nodestack[-1].flush() 10867db96d56Sopenharmony_ci del self.nodestack[-1] 10877db96d56Sopenharmony_ci elif self.nodestack[-1].type == type: 10887db96d56Sopenharmony_ci if not self.nodestack[-1].next: 10897db96d56Sopenharmony_ci self.nodestack[-1].next = self.node.name 10907db96d56Sopenharmony_ci if not self.node.prev: 10917db96d56Sopenharmony_ci self.node.prev = self.nodestack[-1].name 10927db96d56Sopenharmony_ci self.nodestack[-1].finalize() 10937db96d56Sopenharmony_ci self.nodestack[-1].flush() 10947db96d56Sopenharmony_ci del self.nodestack[-1] 10957db96d56Sopenharmony_ci else: 10967db96d56Sopenharmony_ci if type > 1 and not self.node.up: 10977db96d56Sopenharmony_ci self.node.up = self.nodestack[-1].name 10987db96d56Sopenharmony_ci break 10997db96d56Sopenharmony_ci 11007db96d56Sopenharmony_ci def do_chapter(self, args): 11017db96d56Sopenharmony_ci self.heading('H1', args, 0) 11027db96d56Sopenharmony_ci self.popstack(1) 11037db96d56Sopenharmony_ci 11047db96d56Sopenharmony_ci def do_unnumbered(self, args): 11057db96d56Sopenharmony_ci self.heading('H1', args, -1) 11067db96d56Sopenharmony_ci self.popstack(1) 11077db96d56Sopenharmony_ci def do_appendix(self, args): 11087db96d56Sopenharmony_ci self.heading('H1', args, -1) 11097db96d56Sopenharmony_ci self.popstack(1) 11107db96d56Sopenharmony_ci def do_top(self, args): 11117db96d56Sopenharmony_ci self.heading('H1', args, -1) 11127db96d56Sopenharmony_ci def do_chapheading(self, args): 11137db96d56Sopenharmony_ci self.heading('H1', args, -1) 11147db96d56Sopenharmony_ci def do_majorheading(self, args): 11157db96d56Sopenharmony_ci self.heading('H1', args, -1) 11167db96d56Sopenharmony_ci 11177db96d56Sopenharmony_ci def do_section(self, args): 11187db96d56Sopenharmony_ci self.heading('H1', args, 1) 11197db96d56Sopenharmony_ci self.popstack(2) 11207db96d56Sopenharmony_ci 11217db96d56Sopenharmony_ci def do_unnumberedsec(self, args): 11227db96d56Sopenharmony_ci self.heading('H1', args, -1) 11237db96d56Sopenharmony_ci self.popstack(2) 11247db96d56Sopenharmony_ci def do_appendixsec(self, args): 11257db96d56Sopenharmony_ci self.heading('H1', args, -1) 11267db96d56Sopenharmony_ci self.popstack(2) 11277db96d56Sopenharmony_ci do_appendixsection = do_appendixsec 11287db96d56Sopenharmony_ci def do_heading(self, args): 11297db96d56Sopenharmony_ci self.heading('H1', args, -1) 11307db96d56Sopenharmony_ci 11317db96d56Sopenharmony_ci def do_subsection(self, args): 11327db96d56Sopenharmony_ci self.heading('H2', args, 2) 11337db96d56Sopenharmony_ci self.popstack(3) 11347db96d56Sopenharmony_ci def do_unnumberedsubsec(self, args): 11357db96d56Sopenharmony_ci self.heading('H2', args, -1) 11367db96d56Sopenharmony_ci self.popstack(3) 11377db96d56Sopenharmony_ci def do_appendixsubsec(self, args): 11387db96d56Sopenharmony_ci self.heading('H2', args, -1) 11397db96d56Sopenharmony_ci self.popstack(3) 11407db96d56Sopenharmony_ci def do_subheading(self, args): 11417db96d56Sopenharmony_ci self.heading('H2', args, -1) 11427db96d56Sopenharmony_ci 11437db96d56Sopenharmony_ci def do_subsubsection(self, args): 11447db96d56Sopenharmony_ci self.heading('H3', args, 3) 11457db96d56Sopenharmony_ci self.popstack(4) 11467db96d56Sopenharmony_ci def do_unnumberedsubsubsec(self, args): 11477db96d56Sopenharmony_ci self.heading('H3', args, -1) 11487db96d56Sopenharmony_ci self.popstack(4) 11497db96d56Sopenharmony_ci def do_appendixsubsubsec(self, args): 11507db96d56Sopenharmony_ci self.heading('H3', args, -1) 11517db96d56Sopenharmony_ci self.popstack(4) 11527db96d56Sopenharmony_ci def do_subsubheading(self, args): 11537db96d56Sopenharmony_ci self.heading('H3', args, -1) 11547db96d56Sopenharmony_ci 11557db96d56Sopenharmony_ci def heading(self, type, args, level): 11567db96d56Sopenharmony_ci if level >= 0: 11577db96d56Sopenharmony_ci while len(self.numbering) <= level: 11587db96d56Sopenharmony_ci self.numbering.append(0) 11597db96d56Sopenharmony_ci del self.numbering[level+1:] 11607db96d56Sopenharmony_ci self.numbering[level] = self.numbering[level] + 1 11617db96d56Sopenharmony_ci x = '' 11627db96d56Sopenharmony_ci for i in self.numbering: 11637db96d56Sopenharmony_ci x = x + repr(i) + '.' 11647db96d56Sopenharmony_ci args = x + ' ' + args 11657db96d56Sopenharmony_ci self.contents.append((level, args, self.nodename)) 11667db96d56Sopenharmony_ci self.write('<', type, '>') 11677db96d56Sopenharmony_ci self.expand(args) 11687db96d56Sopenharmony_ci self.write('</', type, '>\n') 11697db96d56Sopenharmony_ci if self.debugging or self.print_headers: 11707db96d56Sopenharmony_ci print('---', args) 11717db96d56Sopenharmony_ci 11727db96d56Sopenharmony_ci def do_contents(self, args): 11737db96d56Sopenharmony_ci # pass 11747db96d56Sopenharmony_ci self.listcontents('Table of Contents', 999) 11757db96d56Sopenharmony_ci 11767db96d56Sopenharmony_ci def do_shortcontents(self, args): 11777db96d56Sopenharmony_ci pass 11787db96d56Sopenharmony_ci # self.listcontents('Short Contents', 0) 11797db96d56Sopenharmony_ci do_summarycontents = do_shortcontents 11807db96d56Sopenharmony_ci 11817db96d56Sopenharmony_ci def listcontents(self, title, maxlevel): 11827db96d56Sopenharmony_ci self.write('<H1>', title, '</H1>\n<UL COMPACT PLAIN>\n') 11837db96d56Sopenharmony_ci prevlevels = [0] 11847db96d56Sopenharmony_ci for level, title, node in self.contents: 11857db96d56Sopenharmony_ci if level > maxlevel: 11867db96d56Sopenharmony_ci continue 11877db96d56Sopenharmony_ci if level > prevlevels[-1]: 11887db96d56Sopenharmony_ci # can only advance one level at a time 11897db96d56Sopenharmony_ci self.write(' '*prevlevels[-1], '<UL PLAIN>\n') 11907db96d56Sopenharmony_ci prevlevels.append(level) 11917db96d56Sopenharmony_ci elif level < prevlevels[-1]: 11927db96d56Sopenharmony_ci # might drop back multiple levels 11937db96d56Sopenharmony_ci while level < prevlevels[-1]: 11947db96d56Sopenharmony_ci del prevlevels[-1] 11957db96d56Sopenharmony_ci self.write(' '*prevlevels[-1], 11967db96d56Sopenharmony_ci '</UL>\n') 11977db96d56Sopenharmony_ci self.write(' '*level, '<LI> <A HREF="', 11987db96d56Sopenharmony_ci makefile(node), '">') 11997db96d56Sopenharmony_ci self.expand(title) 12007db96d56Sopenharmony_ci self.write('</A>\n') 12017db96d56Sopenharmony_ci self.write('</UL>\n' * len(prevlevels)) 12027db96d56Sopenharmony_ci 12037db96d56Sopenharmony_ci # --- Page lay-out --- 12047db96d56Sopenharmony_ci 12057db96d56Sopenharmony_ci # These commands are only meaningful in printed text 12067db96d56Sopenharmony_ci 12077db96d56Sopenharmony_ci def do_page(self, args): pass 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_ci def do_need(self, args): pass 12107db96d56Sopenharmony_ci 12117db96d56Sopenharmony_ci def bgn_group(self, args): pass 12127db96d56Sopenharmony_ci def end_group(self): pass 12137db96d56Sopenharmony_ci 12147db96d56Sopenharmony_ci # --- Line lay-out --- 12157db96d56Sopenharmony_ci 12167db96d56Sopenharmony_ci def do_sp(self, args): 12177db96d56Sopenharmony_ci if self.nofill: 12187db96d56Sopenharmony_ci self.write('\n') 12197db96d56Sopenharmony_ci else: 12207db96d56Sopenharmony_ci self.write('<P>\n') 12217db96d56Sopenharmony_ci 12227db96d56Sopenharmony_ci def do_hline(self, args): 12237db96d56Sopenharmony_ci self.write('<HR>') 12247db96d56Sopenharmony_ci 12257db96d56Sopenharmony_ci # --- Function and variable definitions --- 12267db96d56Sopenharmony_ci 12277db96d56Sopenharmony_ci def bgn_deffn(self, args): 12287db96d56Sopenharmony_ci self.write('<DL>') 12297db96d56Sopenharmony_ci self.do_deffnx(args) 12307db96d56Sopenharmony_ci 12317db96d56Sopenharmony_ci def end_deffn(self): 12327db96d56Sopenharmony_ci self.write('</DL>\n') 12337db96d56Sopenharmony_ci 12347db96d56Sopenharmony_ci def do_deffnx(self, args): 12357db96d56Sopenharmony_ci self.write('<DT>') 12367db96d56Sopenharmony_ci words = splitwords(args, 2) 12377db96d56Sopenharmony_ci [category, name], rest = words[:2], words[2:] 12387db96d56Sopenharmony_ci self.expand('@b{%s}' % name) 12397db96d56Sopenharmony_ci for word in rest: self.expand(' ' + makevar(word)) 12407db96d56Sopenharmony_ci #self.expand(' -- ' + category) 12417db96d56Sopenharmony_ci self.write('\n<DD>') 12427db96d56Sopenharmony_ci self.index('fn', name) 12437db96d56Sopenharmony_ci 12447db96d56Sopenharmony_ci def bgn_defun(self, args): self.bgn_deffn('Function ' + args) 12457db96d56Sopenharmony_ci end_defun = end_deffn 12467db96d56Sopenharmony_ci def do_defunx(self, args): self.do_deffnx('Function ' + args) 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) 12497db96d56Sopenharmony_ci end_defmac = end_deffn 12507db96d56Sopenharmony_ci def do_defmacx(self, args): self.do_deffnx('Macro ' + args) 12517db96d56Sopenharmony_ci 12527db96d56Sopenharmony_ci def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) 12537db96d56Sopenharmony_ci end_defspec = end_deffn 12547db96d56Sopenharmony_ci def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) 12557db96d56Sopenharmony_ci 12567db96d56Sopenharmony_ci def bgn_defvr(self, args): 12577db96d56Sopenharmony_ci self.write('<DL>') 12587db96d56Sopenharmony_ci self.do_defvrx(args) 12597db96d56Sopenharmony_ci 12607db96d56Sopenharmony_ci end_defvr = end_deffn 12617db96d56Sopenharmony_ci 12627db96d56Sopenharmony_ci def do_defvrx(self, args): 12637db96d56Sopenharmony_ci self.write('<DT>') 12647db96d56Sopenharmony_ci words = splitwords(args, 2) 12657db96d56Sopenharmony_ci [category, name], rest = words[:2], words[2:] 12667db96d56Sopenharmony_ci self.expand('@code{%s}' % name) 12677db96d56Sopenharmony_ci # If there are too many arguments, show them 12687db96d56Sopenharmony_ci for word in rest: self.expand(' ' + word) 12697db96d56Sopenharmony_ci #self.expand(' -- ' + category) 12707db96d56Sopenharmony_ci self.write('\n<DD>') 12717db96d56Sopenharmony_ci self.index('vr', name) 12727db96d56Sopenharmony_ci 12737db96d56Sopenharmony_ci def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) 12747db96d56Sopenharmony_ci end_defvar = end_defvr 12757db96d56Sopenharmony_ci def do_defvarx(self, args): self.do_defvrx('Variable ' + args) 12767db96d56Sopenharmony_ci 12777db96d56Sopenharmony_ci def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) 12787db96d56Sopenharmony_ci end_defopt = end_defvr 12797db96d56Sopenharmony_ci def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) 12807db96d56Sopenharmony_ci 12817db96d56Sopenharmony_ci # --- Ditto for typed languages --- 12827db96d56Sopenharmony_ci 12837db96d56Sopenharmony_ci def bgn_deftypefn(self, args): 12847db96d56Sopenharmony_ci self.write('<DL>') 12857db96d56Sopenharmony_ci self.do_deftypefnx(args) 12867db96d56Sopenharmony_ci 12877db96d56Sopenharmony_ci end_deftypefn = end_deffn 12887db96d56Sopenharmony_ci 12897db96d56Sopenharmony_ci def do_deftypefnx(self, args): 12907db96d56Sopenharmony_ci self.write('<DT>') 12917db96d56Sopenharmony_ci words = splitwords(args, 3) 12927db96d56Sopenharmony_ci [category, datatype, name], rest = words[:3], words[3:] 12937db96d56Sopenharmony_ci self.expand('@code{%s} @b{%s}' % (datatype, name)) 12947db96d56Sopenharmony_ci for word in rest: self.expand(' ' + makevar(word)) 12957db96d56Sopenharmony_ci #self.expand(' -- ' + category) 12967db96d56Sopenharmony_ci self.write('\n<DD>') 12977db96d56Sopenharmony_ci self.index('fn', name) 12987db96d56Sopenharmony_ci 12997db96d56Sopenharmony_ci 13007db96d56Sopenharmony_ci def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) 13017db96d56Sopenharmony_ci end_deftypefun = end_deftypefn 13027db96d56Sopenharmony_ci def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) 13037db96d56Sopenharmony_ci 13047db96d56Sopenharmony_ci def bgn_deftypevr(self, args): 13057db96d56Sopenharmony_ci self.write('<DL>') 13067db96d56Sopenharmony_ci self.do_deftypevrx(args) 13077db96d56Sopenharmony_ci 13087db96d56Sopenharmony_ci end_deftypevr = end_deftypefn 13097db96d56Sopenharmony_ci 13107db96d56Sopenharmony_ci def do_deftypevrx(self, args): 13117db96d56Sopenharmony_ci self.write('<DT>') 13127db96d56Sopenharmony_ci words = splitwords(args, 3) 13137db96d56Sopenharmony_ci [category, datatype, name], rest = words[:3], words[3:] 13147db96d56Sopenharmony_ci self.expand('@code{%s} @b{%s}' % (datatype, name)) 13157db96d56Sopenharmony_ci # If there are too many arguments, show them 13167db96d56Sopenharmony_ci for word in rest: self.expand(' ' + word) 13177db96d56Sopenharmony_ci #self.expand(' -- ' + category) 13187db96d56Sopenharmony_ci self.write('\n<DD>') 13197db96d56Sopenharmony_ci self.index('fn', name) 13207db96d56Sopenharmony_ci 13217db96d56Sopenharmony_ci def bgn_deftypevar(self, args): 13227db96d56Sopenharmony_ci self.bgn_deftypevr('Variable ' + args) 13237db96d56Sopenharmony_ci end_deftypevar = end_deftypevr 13247db96d56Sopenharmony_ci def do_deftypevarx(self, args): 13257db96d56Sopenharmony_ci self.do_deftypevrx('Variable ' + args) 13267db96d56Sopenharmony_ci 13277db96d56Sopenharmony_ci # --- Ditto for object-oriented languages --- 13287db96d56Sopenharmony_ci 13297db96d56Sopenharmony_ci def bgn_defcv(self, args): 13307db96d56Sopenharmony_ci self.write('<DL>') 13317db96d56Sopenharmony_ci self.do_defcvx(args) 13327db96d56Sopenharmony_ci 13337db96d56Sopenharmony_ci end_defcv = end_deftypevr 13347db96d56Sopenharmony_ci 13357db96d56Sopenharmony_ci def do_defcvx(self, args): 13367db96d56Sopenharmony_ci self.write('<DT>') 13377db96d56Sopenharmony_ci words = splitwords(args, 3) 13387db96d56Sopenharmony_ci [category, classname, name], rest = words[:3], words[3:] 13397db96d56Sopenharmony_ci self.expand('@b{%s}' % name) 13407db96d56Sopenharmony_ci # If there are too many arguments, show them 13417db96d56Sopenharmony_ci for word in rest: self.expand(' ' + word) 13427db96d56Sopenharmony_ci #self.expand(' -- %s of @code{%s}' % (category, classname)) 13437db96d56Sopenharmony_ci self.write('\n<DD>') 13447db96d56Sopenharmony_ci self.index('vr', '%s @r{on %s}' % (name, classname)) 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ci def bgn_defivar(self, args): 13477db96d56Sopenharmony_ci self.bgn_defcv('{Instance Variable} ' + args) 13487db96d56Sopenharmony_ci end_defivar = end_defcv 13497db96d56Sopenharmony_ci def do_defivarx(self, args): 13507db96d56Sopenharmony_ci self.do_defcvx('{Instance Variable} ' + args) 13517db96d56Sopenharmony_ci 13527db96d56Sopenharmony_ci def bgn_defop(self, args): 13537db96d56Sopenharmony_ci self.write('<DL>') 13547db96d56Sopenharmony_ci self.do_defopx(args) 13557db96d56Sopenharmony_ci 13567db96d56Sopenharmony_ci end_defop = end_defcv 13577db96d56Sopenharmony_ci 13587db96d56Sopenharmony_ci def do_defopx(self, args): 13597db96d56Sopenharmony_ci self.write('<DT>') 13607db96d56Sopenharmony_ci words = splitwords(args, 3) 13617db96d56Sopenharmony_ci [category, classname, name], rest = words[:3], words[3:] 13627db96d56Sopenharmony_ci self.expand('@b{%s}' % name) 13637db96d56Sopenharmony_ci for word in rest: self.expand(' ' + makevar(word)) 13647db96d56Sopenharmony_ci #self.expand(' -- %s of @code{%s}' % (category, classname)) 13657db96d56Sopenharmony_ci self.write('\n<DD>') 13667db96d56Sopenharmony_ci self.index('fn', '%s @r{on %s}' % (name, classname)) 13677db96d56Sopenharmony_ci 13687db96d56Sopenharmony_ci def bgn_defmethod(self, args): 13697db96d56Sopenharmony_ci self.bgn_defop('Method ' + args) 13707db96d56Sopenharmony_ci end_defmethod = end_defop 13717db96d56Sopenharmony_ci def do_defmethodx(self, args): 13727db96d56Sopenharmony_ci self.do_defopx('Method ' + args) 13737db96d56Sopenharmony_ci 13747db96d56Sopenharmony_ci # --- Ditto for data types --- 13757db96d56Sopenharmony_ci 13767db96d56Sopenharmony_ci def bgn_deftp(self, args): 13777db96d56Sopenharmony_ci self.write('<DL>') 13787db96d56Sopenharmony_ci self.do_deftpx(args) 13797db96d56Sopenharmony_ci 13807db96d56Sopenharmony_ci end_deftp = end_defcv 13817db96d56Sopenharmony_ci 13827db96d56Sopenharmony_ci def do_deftpx(self, args): 13837db96d56Sopenharmony_ci self.write('<DT>') 13847db96d56Sopenharmony_ci words = splitwords(args, 2) 13857db96d56Sopenharmony_ci [category, name], rest = words[:2], words[2:] 13867db96d56Sopenharmony_ci self.expand('@b{%s}' % name) 13877db96d56Sopenharmony_ci for word in rest: self.expand(' ' + word) 13887db96d56Sopenharmony_ci #self.expand(' -- ' + category) 13897db96d56Sopenharmony_ci self.write('\n<DD>') 13907db96d56Sopenharmony_ci self.index('tp', name) 13917db96d56Sopenharmony_ci 13927db96d56Sopenharmony_ci # --- Making Lists and Tables 13937db96d56Sopenharmony_ci 13947db96d56Sopenharmony_ci def bgn_enumerate(self, args): 13957db96d56Sopenharmony_ci if not args: 13967db96d56Sopenharmony_ci self.write('<OL>\n') 13977db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = '</OL>\n' 13987db96d56Sopenharmony_ci else: 13997db96d56Sopenharmony_ci self.itemnumber = args 14007db96d56Sopenharmony_ci self.write('<UL>\n') 14017db96d56Sopenharmony_ci self.stackinfo[len(self.stack)] = '</UL>\n' 14027db96d56Sopenharmony_ci def end_enumerate(self): 14037db96d56Sopenharmony_ci self.itemnumber = None 14047db96d56Sopenharmony_ci self.write(self.stackinfo[len(self.stack) + 1]) 14057db96d56Sopenharmony_ci del self.stackinfo[len(self.stack) + 1] 14067db96d56Sopenharmony_ci 14077db96d56Sopenharmony_ci def bgn_itemize(self, args): 14087db96d56Sopenharmony_ci self.itemarg = args 14097db96d56Sopenharmony_ci self.write('<UL>\n') 14107db96d56Sopenharmony_ci def end_itemize(self): 14117db96d56Sopenharmony_ci self.itemarg = None 14127db96d56Sopenharmony_ci self.write('</UL>\n') 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ci def bgn_table(self, args): 14157db96d56Sopenharmony_ci self.itemarg = args 14167db96d56Sopenharmony_ci self.write('<DL>\n') 14177db96d56Sopenharmony_ci def end_table(self): 14187db96d56Sopenharmony_ci self.itemarg = None 14197db96d56Sopenharmony_ci self.write('</DL>\n') 14207db96d56Sopenharmony_ci 14217db96d56Sopenharmony_ci def bgn_ftable(self, args): 14227db96d56Sopenharmony_ci self.itemindex = 'fn' 14237db96d56Sopenharmony_ci self.bgn_table(args) 14247db96d56Sopenharmony_ci def end_ftable(self): 14257db96d56Sopenharmony_ci self.itemindex = None 14267db96d56Sopenharmony_ci self.end_table() 14277db96d56Sopenharmony_ci 14287db96d56Sopenharmony_ci def bgn_vtable(self, args): 14297db96d56Sopenharmony_ci self.itemindex = 'vr' 14307db96d56Sopenharmony_ci self.bgn_table(args) 14317db96d56Sopenharmony_ci def end_vtable(self): 14327db96d56Sopenharmony_ci self.itemindex = None 14337db96d56Sopenharmony_ci self.end_table() 14347db96d56Sopenharmony_ci 14357db96d56Sopenharmony_ci def do_item(self, args): 14367db96d56Sopenharmony_ci if self.itemindex: self.index(self.itemindex, args) 14377db96d56Sopenharmony_ci if self.itemarg: 14387db96d56Sopenharmony_ci if self.itemarg[0] == '@' and self.itemarg[1] and \ 14397db96d56Sopenharmony_ci self.itemarg[1] in string.ascii_letters: 14407db96d56Sopenharmony_ci args = self.itemarg + '{' + args + '}' 14417db96d56Sopenharmony_ci else: 14427db96d56Sopenharmony_ci # some other character, e.g. '-' 14437db96d56Sopenharmony_ci args = self.itemarg + ' ' + args 14447db96d56Sopenharmony_ci if self.itemnumber is not None: 14457db96d56Sopenharmony_ci args = self.itemnumber + '. ' + args 14467db96d56Sopenharmony_ci self.itemnumber = increment(self.itemnumber) 14477db96d56Sopenharmony_ci if self.stack and self.stack[-1] == 'table': 14487db96d56Sopenharmony_ci self.write('<DT>') 14497db96d56Sopenharmony_ci self.expand(args) 14507db96d56Sopenharmony_ci self.write('\n<DD>') 14517db96d56Sopenharmony_ci elif self.stack and self.stack[-1] == 'multitable': 14527db96d56Sopenharmony_ci self.write('<TR><TD>') 14537db96d56Sopenharmony_ci self.expand(args) 14547db96d56Sopenharmony_ci self.write('</TD>\n</TR>\n') 14557db96d56Sopenharmony_ci else: 14567db96d56Sopenharmony_ci self.write('<LI>') 14577db96d56Sopenharmony_ci self.expand(args) 14587db96d56Sopenharmony_ci self.write(' ') 14597db96d56Sopenharmony_ci do_itemx = do_item # XXX Should suppress leading blank line 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ci # rpyron 2002-05-07 multitable support 14627db96d56Sopenharmony_ci def bgn_multitable(self, args): 14637db96d56Sopenharmony_ci self.itemarg = None # should be handled by columnfractions 14647db96d56Sopenharmony_ci self.write('<TABLE BORDER="">\n') 14657db96d56Sopenharmony_ci def end_multitable(self): 14667db96d56Sopenharmony_ci self.itemarg = None 14677db96d56Sopenharmony_ci self.write('</TABLE>\n<BR>\n') 14687db96d56Sopenharmony_ci def handle_columnfractions(self): 14697db96d56Sopenharmony_ci # It would be better to handle this, but for now it's in the way... 14707db96d56Sopenharmony_ci self.itemarg = None 14717db96d56Sopenharmony_ci def handle_tab(self): 14727db96d56Sopenharmony_ci self.write('</TD>\n <TD>') 14737db96d56Sopenharmony_ci 14747db96d56Sopenharmony_ci # --- Enumerations, displays, quotations --- 14757db96d56Sopenharmony_ci # XXX Most of these should increase the indentation somehow 14767db96d56Sopenharmony_ci 14777db96d56Sopenharmony_ci def bgn_quotation(self, args): self.write('<BLOCKQUOTE>') 14787db96d56Sopenharmony_ci def end_quotation(self): self.write('</BLOCKQUOTE>\n') 14797db96d56Sopenharmony_ci 14807db96d56Sopenharmony_ci def bgn_example(self, args): 14817db96d56Sopenharmony_ci self.nofill = self.nofill + 1 14827db96d56Sopenharmony_ci self.write('<PRE>') 14837db96d56Sopenharmony_ci def end_example(self): 14847db96d56Sopenharmony_ci self.write('</PRE>\n') 14857db96d56Sopenharmony_ci self.nofill = self.nofill - 1 14867db96d56Sopenharmony_ci 14877db96d56Sopenharmony_ci bgn_lisp = bgn_example # Synonym when contents are executable lisp code 14887db96d56Sopenharmony_ci end_lisp = end_example 14897db96d56Sopenharmony_ci 14907db96d56Sopenharmony_ci bgn_smallexample = bgn_example # XXX Should use smaller font 14917db96d56Sopenharmony_ci end_smallexample = end_example 14927db96d56Sopenharmony_ci 14937db96d56Sopenharmony_ci bgn_smalllisp = bgn_lisp # Ditto 14947db96d56Sopenharmony_ci end_smalllisp = end_lisp 14957db96d56Sopenharmony_ci 14967db96d56Sopenharmony_ci bgn_display = bgn_example 14977db96d56Sopenharmony_ci end_display = end_example 14987db96d56Sopenharmony_ci 14997db96d56Sopenharmony_ci bgn_format = bgn_display 15007db96d56Sopenharmony_ci end_format = end_display 15017db96d56Sopenharmony_ci 15027db96d56Sopenharmony_ci def do_exdent(self, args): self.expand(args + '\n') 15037db96d56Sopenharmony_ci # XXX Should really mess with indentation 15047db96d56Sopenharmony_ci 15057db96d56Sopenharmony_ci def bgn_flushleft(self, args): 15067db96d56Sopenharmony_ci self.nofill = self.nofill + 1 15077db96d56Sopenharmony_ci self.write('<PRE>\n') 15087db96d56Sopenharmony_ci def end_flushleft(self): 15097db96d56Sopenharmony_ci self.write('</PRE>\n') 15107db96d56Sopenharmony_ci self.nofill = self.nofill - 1 15117db96d56Sopenharmony_ci 15127db96d56Sopenharmony_ci def bgn_flushright(self, args): 15137db96d56Sopenharmony_ci self.nofill = self.nofill + 1 15147db96d56Sopenharmony_ci self.write('<ADDRESS COMPACT>\n') 15157db96d56Sopenharmony_ci def end_flushright(self): 15167db96d56Sopenharmony_ci self.write('</ADDRESS>\n') 15177db96d56Sopenharmony_ci self.nofill = self.nofill - 1 15187db96d56Sopenharmony_ci 15197db96d56Sopenharmony_ci def bgn_menu(self, args): 15207db96d56Sopenharmony_ci self.write('<DIR>\n') 15217db96d56Sopenharmony_ci self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n') 15227db96d56Sopenharmony_ci self.htmlhelp.beginmenu() 15237db96d56Sopenharmony_ci def end_menu(self): 15247db96d56Sopenharmony_ci self.write('</DIR>\n') 15257db96d56Sopenharmony_ci self.htmlhelp.endmenu() 15267db96d56Sopenharmony_ci 15277db96d56Sopenharmony_ci def bgn_cartouche(self, args): pass 15287db96d56Sopenharmony_ci def end_cartouche(self): pass 15297db96d56Sopenharmony_ci 15307db96d56Sopenharmony_ci # --- Indices --- 15317db96d56Sopenharmony_ci 15327db96d56Sopenharmony_ci def resetindex(self): 15337db96d56Sopenharmony_ci self.noncodeindices = ['cp'] 15347db96d56Sopenharmony_ci self.indextitle = {} 15357db96d56Sopenharmony_ci self.indextitle['cp'] = 'Concept' 15367db96d56Sopenharmony_ci self.indextitle['fn'] = 'Function' 15377db96d56Sopenharmony_ci self.indextitle['ky'] = 'Keyword' 15387db96d56Sopenharmony_ci self.indextitle['pg'] = 'Program' 15397db96d56Sopenharmony_ci self.indextitle['tp'] = 'Type' 15407db96d56Sopenharmony_ci self.indextitle['vr'] = 'Variable' 15417db96d56Sopenharmony_ci # 15427db96d56Sopenharmony_ci self.whichindex = {} 15437db96d56Sopenharmony_ci for name in self.indextitle: 15447db96d56Sopenharmony_ci self.whichindex[name] = [] 15457db96d56Sopenharmony_ci 15467db96d56Sopenharmony_ci def user_index(self, name, args): 15477db96d56Sopenharmony_ci if name in self.whichindex: 15487db96d56Sopenharmony_ci self.index(name, args) 15497db96d56Sopenharmony_ci else: 15507db96d56Sopenharmony_ci print('*** No index named', repr(name)) 15517db96d56Sopenharmony_ci 15527db96d56Sopenharmony_ci def do_cindex(self, args): self.index('cp', args) 15537db96d56Sopenharmony_ci def do_findex(self, args): self.index('fn', args) 15547db96d56Sopenharmony_ci def do_kindex(self, args): self.index('ky', args) 15557db96d56Sopenharmony_ci def do_pindex(self, args): self.index('pg', args) 15567db96d56Sopenharmony_ci def do_tindex(self, args): self.index('tp', args) 15577db96d56Sopenharmony_ci def do_vindex(self, args): self.index('vr', args) 15587db96d56Sopenharmony_ci 15597db96d56Sopenharmony_ci def index(self, name, args): 15607db96d56Sopenharmony_ci self.whichindex[name].append((args, self.nodename)) 15617db96d56Sopenharmony_ci self.htmlhelp.index(args, self.nodename) 15627db96d56Sopenharmony_ci 15637db96d56Sopenharmony_ci def do_synindex(self, args): 15647db96d56Sopenharmony_ci words = args.split() 15657db96d56Sopenharmony_ci if len(words) != 2: 15667db96d56Sopenharmony_ci print('*** bad @synindex', args) 15677db96d56Sopenharmony_ci return 15687db96d56Sopenharmony_ci [old, new] = words 15697db96d56Sopenharmony_ci if old not in self.whichindex or \ 15707db96d56Sopenharmony_ci new not in self.whichindex: 15717db96d56Sopenharmony_ci print('*** bad key(s) in @synindex', args) 15727db96d56Sopenharmony_ci return 15737db96d56Sopenharmony_ci if old != new and \ 15747db96d56Sopenharmony_ci self.whichindex[old] is not self.whichindex[new]: 15757db96d56Sopenharmony_ci inew = self.whichindex[new] 15767db96d56Sopenharmony_ci inew[len(inew):] = self.whichindex[old] 15777db96d56Sopenharmony_ci self.whichindex[old] = inew 15787db96d56Sopenharmony_ci do_syncodeindex = do_synindex # XXX Should use code font 15797db96d56Sopenharmony_ci 15807db96d56Sopenharmony_ci def do_printindex(self, args): 15817db96d56Sopenharmony_ci words = args.split() 15827db96d56Sopenharmony_ci for name in words: 15837db96d56Sopenharmony_ci if name in self.whichindex: 15847db96d56Sopenharmony_ci self.prindex(name) 15857db96d56Sopenharmony_ci else: 15867db96d56Sopenharmony_ci print('*** No index named', repr(name)) 15877db96d56Sopenharmony_ci 15887db96d56Sopenharmony_ci def prindex(self, name): 15897db96d56Sopenharmony_ci iscodeindex = (name not in self.noncodeindices) 15907db96d56Sopenharmony_ci index = self.whichindex[name] 15917db96d56Sopenharmony_ci if not index: return 15927db96d56Sopenharmony_ci if self.debugging: 15937db96d56Sopenharmony_ci print('!'*self.debugging, '--- Generating', \ 15947db96d56Sopenharmony_ci self.indextitle[name], 'index') 15957db96d56Sopenharmony_ci # The node already provides a title 15967db96d56Sopenharmony_ci index1 = [] 15977db96d56Sopenharmony_ci junkprog = re.compile('^(@[a-z]+)?{') 15987db96d56Sopenharmony_ci for key, node in index: 15997db96d56Sopenharmony_ci sortkey = key.lower() 16007db96d56Sopenharmony_ci # Remove leading `@cmd{' from sort key 16017db96d56Sopenharmony_ci # -- don't bother about the matching `}' 16027db96d56Sopenharmony_ci oldsortkey = sortkey 16037db96d56Sopenharmony_ci while 1: 16047db96d56Sopenharmony_ci mo = junkprog.match(sortkey) 16057db96d56Sopenharmony_ci if not mo: 16067db96d56Sopenharmony_ci break 16077db96d56Sopenharmony_ci i = mo.end() 16087db96d56Sopenharmony_ci sortkey = sortkey[i:] 16097db96d56Sopenharmony_ci index1.append((sortkey, key, node)) 16107db96d56Sopenharmony_ci del index[:] 16117db96d56Sopenharmony_ci index1.sort() 16127db96d56Sopenharmony_ci self.write('<DL COMPACT>\n') 16137db96d56Sopenharmony_ci prevkey = prevnode = None 16147db96d56Sopenharmony_ci for sortkey, key, node in index1: 16157db96d56Sopenharmony_ci if (key, node) == (prevkey, prevnode): 16167db96d56Sopenharmony_ci continue 16177db96d56Sopenharmony_ci if self.debugging > 1: print('!'*self.debugging, key, ':', node) 16187db96d56Sopenharmony_ci self.write('<DT>') 16197db96d56Sopenharmony_ci if iscodeindex: key = '@code{' + key + '}' 16207db96d56Sopenharmony_ci if key != prevkey: 16217db96d56Sopenharmony_ci self.expand(key) 16227db96d56Sopenharmony_ci self.write('\n<DD><A HREF="%s">%s</A>\n' % (makefile(node), node)) 16237db96d56Sopenharmony_ci prevkey, prevnode = key, node 16247db96d56Sopenharmony_ci self.write('</DL>\n') 16257db96d56Sopenharmony_ci 16267db96d56Sopenharmony_ci # --- Final error reports --- 16277db96d56Sopenharmony_ci 16287db96d56Sopenharmony_ci def report(self): 16297db96d56Sopenharmony_ci if self.unknown: 16307db96d56Sopenharmony_ci print('--- Unrecognized commands ---') 16317db96d56Sopenharmony_ci cmds = sorted(self.unknown.keys()) 16327db96d56Sopenharmony_ci for cmd in cmds: 16337db96d56Sopenharmony_ci print(cmd.ljust(20), self.unknown[cmd]) 16347db96d56Sopenharmony_ci 16357db96d56Sopenharmony_ci 16367db96d56Sopenharmony_ciclass TexinfoParserHTML3(TexinfoParser): 16377db96d56Sopenharmony_ci 16387db96d56Sopenharmony_ci COPYRIGHT_SYMBOL = "©" 16397db96d56Sopenharmony_ci FN_ID_PATTERN = "[%(id)s]" 16407db96d56Sopenharmony_ci FN_SOURCE_PATTERN = '<A ID=footnoteref%(id)s ' \ 16417db96d56Sopenharmony_ci 'HREF="#footnotetext%(id)s">' + FN_ID_PATTERN + '</A>' 16427db96d56Sopenharmony_ci FN_TARGET_PATTERN = '<FN ID=footnotetext%(id)s>\n' \ 16437db96d56Sopenharmony_ci '<P><A HREF="#footnoteref%(id)s">' + FN_ID_PATTERN \ 16447db96d56Sopenharmony_ci + '</A>\n%(text)s</P></FN>\n' 16457db96d56Sopenharmony_ci FN_HEADER = '<DIV CLASS=footnotes>\n <HR NOSHADE WIDTH=200>\n' \ 16467db96d56Sopenharmony_ci ' <STRONG><EM>Footnotes</EM></STRONG>\n <P>\n' 16477db96d56Sopenharmony_ci 16487db96d56Sopenharmony_ci Node = HTML3Node 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_ci def bgn_quotation(self, args): self.write('<BQ>') 16517db96d56Sopenharmony_ci def end_quotation(self): self.write('</BQ>\n') 16527db96d56Sopenharmony_ci 16537db96d56Sopenharmony_ci def bgn_example(self, args): 16547db96d56Sopenharmony_ci # this use of <CODE> would not be legal in HTML 2.0, 16557db96d56Sopenharmony_ci # but is in more recent DTDs. 16567db96d56Sopenharmony_ci self.nofill = self.nofill + 1 16577db96d56Sopenharmony_ci self.write('<PRE CLASS=example><CODE>') 16587db96d56Sopenharmony_ci def end_example(self): 16597db96d56Sopenharmony_ci self.write("</CODE></PRE>\n") 16607db96d56Sopenharmony_ci self.nofill = self.nofill - 1 16617db96d56Sopenharmony_ci 16627db96d56Sopenharmony_ci def bgn_flushleft(self, args): 16637db96d56Sopenharmony_ci self.nofill = self.nofill + 1 16647db96d56Sopenharmony_ci self.write('<PRE CLASS=flushleft>\n') 16657db96d56Sopenharmony_ci 16667db96d56Sopenharmony_ci def bgn_flushright(self, args): 16677db96d56Sopenharmony_ci self.nofill = self.nofill + 1 16687db96d56Sopenharmony_ci self.write('<DIV ALIGN=right CLASS=flushright><ADDRESS COMPACT>\n') 16697db96d56Sopenharmony_ci def end_flushright(self): 16707db96d56Sopenharmony_ci self.write('</ADDRESS></DIV>\n') 16717db96d56Sopenharmony_ci self.nofill = self.nofill - 1 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_ci def bgn_menu(self, args): 16747db96d56Sopenharmony_ci self.write('<UL PLAIN CLASS=menu>\n') 16757db96d56Sopenharmony_ci self.write(' <LH>Menu</LH>\n') 16767db96d56Sopenharmony_ci def end_menu(self): 16777db96d56Sopenharmony_ci self.write('</UL>\n') 16787db96d56Sopenharmony_ci 16797db96d56Sopenharmony_ci 16807db96d56Sopenharmony_ci# rpyron 2002-05-07 16817db96d56Sopenharmony_ciclass HTMLHelp: 16827db96d56Sopenharmony_ci """ 16837db96d56Sopenharmony_ci This class encapsulates support for HTML Help. Node names, 16847db96d56Sopenharmony_ci file names, menu items, index items, and image file names are 16857db96d56Sopenharmony_ci accumulated until a call to finalize(). At that time, three 16867db96d56Sopenharmony_ci output files are created in the current directory: 16877db96d56Sopenharmony_ci 16887db96d56Sopenharmony_ci `helpbase`.hhp is a HTML Help Workshop project file. 16897db96d56Sopenharmony_ci It contains various information, some of 16907db96d56Sopenharmony_ci which I do not understand; I just copied 16917db96d56Sopenharmony_ci the default project info from a fresh 16927db96d56Sopenharmony_ci installation. 16937db96d56Sopenharmony_ci `helpbase`.hhc is the Contents file for the project. 16947db96d56Sopenharmony_ci `helpbase`.hhk is the Index file for the project. 16957db96d56Sopenharmony_ci 16967db96d56Sopenharmony_ci When these files are used as input to HTML Help Workshop, 16977db96d56Sopenharmony_ci the resulting file will be named: 16987db96d56Sopenharmony_ci 16997db96d56Sopenharmony_ci `helpbase`.chm 17007db96d56Sopenharmony_ci 17017db96d56Sopenharmony_ci If none of the defaults in `helpbase`.hhp are changed, 17027db96d56Sopenharmony_ci the .CHM file will have Contents, Index, Search, and 17037db96d56Sopenharmony_ci Favorites tabs. 17047db96d56Sopenharmony_ci """ 17057db96d56Sopenharmony_ci 17067db96d56Sopenharmony_ci codeprog = re.compile('@code{(.*?)}') 17077db96d56Sopenharmony_ci 17087db96d56Sopenharmony_ci def __init__(self,helpbase,dirname): 17097db96d56Sopenharmony_ci self.helpbase = helpbase 17107db96d56Sopenharmony_ci self.dirname = dirname 17117db96d56Sopenharmony_ci self.projectfile = None 17127db96d56Sopenharmony_ci self.contentfile = None 17137db96d56Sopenharmony_ci self.indexfile = None 17147db96d56Sopenharmony_ci self.nodelist = [] 17157db96d56Sopenharmony_ci self.nodenames = {} # nodename : index 17167db96d56Sopenharmony_ci self.nodeindex = {} 17177db96d56Sopenharmony_ci self.filenames = {} # filename : filename 17187db96d56Sopenharmony_ci self.indexlist = [] # (args,nodename) == (key,location) 17197db96d56Sopenharmony_ci self.current = '' 17207db96d56Sopenharmony_ci self.menudict = {} 17217db96d56Sopenharmony_ci self.dumped = {} 17227db96d56Sopenharmony_ci 17237db96d56Sopenharmony_ci 17247db96d56Sopenharmony_ci def addnode(self,name,next,prev,up,filename): 17257db96d56Sopenharmony_ci node = (name,next,prev,up,filename) 17267db96d56Sopenharmony_ci # add this file to dict 17277db96d56Sopenharmony_ci # retrieve list with self.filenames.values() 17287db96d56Sopenharmony_ci self.filenames[filename] = filename 17297db96d56Sopenharmony_ci # add this node to nodelist 17307db96d56Sopenharmony_ci self.nodeindex[name] = len(self.nodelist) 17317db96d56Sopenharmony_ci self.nodelist.append(node) 17327db96d56Sopenharmony_ci # set 'current' for menu items 17337db96d56Sopenharmony_ci self.current = name 17347db96d56Sopenharmony_ci self.menudict[self.current] = [] 17357db96d56Sopenharmony_ci 17367db96d56Sopenharmony_ci def menuitem(self,nodename): 17377db96d56Sopenharmony_ci menu = self.menudict[self.current] 17387db96d56Sopenharmony_ci menu.append(nodename) 17397db96d56Sopenharmony_ci 17407db96d56Sopenharmony_ci 17417db96d56Sopenharmony_ci def addimage(self,imagename): 17427db96d56Sopenharmony_ci self.filenames[imagename] = imagename 17437db96d56Sopenharmony_ci 17447db96d56Sopenharmony_ci def index(self, args, nodename): 17457db96d56Sopenharmony_ci self.indexlist.append((args,nodename)) 17467db96d56Sopenharmony_ci 17477db96d56Sopenharmony_ci def beginmenu(self): 17487db96d56Sopenharmony_ci pass 17497db96d56Sopenharmony_ci 17507db96d56Sopenharmony_ci def endmenu(self): 17517db96d56Sopenharmony_ci pass 17527db96d56Sopenharmony_ci 17537db96d56Sopenharmony_ci def finalize(self): 17547db96d56Sopenharmony_ci if not self.helpbase: 17557db96d56Sopenharmony_ci return 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ci # generate interesting filenames 17587db96d56Sopenharmony_ci resultfile = self.helpbase + '.chm' 17597db96d56Sopenharmony_ci projectfile = self.helpbase + '.hhp' 17607db96d56Sopenharmony_ci contentfile = self.helpbase + '.hhc' 17617db96d56Sopenharmony_ci indexfile = self.helpbase + '.hhk' 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_ci # generate a reasonable title 17647db96d56Sopenharmony_ci title = self.helpbase 17657db96d56Sopenharmony_ci 17667db96d56Sopenharmony_ci # get the default topic file 17677db96d56Sopenharmony_ci (topname,topnext,topprev,topup,topfile) = self.nodelist[0] 17687db96d56Sopenharmony_ci defaulttopic = topfile 17697db96d56Sopenharmony_ci 17707db96d56Sopenharmony_ci # PROJECT FILE 17717db96d56Sopenharmony_ci try: 17727db96d56Sopenharmony_ci with open(projectfile, 'w') as fp: 17737db96d56Sopenharmony_ci print('[OPTIONS]', file=fp) 17747db96d56Sopenharmony_ci print('Auto Index=Yes', file=fp) 17757db96d56Sopenharmony_ci print('Binary TOC=No', file=fp) 17767db96d56Sopenharmony_ci print('Binary Index=Yes', file=fp) 17777db96d56Sopenharmony_ci print('Compatibility=1.1', file=fp) 17787db96d56Sopenharmony_ci print('Compiled file=' + resultfile + '', file=fp) 17797db96d56Sopenharmony_ci print('Contents file=' + contentfile + '', file=fp) 17807db96d56Sopenharmony_ci print('Default topic=' + defaulttopic + '', file=fp) 17817db96d56Sopenharmony_ci print('Error log file=ErrorLog.log', file=fp) 17827db96d56Sopenharmony_ci print('Index file=' + indexfile + '', file=fp) 17837db96d56Sopenharmony_ci print('Title=' + title + '', file=fp) 17847db96d56Sopenharmony_ci print('Display compile progress=Yes', file=fp) 17857db96d56Sopenharmony_ci print('Full-text search=Yes', file=fp) 17867db96d56Sopenharmony_ci print('Default window=main', file=fp) 17877db96d56Sopenharmony_ci print('', file=fp) 17887db96d56Sopenharmony_ci print('[WINDOWS]', file=fp) 17897db96d56Sopenharmony_ci print('main=,"' + contentfile + '","' + indexfile 17907db96d56Sopenharmony_ci + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' 17917db96d56Sopenharmony_ci '0xB0000,,,,,,0', file=fp) 17927db96d56Sopenharmony_ci print('', file=fp) 17937db96d56Sopenharmony_ci print('[FILES]', file=fp) 17947db96d56Sopenharmony_ci print('', file=fp) 17957db96d56Sopenharmony_ci self.dumpfiles(fp) 17967db96d56Sopenharmony_ci except IOError as msg: 17977db96d56Sopenharmony_ci print(projectfile, ':', msg) 17987db96d56Sopenharmony_ci sys.exit(1) 17997db96d56Sopenharmony_ci 18007db96d56Sopenharmony_ci # CONTENT FILE 18017db96d56Sopenharmony_ci try: 18027db96d56Sopenharmony_ci with open(contentfile, 'w') as fp: 18037db96d56Sopenharmony_ci print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp) 18047db96d56Sopenharmony_ci print('<!-- This file defines the table of contents -->', file=fp) 18057db96d56Sopenharmony_ci print('<HTML>', file=fp) 18067db96d56Sopenharmony_ci print('<HEAD>', file=fp) 18077db96d56Sopenharmony_ci print('<meta name="GENERATOR" ' 18087db96d56Sopenharmony_ci 'content="Microsoft® HTML Help Workshop 4.1">', file=fp) 18097db96d56Sopenharmony_ci print('<!-- Sitemap 1.0 -->', file=fp) 18107db96d56Sopenharmony_ci print('</HEAD>', file=fp) 18117db96d56Sopenharmony_ci print('<BODY>', file=fp) 18127db96d56Sopenharmony_ci print(' <OBJECT type="text/site properties">', file=fp) 18137db96d56Sopenharmony_ci print(' <param name="Window Styles" value="0x800025">', file=fp) 18147db96d56Sopenharmony_ci print(' <param name="comment" value="title:">', file=fp) 18157db96d56Sopenharmony_ci print(' <param name="comment" value="base:">', file=fp) 18167db96d56Sopenharmony_ci print(' </OBJECT>', file=fp) 18177db96d56Sopenharmony_ci self.dumpnodes(fp) 18187db96d56Sopenharmony_ci print('</BODY>', file=fp) 18197db96d56Sopenharmony_ci print('</HTML>', file=fp) 18207db96d56Sopenharmony_ci except IOError as msg: 18217db96d56Sopenharmony_ci print(contentfile, ':', msg) 18227db96d56Sopenharmony_ci sys.exit(1) 18237db96d56Sopenharmony_ci 18247db96d56Sopenharmony_ci # INDEX FILE 18257db96d56Sopenharmony_ci try: 18267db96d56Sopenharmony_ci with open(indexfile, 'w') as fp: 18277db96d56Sopenharmony_ci print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp) 18287db96d56Sopenharmony_ci print('<!-- This file defines the index -->', file=fp) 18297db96d56Sopenharmony_ci print('<HTML>', file=fp) 18307db96d56Sopenharmony_ci print('<HEAD>', file=fp) 18317db96d56Sopenharmony_ci print('<meta name="GENERATOR" ' 18327db96d56Sopenharmony_ci 'content="Microsoft® HTML Help Workshop 4.1">', file=fp) 18337db96d56Sopenharmony_ci print('<!-- Sitemap 1.0 -->', file=fp) 18347db96d56Sopenharmony_ci print('</HEAD>', file=fp) 18357db96d56Sopenharmony_ci print('<BODY>', file=fp) 18367db96d56Sopenharmony_ci print('<OBJECT type="text/site properties">', file=fp) 18377db96d56Sopenharmony_ci print('</OBJECT>', file=fp) 18387db96d56Sopenharmony_ci self.dumpindex(fp) 18397db96d56Sopenharmony_ci print('</BODY>', file=fp) 18407db96d56Sopenharmony_ci print('</HTML>', file=fp) 18417db96d56Sopenharmony_ci except IOError as msg: 18427db96d56Sopenharmony_ci print(indexfile , ':', msg) 18437db96d56Sopenharmony_ci sys.exit(1) 18447db96d56Sopenharmony_ci 18457db96d56Sopenharmony_ci def dumpfiles(self, outfile=sys.stdout): 18467db96d56Sopenharmony_ci filelist = sorted(self.filenames.values()) 18477db96d56Sopenharmony_ci for filename in filelist: 18487db96d56Sopenharmony_ci print(filename, file=outfile) 18497db96d56Sopenharmony_ci 18507db96d56Sopenharmony_ci def dumpnodes(self, outfile=sys.stdout): 18517db96d56Sopenharmony_ci self.dumped = {} 18527db96d56Sopenharmony_ci if self.nodelist: 18537db96d56Sopenharmony_ci nodename, dummy, dummy, dummy, dummy = self.nodelist[0] 18547db96d56Sopenharmony_ci self.topnode = nodename 18557db96d56Sopenharmony_ci 18567db96d56Sopenharmony_ci print('<UL>', file=outfile) 18577db96d56Sopenharmony_ci for node in self.nodelist: 18587db96d56Sopenharmony_ci self.dumpnode(node,0,outfile) 18597db96d56Sopenharmony_ci print('</UL>', file=outfile) 18607db96d56Sopenharmony_ci 18617db96d56Sopenharmony_ci def dumpnode(self, node, indent=0, outfile=sys.stdout): 18627db96d56Sopenharmony_ci if node: 18637db96d56Sopenharmony_ci # Retrieve info for this node 18647db96d56Sopenharmony_ci (nodename,next,prev,up,filename) = node 18657db96d56Sopenharmony_ci self.current = nodename 18667db96d56Sopenharmony_ci 18677db96d56Sopenharmony_ci # Have we been dumped already? 18687db96d56Sopenharmony_ci if nodename in self.dumped: 18697db96d56Sopenharmony_ci return 18707db96d56Sopenharmony_ci self.dumped[nodename] = 1 18717db96d56Sopenharmony_ci 18727db96d56Sopenharmony_ci # Print info for this node 18737db96d56Sopenharmony_ci print(' '*indent, end=' ', file=outfile) 18747db96d56Sopenharmony_ci print('<LI><OBJECT type="text/sitemap">', end=' ', file=outfile) 18757db96d56Sopenharmony_ci print('<param name="Name" value="' + nodename +'">', end=' ', file=outfile) 18767db96d56Sopenharmony_ci print('<param name="Local" value="'+ filename +'">', end=' ', file=outfile) 18777db96d56Sopenharmony_ci print('</OBJECT>', file=outfile) 18787db96d56Sopenharmony_ci 18797db96d56Sopenharmony_ci # Does this node have menu items? 18807db96d56Sopenharmony_ci try: 18817db96d56Sopenharmony_ci menu = self.menudict[nodename] 18827db96d56Sopenharmony_ci self.dumpmenu(menu,indent+2,outfile) 18837db96d56Sopenharmony_ci except KeyError: 18847db96d56Sopenharmony_ci pass 18857db96d56Sopenharmony_ci 18867db96d56Sopenharmony_ci def dumpmenu(self, menu, indent=0, outfile=sys.stdout): 18877db96d56Sopenharmony_ci if menu: 18887db96d56Sopenharmony_ci currentnode = self.current 18897db96d56Sopenharmony_ci if currentnode != self.topnode: # XXX this is a hack 18907db96d56Sopenharmony_ci print(' '*indent + '<UL>', file=outfile) 18917db96d56Sopenharmony_ci indent += 2 18927db96d56Sopenharmony_ci for item in menu: 18937db96d56Sopenharmony_ci menunode = self.getnode(item) 18947db96d56Sopenharmony_ci self.dumpnode(menunode,indent,outfile) 18957db96d56Sopenharmony_ci if currentnode != self.topnode: # XXX this is a hack 18967db96d56Sopenharmony_ci print(' '*indent + '</UL>', file=outfile) 18977db96d56Sopenharmony_ci indent -= 2 18987db96d56Sopenharmony_ci 18997db96d56Sopenharmony_ci def getnode(self, nodename): 19007db96d56Sopenharmony_ci try: 19017db96d56Sopenharmony_ci index = self.nodeindex[nodename] 19027db96d56Sopenharmony_ci return self.nodelist[index] 19037db96d56Sopenharmony_ci except KeyError: 19047db96d56Sopenharmony_ci return None 19057db96d56Sopenharmony_ci except IndexError: 19067db96d56Sopenharmony_ci return None 19077db96d56Sopenharmony_ci 19087db96d56Sopenharmony_ci # (args,nodename) == (key,location) 19097db96d56Sopenharmony_ci def dumpindex(self, outfile=sys.stdout): 19107db96d56Sopenharmony_ci print('<UL>', file=outfile) 19117db96d56Sopenharmony_ci for (key,location) in self.indexlist: 19127db96d56Sopenharmony_ci key = self.codeexpand(key) 19137db96d56Sopenharmony_ci location = makefile(location) 19147db96d56Sopenharmony_ci location = self.dirname + '/' + location 19157db96d56Sopenharmony_ci print('<LI><OBJECT type="text/sitemap">', end=' ', file=outfile) 19167db96d56Sopenharmony_ci print('<param name="Name" value="' + key + '">', end=' ', file=outfile) 19177db96d56Sopenharmony_ci print('<param name="Local" value="' + location + '">', end=' ', file=outfile) 19187db96d56Sopenharmony_ci print('</OBJECT>', file=outfile) 19197db96d56Sopenharmony_ci print('</UL>', file=outfile) 19207db96d56Sopenharmony_ci 19217db96d56Sopenharmony_ci def codeexpand(self, line): 19227db96d56Sopenharmony_ci co = self.codeprog.match(line) 19237db96d56Sopenharmony_ci if not co: 19247db96d56Sopenharmony_ci return line 19257db96d56Sopenharmony_ci bgn, end = co.span(0) 19267db96d56Sopenharmony_ci a, b = co.span(1) 19277db96d56Sopenharmony_ci line = line[:bgn] + line[a:b] + line[end:] 19287db96d56Sopenharmony_ci return line 19297db96d56Sopenharmony_ci 19307db96d56Sopenharmony_ci 19317db96d56Sopenharmony_ci# Put @var{} around alphabetic substrings 19327db96d56Sopenharmony_cidef makevar(str): 19337db96d56Sopenharmony_ci return '@var{'+str+'}' 19347db96d56Sopenharmony_ci 19357db96d56Sopenharmony_ci 19367db96d56Sopenharmony_ci# Split a string in "words" according to findwordend 19377db96d56Sopenharmony_cidef splitwords(str, minlength): 19387db96d56Sopenharmony_ci words = [] 19397db96d56Sopenharmony_ci i = 0 19407db96d56Sopenharmony_ci n = len(str) 19417db96d56Sopenharmony_ci while i < n: 19427db96d56Sopenharmony_ci while i < n and str[i] in ' \t\n': i = i+1 19437db96d56Sopenharmony_ci if i >= n: break 19447db96d56Sopenharmony_ci start = i 19457db96d56Sopenharmony_ci i = findwordend(str, i, n) 19467db96d56Sopenharmony_ci words.append(str[start:i]) 19477db96d56Sopenharmony_ci while len(words) < minlength: words.append('') 19487db96d56Sopenharmony_ci return words 19497db96d56Sopenharmony_ci 19507db96d56Sopenharmony_ci 19517db96d56Sopenharmony_ci# Find the end of a "word", matching braces and interpreting @@ @{ @} 19527db96d56Sopenharmony_cifwprog = re.compile('[@{} ]') 19537db96d56Sopenharmony_cidef findwordend(str, i, n): 19547db96d56Sopenharmony_ci level = 0 19557db96d56Sopenharmony_ci while i < n: 19567db96d56Sopenharmony_ci mo = fwprog.search(str, i) 19577db96d56Sopenharmony_ci if not mo: 19587db96d56Sopenharmony_ci break 19597db96d56Sopenharmony_ci i = mo.start() 19607db96d56Sopenharmony_ci c = str[i]; i = i+1 19617db96d56Sopenharmony_ci if c == '@': i = i+1 # Next character is not special 19627db96d56Sopenharmony_ci elif c == '{': level = level+1 19637db96d56Sopenharmony_ci elif c == '}': level = level-1 19647db96d56Sopenharmony_ci elif c == ' ' and level <= 0: return i-1 19657db96d56Sopenharmony_ci return n 19667db96d56Sopenharmony_ci 19677db96d56Sopenharmony_ci 19687db96d56Sopenharmony_ci# Convert a node name into a file name 19697db96d56Sopenharmony_cidef makefile(nodename): 19707db96d56Sopenharmony_ci nodename = nodename.strip() 19717db96d56Sopenharmony_ci return fixfunnychars(nodename) + '.html' 19727db96d56Sopenharmony_ci 19737db96d56Sopenharmony_ci 19747db96d56Sopenharmony_ci# Characters that are perfectly safe in filenames and hyperlinks 19757db96d56Sopenharmony_cigoodchars = string.ascii_letters + string.digits + '!@-=+.' 19767db96d56Sopenharmony_ci 19777db96d56Sopenharmony_ci# Replace characters that aren't perfectly safe by dashes 19787db96d56Sopenharmony_ci# Underscores are bad since Cern HTTPD treats them as delimiters for 19797db96d56Sopenharmony_ci# encoding times, so you get mismatches if you compress your files: 19807db96d56Sopenharmony_ci# a.html.gz will map to a_b.html.gz 19817db96d56Sopenharmony_cidef fixfunnychars(addr): 19827db96d56Sopenharmony_ci i = 0 19837db96d56Sopenharmony_ci while i < len(addr): 19847db96d56Sopenharmony_ci c = addr[i] 19857db96d56Sopenharmony_ci if c not in goodchars: 19867db96d56Sopenharmony_ci c = '-' 19877db96d56Sopenharmony_ci addr = addr[:i] + c + addr[i+1:] 19887db96d56Sopenharmony_ci i = i + len(c) 19897db96d56Sopenharmony_ci return addr 19907db96d56Sopenharmony_ci 19917db96d56Sopenharmony_ci 19927db96d56Sopenharmony_ci# Increment a string used as an enumeration 19937db96d56Sopenharmony_cidef increment(s): 19947db96d56Sopenharmony_ci if not s: 19957db96d56Sopenharmony_ci return '1' 19967db96d56Sopenharmony_ci for sequence in string.digits, string.ascii_lowercase, string.ascii_uppercase: 19977db96d56Sopenharmony_ci lastc = s[-1] 19987db96d56Sopenharmony_ci if lastc in sequence: 19997db96d56Sopenharmony_ci i = sequence.index(lastc) + 1 20007db96d56Sopenharmony_ci if i >= len(sequence): 20017db96d56Sopenharmony_ci if len(s) == 1: 20027db96d56Sopenharmony_ci s = sequence[0]*2 20037db96d56Sopenharmony_ci if s == '00': 20047db96d56Sopenharmony_ci s = '10' 20057db96d56Sopenharmony_ci else: 20067db96d56Sopenharmony_ci s = increment(s[:-1]) + sequence[0] 20077db96d56Sopenharmony_ci else: 20087db96d56Sopenharmony_ci s = s[:-1] + sequence[i] 20097db96d56Sopenharmony_ci return s 20107db96d56Sopenharmony_ci return s # Don't increment 20117db96d56Sopenharmony_ci 20127db96d56Sopenharmony_ci 20137db96d56Sopenharmony_cidef test(): 20147db96d56Sopenharmony_ci import sys 20157db96d56Sopenharmony_ci debugging = 0 20167db96d56Sopenharmony_ci print_headers = 0 20177db96d56Sopenharmony_ci cont = 0 20187db96d56Sopenharmony_ci html3 = 0 20197db96d56Sopenharmony_ci htmlhelp = '' 20207db96d56Sopenharmony_ci 20217db96d56Sopenharmony_ci while sys.argv[1] == ['-d']: 20227db96d56Sopenharmony_ci debugging = debugging + 1 20237db96d56Sopenharmony_ci del sys.argv[1] 20247db96d56Sopenharmony_ci if sys.argv[1] == '-p': 20257db96d56Sopenharmony_ci print_headers = 1 20267db96d56Sopenharmony_ci del sys.argv[1] 20277db96d56Sopenharmony_ci if sys.argv[1] == '-c': 20287db96d56Sopenharmony_ci cont = 1 20297db96d56Sopenharmony_ci del sys.argv[1] 20307db96d56Sopenharmony_ci if sys.argv[1] == '-3': 20317db96d56Sopenharmony_ci html3 = 1 20327db96d56Sopenharmony_ci del sys.argv[1] 20337db96d56Sopenharmony_ci if sys.argv[1] == '-H': 20347db96d56Sopenharmony_ci helpbase = sys.argv[2] 20357db96d56Sopenharmony_ci del sys.argv[1:3] 20367db96d56Sopenharmony_ci if len(sys.argv) != 3: 20377db96d56Sopenharmony_ci print('usage: texi2hh [-d [-d]] [-p] [-c] [-3] [-H htmlhelp]', \ 20387db96d56Sopenharmony_ci 'inputfile outputdirectory') 20397db96d56Sopenharmony_ci sys.exit(2) 20407db96d56Sopenharmony_ci 20417db96d56Sopenharmony_ci if html3: 20427db96d56Sopenharmony_ci parser = TexinfoParserHTML3() 20437db96d56Sopenharmony_ci else: 20447db96d56Sopenharmony_ci parser = TexinfoParser() 20457db96d56Sopenharmony_ci parser.cont = cont 20467db96d56Sopenharmony_ci parser.debugging = debugging 20477db96d56Sopenharmony_ci parser.print_headers = print_headers 20487db96d56Sopenharmony_ci 20497db96d56Sopenharmony_ci file = sys.argv[1] 20507db96d56Sopenharmony_ci dirname = sys.argv[2] 20517db96d56Sopenharmony_ci parser.setdirname(dirname) 20527db96d56Sopenharmony_ci parser.setincludedir(os.path.dirname(file)) 20537db96d56Sopenharmony_ci 20547db96d56Sopenharmony_ci htmlhelp = HTMLHelp(helpbase, dirname) 20557db96d56Sopenharmony_ci parser.sethtmlhelp(htmlhelp) 20567db96d56Sopenharmony_ci 20577db96d56Sopenharmony_ci try: 20587db96d56Sopenharmony_ci fp = open(file, 'r') 20597db96d56Sopenharmony_ci except IOError as msg: 20607db96d56Sopenharmony_ci print(file, ':', msg) 20617db96d56Sopenharmony_ci sys.exit(1) 20627db96d56Sopenharmony_ci 20637db96d56Sopenharmony_ci with fp: 20647db96d56Sopenharmony_ci parser.parse(fp) 20657db96d56Sopenharmony_ci parser.report() 20667db96d56Sopenharmony_ci 20677db96d56Sopenharmony_ci htmlhelp.finalize() 20687db96d56Sopenharmony_ci 20697db96d56Sopenharmony_ci 20707db96d56Sopenharmony_ciif __name__ == "__main__": 20717db96d56Sopenharmony_ci test() 2072