mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	many fixes by anonymous contributor
This commit is contained in:
		
							parent
							
								
									d639b45ed6
								
							
						
					
					
						commit
						06f4289d3f
					
				
					 3 changed files with 894 additions and 216 deletions
				
			
		
							
								
								
									
										370
									
								
								Doc/texi2html.py
									
										
									
									
									
								
							
							
						
						
									
										370
									
								
								Doc/texi2html.py
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| # Convert GNU texinfo files into HTML, one file per node. | # Convert GNU texinfo files into HTML, one file per node. | ||||||
| # Based on Texinfo 2.14. | # Based on Texinfo 2.14. | ||||||
| # Usage: texi2html [-d] [-d] inputfile outputdirectory | # Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory | ||||||
| # The input file must be a complete texinfo file, e.g. emacs.texi. | # The input file must be a complete texinfo file, e.g. emacs.texi. | ||||||
| # This creates many files (one per info node) in the output directory, | # This creates many files (one per info node) in the output directory, | ||||||
| # overwriting existing files of the same name.  All files created have | # overwriting existing files of the same name.  All files created have | ||||||
|  | @ -17,12 +17,23 @@ | ||||||
| # - handle @exdent properly | # - handle @exdent properly | ||||||
| # - add links directly to the proper line from indices | # - add links directly to the proper line from indices | ||||||
| # - check against the definitive list of @-cmds; we still miss (among others): | # - check against the definitive list of @-cmds; we still miss (among others): | ||||||
| # - @set, @clear, @ifset, @ifclear |  | ||||||
| # - @defindex (hard) | # - @defindex (hard) | ||||||
| # - @c(omment) in the middle of a line (rarely used) | # - @c(omment) in the middle of a line (rarely used) | ||||||
| # - @this* (not really needed, only used in headers anyway) | # - @this* (not really needed, only used in headers anyway) | ||||||
| # - @today{} (ever used outside title page?) | # - @today{} (ever used outside title page?) | ||||||
| 
 | 
 | ||||||
|  | # More consistent handling of chapters/sections/etc. | ||||||
|  | # Lots of documentation | ||||||
|  | # Many more options: | ||||||
|  | #	-top	designate top node | ||||||
|  | #	-links	customize which types of links are included | ||||||
|  | #	-split  split at chapters or sections instead of nodes | ||||||
|  | #	-name	Allow different types of filename handling. Non unix systems | ||||||
|  | #		will have problems with long node names | ||||||
|  | #	... | ||||||
|  | # Support the most recent texinfo version and take a good look at HTML 3.0 | ||||||
|  | # More debugging output (customizable) and more fexible error handling | ||||||
|  | # How about icons ? | ||||||
| 
 | 
 | ||||||
| import os | import os | ||||||
| import regex | import regex | ||||||
|  | @ -39,6 +50,81 @@ | ||||||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||||
| 					# menu item (Yuck!) | 					# menu item (Yuck!) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class Node: | ||||||
|  |     __doc__ = """ | ||||||
|  |     Some of the parser's functionality is separated into this class. | ||||||
|  | 
 | ||||||
|  |     A Node accumulates its contents, takes care of links to other Nodes | ||||||
|  |     and saves itself when it is finished and all links are resolved. """ | ||||||
|  |      | ||||||
|  |     def __init__ (self, dir, name, topname, title, next, prev, up): | ||||||
|  | 	self.dirname = dir | ||||||
|  | 	self.name = name | ||||||
|  | 	if topname: | ||||||
|  | 	    self.topname = topname | ||||||
|  | 	else: | ||||||
|  | 	    self.topname = name | ||||||
|  | 	self.title = title | ||||||
|  | 	self.next = next | ||||||
|  | 	self.prev = prev | ||||||
|  | 	self.up = up | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.type = 0 | ||||||
|  | 	self.cont = '' | ||||||
|  | 	 | ||||||
|  |     def write (self, *lines): | ||||||
|  | 	for line in lines: | ||||||
|  | 	    self.lines.append (line) | ||||||
|  | 
 | ||||||
|  |     def flush (self): | ||||||
|  | 	fp = open (self.dirname + '/' + makefile(self.name), 'w') | ||||||
|  | 	fp.write (self.prologue) | ||||||
|  | 	fp.write (self.text) | ||||||
|  | 	fp.write (self.epilogue) | ||||||
|  | 	fp.close () | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def link(self, label, nodename): | ||||||
|  | 	if nodename: | ||||||
|  | 	    if string.lower(nodename) == '(dir)': | ||||||
|  | 		addr = '../dir.html' | ||||||
|  | 	    else: | ||||||
|  | 		addr = makefile(nodename) | ||||||
|  | 	    self.write(label, ': <A HREF="', addr, '" TYPE="', \ | ||||||
|  | 		       label, '">', nodename, '</A>  \n') | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def finalize(self): | ||||||
|  | 	length = len (self.lines) | ||||||
|  | 	self.text = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.write ('<BR> <HR>\n') | ||||||
|  | 	if self.cont != self.next: | ||||||
|  | 	    self.link('Cont', self.cont) | ||||||
|  | 	self.link('Next', self.next) | ||||||
|  | 	self.link('Prev', self.prev) | ||||||
|  | 	self.link('Up', self.up) | ||||||
|  | 	if self.name <> self.topname: | ||||||
|  | 	    self.link('Top', self.topname) | ||||||
|  | 	self.write ('<BR> <HR> <P>\n') | ||||||
|  | 	links = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	 | ||||||
|  | 	self.prologue = \ | ||||||
|  | 		      '<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n' + \ | ||||||
|  | 		      '<!- Converted with texi2html and Python>\n' + \ | ||||||
|  | 		      '<P>\n<HEAD>\n' + \ | ||||||
|  | 		      '<TITLE>' + self.title + '</TITLE>\n' + \ | ||||||
|  | 		      '</HEAD>\n<BODY>\n<P>\n' + \ | ||||||
|  | 		      links | ||||||
|  | 	 | ||||||
|  | 	if length > 20: | ||||||
|  | 	    self.epilogue = links + '</BODY>\n' | ||||||
|  | 	else: | ||||||
|  | 	    self.epilogue = '</BODY>\n' | ||||||
|  | 	     | ||||||
|  | 
 | ||||||
| class TexinfoParser: | class TexinfoParser: | ||||||
| 
 | 
 | ||||||
| 	# Initialize an instance | 	# Initialize an instance | ||||||
|  | @ -50,6 +136,7 @@ def __init__(self): | ||||||
| 		self.nodelineno = 0	# Linenumber relative to node | 		self.nodelineno = 0	# Linenumber relative to node | ||||||
| 		self.links = None	# Links from current node | 		self.links = None	# Links from current node | ||||||
| 		self.savetext = None	# If not None, save text head instead | 		self.savetext = None	# If not None, save text head instead | ||||||
|  | 		self.savestack = []	# If not None, save text head instead | ||||||
| 		self.dirname = 'tmp'	# directory where files are created | 		self.dirname = 'tmp'	# directory where files are created | ||||||
| 		self.includedir = '.'	# directory to search @include files | 		self.includedir = '.'	# directory to search @include files | ||||||
| 		self.nodename = ''	# name of current node | 		self.nodename = ''	# name of current node | ||||||
|  | @ -59,14 +146,17 @@ def __init__(self): | ||||||
| 		self.contents = []	# Reset table of contents | 		self.contents = []	# Reset table of contents | ||||||
| 		self.numbering = []	# Reset section numbering counters | 		self.numbering = []	# Reset section numbering counters | ||||||
| 		self.nofill = 0		# Normal operation: fill paragraphs | 		self.nofill = 0		# Normal operation: fill paragraphs | ||||||
| 		self.goodset=['html']	# Names that should be parsed in ifset | 		self.values={'html': 1} # Names that should be parsed in ifset | ||||||
| 		self.stackinfo={}	# Keep track of state in the stack | 		self.stackinfo={}	# Keep track of state in the stack | ||||||
| 		# XXX The following should be reset per node?! | 		# XXX The following should be reset per node?! | ||||||
| 		self.footnotes = []	# Reset list of footnotes | 		self.footnotes = []	# Reset list of footnotes | ||||||
| 		self.itemarg = None	# Reset command used by @item | 		self.itemarg = None	# Reset command used by @item | ||||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||||
| 		self.itemindex = None	# Reset item index name | 		self.itemindex = None	# Reset item index name | ||||||
| 
 | 		self.node = None | ||||||
|  | 		self.nodestack = [] | ||||||
|  | 		self.cont = 0 | ||||||
|  | 		self.includedepth = 0 | ||||||
| 	# Set (output) directory name | 	# Set (output) directory name | ||||||
| 	def setdirname(self, dirname): | 	def setdirname(self, dirname): | ||||||
| 		self.dirname = dirname | 		self.dirname = dirname | ||||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | ||||||
| 		if self.stack: | 		if self.stack: | ||||||
| 			print '*** Stack not empty at the end' | 			print '*** Stack not empty at the end' | ||||||
| 			print '***', self.stack | 			print '***', self.stack | ||||||
|  | 		if self.includedepth == 0: | ||||||
|  | 		    while self.nodestack: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
| 
 | 
 | ||||||
| 	# Start saving text in a buffer instead of writing it to a file | 	# Start saving text in a buffer instead of writing it to a file | ||||||
| 	def startsaving(self): | 	def startsaving(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			print '*** Recursively saving text, expect trouble' | 			self.savestack.append (self.savetext) | ||||||
|  | 			# print '*** Recursively saving text, expect trouble' | ||||||
| 		self.savetext = '' | 		self.savetext = '' | ||||||
| 
 | 
 | ||||||
| 	# Return the text saved so far and start writing to file again | 	# Return the text saved so far and start writing to file again | ||||||
| 	def collectsavings(self): | 	def collectsavings(self): | ||||||
| 		savetext = self.savetext | 		savetext = self.savetext | ||||||
| 		self.savetext = None | 		if len (self.savestack) > 0: | ||||||
|  | 			self.savetext = self.savestack[-1] | ||||||
|  | 			del self.savestack[-1] | ||||||
|  | 		else: | ||||||
|  | 			self.savetext = None | ||||||
| 		return savetext or '' | 		return savetext or '' | ||||||
| 
 | 
 | ||||||
| 	# Write text to file, or save it in a buffer, or ignore it | 	# Write text to file, or save it in a buffer, or ignore it | ||||||
| 	def write(self, *args): | 	def write(self, *args): | ||||||
| 		text = string.joinfields(args, '') | 		try: | ||||||
|  | 			text = string.joinfields(args, '') | ||||||
|  | 		except: | ||||||
|  | 			print args | ||||||
|  | 			raise TypeError | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			self.savetext = self.savetext + text | 			self.savetext = self.savetext + text | ||||||
| 		elif self.nodefp: | 		elif self.nodefp: | ||||||
| 			self.nodefp.write(text) | 			self.nodefp.write(text) | ||||||
| 
 | 		elif self.node: | ||||||
|  | 		        self.node.write (text) | ||||||
| 	# Complete the current node -- write footnotes and close file | 	# Complete the current node -- write footnotes and close file | ||||||
| 	def endnode(self): | 	def endnode(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
|  | @ -172,7 +277,16 @@ def endnode(self): | ||||||
| 				self.write ('<HR>\n') | 				self.write ('<HR>\n') | ||||||
| 			self.write('</BODY>\n') | 			self.write('</BODY>\n') | ||||||
| 			self.nodefp.close() | 			self.nodefp.close() | ||||||
| 		self.nodefp = None | 			self.nodefp = None | ||||||
|  | 		elif self.node: | ||||||
|  | 		    if not self.cont and \ | ||||||
|  | 		       (not self.node.type or \ | ||||||
|  | 			(self.node.next and self.node.prev and self.node.up)): | ||||||
|  | 			self.node.finalize () | ||||||
|  | 			self.node.flush () | ||||||
|  | 		    else: | ||||||
|  | 			self.nodestack.append (self.node) | ||||||
|  | 		    self.node = None | ||||||
| 		self.nodename = '' | 		self.nodename = '' | ||||||
| 
 | 
 | ||||||
| 	# Process a list of lines, expanding embedded @-commands | 	# Process a list of lines, expanding embedded @-commands | ||||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | ||||||
| 		save_done = self.done | 		save_done = self.done | ||||||
| 		save_skip = self.skip | 		save_skip = self.skip | ||||||
| 		save_stack = self.stack | 		save_stack = self.stack | ||||||
|  | 		self.includedepth = self.includedepth + 1 | ||||||
| 		self.parserest(fp, 0) | 		self.parserest(fp, 0) | ||||||
|  | 		self.includedepth = self.includedepth - 1 | ||||||
| 		fp.close() | 		fp.close() | ||||||
| 		self.done = save_done | 		self.done = save_done | ||||||
| 		self.skip = save_skip | 		self.skip = save_skip | ||||||
|  | @ -364,7 +480,9 @@ def open_TeX(self): self.write('TeX') | ||||||
| 	def close_TeX(self): pass | 	def close_TeX(self): pass | ||||||
| 
 | 
 | ||||||
| 	def handle_copyright(self): self.write('(C)') | 	def handle_copyright(self): self.write('(C)') | ||||||
| 
 | 	def open_copyright(self): self.write('(C)') | ||||||
|  | 	def close_copyright(self): pass | ||||||
|  | 		 | ||||||
| 	def open_minus(self): self.write('-') | 	def open_minus(self): self.write('-') | ||||||
| 	def close_minus(self): pass | 	def close_minus(self): pass | ||||||
| 
 | 
 | ||||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | ||||||
| 	close_i = close_emph | 	close_i = close_emph | ||||||
| 
 | 
 | ||||||
| 	def open_footnote(self): | 	def open_footnote(self): | ||||||
| 		if self.savetext <> None: | 		# if self.savetext <> None: | ||||||
| 			print '*** Recursive footnote -- expect weirdness' | 		# 	print '*** Recursive footnote -- expect weirdness' | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.write('<A NAME="footnoteref', `id`, \ | 		self.write('<A NAME="footnoteref', `id`, \ | ||||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||||
| 		self.savetext = '' | 		# self.savetext = '' | ||||||
|  | 		self.startsaving () | ||||||
| 
 | 
 | ||||||
| 	def close_footnote(self): | 	def close_footnote(self): | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.footnotes.append(`id`, self.savetext) | 		# self.footnotes.append(`id`, self.savetext) | ||||||
| 		self.savetext = None | 		self.footnotes.append(`id`, self.collectsavings()) | ||||||
|  | 		# self.savetext = None | ||||||
| 
 | 
 | ||||||
| 	def writefootnotes(self): | 	def writefootnotes(self): | ||||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||||
|  | @ -534,7 +654,9 @@ def command(self, line): | ||||||
| 			try: | 			try: | ||||||
| 				func = getattr(self, 'bgn_' + cmd) | 				func = getattr(self, 'bgn_' + cmd) | ||||||
| 			except AttributeError: | 			except AttributeError: | ||||||
| 				self.unknown_cmd(cmd, args) | 				# don't complain if we are skipping anyway | ||||||
|  | 				if not self.skip: | ||||||
|  | 					self.unknown_cmd(cmd, args) | ||||||
| 				return | 				return | ||||||
| 			self.stack.append(cmd) | 			self.stack.append(cmd) | ||||||
| 			func(args) | 			func(args) | ||||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): self.skip = self.skip - 1 | ||||||
| 	def bgn_tex(self, args): self.skip = self.skip + 1 | 	def bgn_tex(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_tex(self): self.skip = self.skip - 1 | 	def end_tex(self): self.skip = self.skip - 1 | ||||||
| 
 | 
 | ||||||
| 	def bgn_set(self, args): | 	def do_set(self, args): | ||||||
| 		if args not in self.goodset: | 		fields = string.splitfields (args, ' ') | ||||||
| 			self.gooset.append(args) | 		key = fields[0] | ||||||
|  | 		if len(fields) == 1: | ||||||
|  | 			value = 1 | ||||||
|  | 		else: | ||||||
|  | 			value = string.joinfields (fields[1:], ' ') | ||||||
|  | 		self.values[key]=value | ||||||
|  | 		print self.values | ||||||
| 			 | 			 | ||||||
| 	def bgn_clear(self, args): | 	def do_clear(self, args): | ||||||
| 		if args in self.goodset: | 		self.values[args] = None | ||||||
| 			self.gooset.remove(args) |  | ||||||
| 			 | 			 | ||||||
| 	def bgn_ifset(self, args): | 	def bgn_ifset(self, args): | ||||||
| 		if args not in self.goodset: | 		if args not in self.values.keys() \ | ||||||
|  | 		   or self.values[args] is None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
|  | @ -615,14 +743,25 @@ def end_ifset(self): | ||||||
| 		del self.stackinfo[len(self.stack) + 1] | 		del self.stackinfo[len(self.stack) + 1] | ||||||
| 
 | 
 | ||||||
| 	def bgn_ifclear(self, args): | 	def bgn_ifclear(self, args): | ||||||
| 		if args in self.goodset: | 		if args in self.values.keys() \ | ||||||
|  | 		   and self.values[args] is not None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
| 			self.stackinfo[len(self.stack)] = 0 | 			self.stackinfo[len(self.stack)] = 0 | ||||||
| 		 | 		 | ||||||
| 	end_ifclear = end_ifset | 	end_ifclear = end_ifset | ||||||
| 	 | 
 | ||||||
|  | 	def open_value(self): | ||||||
|  | 		self.startsaving() | ||||||
|  | 
 | ||||||
|  | 	def close_value(self): | ||||||
|  | 		key = self.collectsavings () | ||||||
|  | 		if key in self.values.keys(): | ||||||
|  | 			self.write (self.values[key]) | ||||||
|  | 		else: | ||||||
|  | 			print '*** Undefined value: ', key | ||||||
|  | 		        | ||||||
| 	# --- Beginning a file --- | 	# --- Beginning a file --- | ||||||
| 
 | 
 | ||||||
| 	do_finalout = do_comment | 	do_finalout = do_comment | ||||||
|  | @ -630,20 +769,25 @@ def bgn_ifclear(self, args): | ||||||
| 	do_setfilename = do_comment | 	do_setfilename = do_comment | ||||||
| 
 | 
 | ||||||
| 	def do_settitle(self, args): | 	def do_settitle(self, args): | ||||||
| 		self.title = args | 		print args | ||||||
| 
 | 		self.startsaving() | ||||||
|  | 		self.expand (args) | ||||||
|  | 		self.title = self.collectsavings () | ||||||
|  | 		print self.title | ||||||
| 	def do_parskip(self, args): pass | 	def do_parskip(self, args): pass | ||||||
| 	 | 	 | ||||||
| 	# --- Ending a file --- | 	# --- Ending a file --- | ||||||
| 
 | 
 | ||||||
| 	def do_bye(self, args): | 	def do_bye(self, args): | ||||||
|  | 		self.endnode () | ||||||
| 		self.done = 1 | 		self.done = 1 | ||||||
| 
 | 
 | ||||||
| 	# --- Title page --- | 	# --- Title page --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_titlepage(self): self.skip = self.skip - 1 | 	def end_titlepage(self): self.skip = self.skip - 1 | ||||||
| 
 | 	def do_shorttitlepage(self, args): pass | ||||||
|  | 	 | ||||||
| 	def do_center(self, args): | 	def do_center(self, args): | ||||||
| 		# Actually not used outside title page... | 		# Actually not used outside title page... | ||||||
| 		self.write('<H1>') | 		self.write('<H1>') | ||||||
|  | @ -685,24 +829,28 @@ def do_node(self, args): | ||||||
| 		else: | 		else: | ||||||
| 			if self.debugging: print '--- writing', file | 			if self.debugging: print '--- writing', file | ||||||
| 		self.filenames[file] = 1 | 		self.filenames[file] = 1 | ||||||
| 		self.nodefp = open(file, 'w') | 		# self.nodefp = open(file, 'w') | ||||||
| 		self.nodename = name | 		self.nodename = name | ||||||
|  | 		if self.cont and self.nodestack: | ||||||
|  | 		    self.nodestack[-1].cont = self.nodename | ||||||
| 		if not self.topname: self.topname = name | 		if not self.topname: self.topname = name | ||||||
| 		title = name | 		title = name | ||||||
| 		if self.title: title = title + ' -- ' + self.title | 		if self.title: title = title + ' -- ' + self.title | ||||||
| 		# No idea what this means, but this is what latex2html writes | 		# No idea what this means, but this is what latex2html writes | ||||||
| 		self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||||
| 		self.write('<!- Converted with texi2html and Python>\n') | 		# self.write('<!- Converted with texi2html and Python>\n') | ||||||
| 		self.write ('<P>\n<HEAD>\n') | 		# self.write ('<P>\n<HEAD>\n') | ||||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||||
| 		self.link('Next', next) | 		# self.link('Next', next) | ||||||
| 		self.link('Prev', prev) | 		# self.link('Prev', prev) | ||||||
| 		self.link('Up', up) | 		# self.link('Up', up) | ||||||
| 		if self.nodename <> self.topname: | 		# if self.nodename <> self.topname: | ||||||
| 			self.link('Top', self.topname) | 		# 	self.link('Top', self.topname) | ||||||
| 		self.write ('<BR> <HR> <P>\n') | 		# self.write ('<BR> <HR> <P>\n') | ||||||
| 
 | 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||||
|  | 				  title, next, prev, up) | ||||||
|  | 		 | ||||||
| 	def link(self, label, nodename): | 	def link(self, label, nodename): | ||||||
| 		if nodename: | 		if nodename: | ||||||
| 			if string.lower(nodename) == '(dir)': | 			if string.lower(nodename) == '(dir)': | ||||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | ||||||
| 
 | 
 | ||||||
| 	# --- Sectioning commands --- | 	# --- Sectioning commands --- | ||||||
| 
 | 
 | ||||||
|  | 	def popstack (self, type): | ||||||
|  | 	    if (self.node): | ||||||
|  | 		self.node.type = type | ||||||
|  | 		while self.nodestack: | ||||||
|  | 		    if self.nodestack[-1].type > type: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    elif self.nodestack[-1].type == type: | ||||||
|  | 			if not self.nodestack[-1].next: | ||||||
|  | 			    self.nodestack[-1].next = self.node.name | ||||||
|  | 			if not self.node.prev: | ||||||
|  | 			    self.node.prev = self.nodestack[-1].name | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    else: | ||||||
|  | 			if type > 1 and not self.node.up: | ||||||
|  | 			    self.node.up = self.nodestack[-1].name | ||||||
|  | 			break | ||||||
|  | 
 | ||||||
| 	def do_chapter(self, args): | 	def do_chapter(self, args): | ||||||
| 		self.heading('H1', args, 0) | 		self.heading('H1', args, 0) | ||||||
|  | 		self.popstack (1) | ||||||
|  | 
 | ||||||
| 	def do_unnumbered(self, args): | 	def do_unnumbered(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_appendix(self, args): | 	def do_appendix(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_top(self, args): | 	def do_top(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 	def do_chapheading(self, args): | 	def do_chapheading(self, args): | ||||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | ||||||
| 
 | 
 | ||||||
| 	def do_section(self, args): | 	def do_section(self, args): | ||||||
| 		self.heading('H1', args, 1) | 		self.heading('H1', args, 1) | ||||||
|  | 		self.popstack (2) | ||||||
|  | 
 | ||||||
| 	def do_unnumberedsec(self, args): | 	def do_unnumberedsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	def do_appendixsec(self, args): | 	def do_appendixsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	do_appendixsection = do_appendixsec | 	do_appendixsection = do_appendixsec | ||||||
| 	def do_heading(self, args): | 	def do_heading(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsection(self, args): | 	def do_subsection(self, args): | ||||||
| 		self.heading('H2', args, 2) | 		self.heading('H2', args, 2) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_unnumberedsubsec(self, args): | 	def do_unnumberedsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_appendixsubsec(self, args): | 	def do_appendixsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_subheading(self, args): | 	def do_subheading(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsubsection(self, args): | 	def do_subsubsection(self, args): | ||||||
| 		self.heading('H3', args, 3) | 		self.heading('H3', args, 3) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_unnumberedsubsubsec(self, args): | 	def do_unnumberedsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_appendixsubsubsec(self, args): | 	def do_appendixsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_subsubheading(self, args): | 	def do_subsubheading(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
| 
 | 
 | ||||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | ||||||
| 			print '---', args | 			print '---', args | ||||||
| 
 | 
 | ||||||
| 	def do_contents(self, args): | 	def do_contents(self, args): | ||||||
| 		pass | 	        # pass | ||||||
| 		# self.listcontents('Table of Contents', 999) | 		self.listcontents('Table of Contents', 999) | ||||||
| 
 | 
 | ||||||
| 	def do_shortcontents(self, args): | 	def do_shortcontents(self, args): | ||||||
| 		pass | 		pass | ||||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | ||||||
| 	# --- Function and variable definitions --- | 	# --- Function and variable definitions --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deffn(self, args): | 	def bgn_deffn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
| 		words = splitwords(args, 2) | 		self.do_deffnx (args) | ||||||
| 		[category, name], rest = words[:2], words[2:] |  | ||||||
| 		self.expand('@b{' + name + '}') |  | ||||||
| 		for word in rest: self.expand(' ' + makevar(word)) |  | ||||||
| 		self.expand(' -- ' + category) |  | ||||||
| 		self.write('<DD>\n') |  | ||||||
| 		self.index('fn', name) |  | ||||||
| 
 | 
 | ||||||
| 	def end_deffn(self): | 	def end_deffn(self): | ||||||
| 		self.write('</DL>\n') | 		self.write('</DL>\n') | ||||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | ||||||
| 
 | 
 | ||||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||||
| 	end_defun = end_deffn | 	end_defun = end_deffn | ||||||
|  | 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||||
| 	end_defmac = end_deffn | 	end_defmac = end_deffn | ||||||
|  | 	def do_defmacx(self, args): self.do_deffnx('Macro ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | ||||||
| 	end_defspec = end_deffn | 	end_defspec = end_deffn | ||||||
|  | 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defvr(self, args): | 	def bgn_defvr(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defvrx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defvr = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_defvrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@code{' + name + '}') | 		self.expand('@code{' + name + '}') | ||||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name) | 		self.index('vr', name) | ||||||
| 
 | 
 | ||||||
| 	end_defvr = end_deffn |  | ||||||
| 
 |  | ||||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||||
| 	end_defvar = end_defvr | 	end_defvar = end_defvr | ||||||
|  | 	def do_defvarx(self, args): self.do_defvrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | ||||||
| 	end_defopt = end_defvr | 	end_defopt = end_defvr | ||||||
|  | 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for typed languages --- | 	# --- Ditto for typed languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefn(self, args): | 	def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypefnx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypefn = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypefnx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypefn = end_deffn |  | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||||
| 	end_deftypefun = end_deftypefn | 	end_deftypefun = end_deftypefn | ||||||
|  | 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypevr(self, args): | 	def bgn_deftypevr(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypevrx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypevr = end_deftypefn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypevrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypevr = end_deftypefn |  | ||||||
| 
 |  | ||||||
| 	def bgn_deftypevar(self, args): | 	def bgn_deftypevar(self, args): | ||||||
| 		self.bgn_deftypevr('Variable ' + args) | 		self.bgn_deftypevr('Variable ' + args) | ||||||
| 	end_deftypevar = end_deftypevr | 	end_deftypevar = end_deftypevr | ||||||
|  | 	def do_deftypevarx(self, args): | ||||||
|  | 		self.do_deftypevrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for object-oriented languages --- | 	# --- Ditto for object-oriented languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_defcv(self, args): | 	def bgn_defcv(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_defcvx(args) | ||||||
|  | 
 | ||||||
|  | 	end_defcv = end_deftypevr | ||||||
|  | 
 | ||||||
|  | 	def do_defcvx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defcv = end_deftypevr |  | ||||||
| 
 |  | ||||||
| 	def bgn_defivar(self, args): | 	def bgn_defivar(self, args): | ||||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | 		self.bgn_defcv('{Instance Variable} ' + args) | ||||||
| 	end_defivar = end_defcv | 	end_defivar = end_defcv | ||||||
|  | 	def do_defivarx(self, args): | ||||||
|  | 		self.do_defcvx('{Instance Variable} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defop(self, args): | 	def bgn_defop(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defopx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defop = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_defopx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defop = end_defcv |  | ||||||
| 
 |  | ||||||
| 	def bgn_defmethod(self, args): | 	def bgn_defmethod(self, args): | ||||||
| 		self.bgn_defop('Method ' + args) | 		self.bgn_defop('Method ' + args) | ||||||
| 	end_defmethod = end_defop | 	end_defmethod = end_defop | ||||||
|  | 	def do_defmethodx(self, args): | ||||||
|  | 		self.do_defopx('Method ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for data types --- | 	# --- Ditto for data types --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftp(self, args): | 	def bgn_deftp(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftpx(args) | ||||||
|  | 
 | ||||||
|  | 	end_deftp = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_deftpx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('tp', name) | 		self.index('tp', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftp = end_defcv |  | ||||||
| 
 |  | ||||||
| 	# --- Making Lists and Tables | 	# --- Making Lists and Tables | ||||||
| 
 | 
 | ||||||
| 	def bgn_enumerate(self, args): | 	def bgn_enumerate(self, args): | ||||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Characters that are perfectly safe in filenames and hyperlinks | # Characters that are perfectly safe in filenames and hyperlinks | ||||||
| goodchars = string.letters + string.digits + '!@-_=+.' | goodchars = string.letters + string.digits + '!@-=+.' | ||||||
| 
 | 
 | ||||||
| # Replace characters that aren't perfectly safe by underscores | # Replace characters that aren't perfectly safe by dashes | ||||||
|  | # Underscores are bad since Cern HTTPD treats them as delimiters for | ||||||
|  | # encoding times, so you get mismatches if you compress your files: | ||||||
|  | # a.html.gz will map to a_b.html.gz | ||||||
| def fixfunnychars(addr): | def fixfunnychars(addr): | ||||||
| 	i = 0 | 	i = 0 | ||||||
| 	while i < len(addr): | 	while i < len(addr): | ||||||
| 		c = addr[i] | 		c = addr[i] | ||||||
| 		if c not in goodchars: | 		if c not in goodchars: | ||||||
| 			c = '_' | 			c = '-' | ||||||
| 			addr = addr[:i] + c + addr[i+1:] | 			addr = addr[:i] + c + addr[i+1:] | ||||||
| 		i = i + len(c) | 		i = i + len(c) | ||||||
| 	return addr | 	return addr | ||||||
|  | @ -1252,8 +1469,11 @@ def test(): | ||||||
| 	while sys.argv[1:2] == ['-d']: | 	while sys.argv[1:2] == ['-d']: | ||||||
| 		parser.debugging = parser.debugging + 1 | 		parser.debugging = parser.debugging + 1 | ||||||
| 		del sys.argv[1:2] | 		del sys.argv[1:2] | ||||||
|  | 	if sys.argv[1] == '-c': | ||||||
|  | 	    parser.cont = 1 | ||||||
|  | 	    del sys.argv[1] | ||||||
| 	if len(sys.argv) <> 3: | 	if len(sys.argv) <> 3: | ||||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||||
| 		sys.exit(2) | 		sys.exit(2) | ||||||
| 	file = sys.argv[1] | 	file = sys.argv[1] | ||||||
| 	parser.setdirname(sys.argv[2]) | 	parser.setdirname(sys.argv[2]) | ||||||
|  | @ -1272,3 +1492,9 @@ def test(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| test() | test() | ||||||
|  | 
 | ||||||
|  | # Emacs local variables | ||||||
|  | #  | ||||||
|  | # Local Variables: | ||||||
|  | # py-indent-offset: 8 | ||||||
|  | # End: | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| # Convert GNU texinfo files into HTML, one file per node. | # Convert GNU texinfo files into HTML, one file per node. | ||||||
| # Based on Texinfo 2.14. | # Based on Texinfo 2.14. | ||||||
| # Usage: texi2html [-d] [-d] inputfile outputdirectory | # Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory | ||||||
| # The input file must be a complete texinfo file, e.g. emacs.texi. | # The input file must be a complete texinfo file, e.g. emacs.texi. | ||||||
| # This creates many files (one per info node) in the output directory, | # This creates many files (one per info node) in the output directory, | ||||||
| # overwriting existing files of the same name.  All files created have | # overwriting existing files of the same name.  All files created have | ||||||
|  | @ -17,12 +17,23 @@ | ||||||
| # - handle @exdent properly | # - handle @exdent properly | ||||||
| # - add links directly to the proper line from indices | # - add links directly to the proper line from indices | ||||||
| # - check against the definitive list of @-cmds; we still miss (among others): | # - check against the definitive list of @-cmds; we still miss (among others): | ||||||
| # - @set, @clear, @ifset, @ifclear |  | ||||||
| # - @defindex (hard) | # - @defindex (hard) | ||||||
| # - @c(omment) in the middle of a line (rarely used) | # - @c(omment) in the middle of a line (rarely used) | ||||||
| # - @this* (not really needed, only used in headers anyway) | # - @this* (not really needed, only used in headers anyway) | ||||||
| # - @today{} (ever used outside title page?) | # - @today{} (ever used outside title page?) | ||||||
| 
 | 
 | ||||||
|  | # More consistent handling of chapters/sections/etc. | ||||||
|  | # Lots of documentation | ||||||
|  | # Many more options: | ||||||
|  | #	-top	designate top node | ||||||
|  | #	-links	customize which types of links are included | ||||||
|  | #	-split  split at chapters or sections instead of nodes | ||||||
|  | #	-name	Allow different types of filename handling. Non unix systems | ||||||
|  | #		will have problems with long node names | ||||||
|  | #	... | ||||||
|  | # Support the most recent texinfo version and take a good look at HTML 3.0 | ||||||
|  | # More debugging output (customizable) and more fexible error handling | ||||||
|  | # How about icons ? | ||||||
| 
 | 
 | ||||||
| import os | import os | ||||||
| import regex | import regex | ||||||
|  | @ -39,6 +50,81 @@ | ||||||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||||
| 					# menu item (Yuck!) | 					# menu item (Yuck!) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class Node: | ||||||
|  |     __doc__ = """ | ||||||
|  |     Some of the parser's functionality is separated into this class. | ||||||
|  | 
 | ||||||
|  |     A Node accumulates its contents, takes care of links to other Nodes | ||||||
|  |     and saves itself when it is finished and all links are resolved. """ | ||||||
|  |      | ||||||
|  |     def __init__ (self, dir, name, topname, title, next, prev, up): | ||||||
|  | 	self.dirname = dir | ||||||
|  | 	self.name = name | ||||||
|  | 	if topname: | ||||||
|  | 	    self.topname = topname | ||||||
|  | 	else: | ||||||
|  | 	    self.topname = name | ||||||
|  | 	self.title = title | ||||||
|  | 	self.next = next | ||||||
|  | 	self.prev = prev | ||||||
|  | 	self.up = up | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.type = 0 | ||||||
|  | 	self.cont = '' | ||||||
|  | 	 | ||||||
|  |     def write (self, *lines): | ||||||
|  | 	for line in lines: | ||||||
|  | 	    self.lines.append (line) | ||||||
|  | 
 | ||||||
|  |     def flush (self): | ||||||
|  | 	fp = open (self.dirname + '/' + makefile(self.name), 'w') | ||||||
|  | 	fp.write (self.prologue) | ||||||
|  | 	fp.write (self.text) | ||||||
|  | 	fp.write (self.epilogue) | ||||||
|  | 	fp.close () | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def link(self, label, nodename): | ||||||
|  | 	if nodename: | ||||||
|  | 	    if string.lower(nodename) == '(dir)': | ||||||
|  | 		addr = '../dir.html' | ||||||
|  | 	    else: | ||||||
|  | 		addr = makefile(nodename) | ||||||
|  | 	    self.write(label, ': <A HREF="', addr, '" TYPE="', \ | ||||||
|  | 		       label, '">', nodename, '</A>  \n') | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def finalize(self): | ||||||
|  | 	length = len (self.lines) | ||||||
|  | 	self.text = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.write ('<BR> <HR>\n') | ||||||
|  | 	if self.cont != self.next: | ||||||
|  | 	    self.link('Cont', self.cont) | ||||||
|  | 	self.link('Next', self.next) | ||||||
|  | 	self.link('Prev', self.prev) | ||||||
|  | 	self.link('Up', self.up) | ||||||
|  | 	if self.name <> self.topname: | ||||||
|  | 	    self.link('Top', self.topname) | ||||||
|  | 	self.write ('<BR> <HR> <P>\n') | ||||||
|  | 	links = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	 | ||||||
|  | 	self.prologue = \ | ||||||
|  | 		      '<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n' + \ | ||||||
|  | 		      '<!- Converted with texi2html and Python>\n' + \ | ||||||
|  | 		      '<P>\n<HEAD>\n' + \ | ||||||
|  | 		      '<TITLE>' + self.title + '</TITLE>\n' + \ | ||||||
|  | 		      '</HEAD>\n<BODY>\n<P>\n' + \ | ||||||
|  | 		      links | ||||||
|  | 	 | ||||||
|  | 	if length > 20: | ||||||
|  | 	    self.epilogue = links + '</BODY>\n' | ||||||
|  | 	else: | ||||||
|  | 	    self.epilogue = '</BODY>\n' | ||||||
|  | 	     | ||||||
|  | 
 | ||||||
| class TexinfoParser: | class TexinfoParser: | ||||||
| 
 | 
 | ||||||
| 	# Initialize an instance | 	# Initialize an instance | ||||||
|  | @ -50,6 +136,7 @@ def __init__(self): | ||||||
| 		self.nodelineno = 0	# Linenumber relative to node | 		self.nodelineno = 0	# Linenumber relative to node | ||||||
| 		self.links = None	# Links from current node | 		self.links = None	# Links from current node | ||||||
| 		self.savetext = None	# If not None, save text head instead | 		self.savetext = None	# If not None, save text head instead | ||||||
|  | 		self.savestack = []	# If not None, save text head instead | ||||||
| 		self.dirname = 'tmp'	# directory where files are created | 		self.dirname = 'tmp'	# directory where files are created | ||||||
| 		self.includedir = '.'	# directory to search @include files | 		self.includedir = '.'	# directory to search @include files | ||||||
| 		self.nodename = ''	# name of current node | 		self.nodename = ''	# name of current node | ||||||
|  | @ -59,14 +146,17 @@ def __init__(self): | ||||||
| 		self.contents = []	# Reset table of contents | 		self.contents = []	# Reset table of contents | ||||||
| 		self.numbering = []	# Reset section numbering counters | 		self.numbering = []	# Reset section numbering counters | ||||||
| 		self.nofill = 0		# Normal operation: fill paragraphs | 		self.nofill = 0		# Normal operation: fill paragraphs | ||||||
| 		self.goodset=['html']	# Names that should be parsed in ifset | 		self.values={'html': 1} # Names that should be parsed in ifset | ||||||
| 		self.stackinfo={}	# Keep track of state in the stack | 		self.stackinfo={}	# Keep track of state in the stack | ||||||
| 		# XXX The following should be reset per node?! | 		# XXX The following should be reset per node?! | ||||||
| 		self.footnotes = []	# Reset list of footnotes | 		self.footnotes = []	# Reset list of footnotes | ||||||
| 		self.itemarg = None	# Reset command used by @item | 		self.itemarg = None	# Reset command used by @item | ||||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||||
| 		self.itemindex = None	# Reset item index name | 		self.itemindex = None	# Reset item index name | ||||||
| 
 | 		self.node = None | ||||||
|  | 		self.nodestack = [] | ||||||
|  | 		self.cont = 0 | ||||||
|  | 		self.includedepth = 0 | ||||||
| 	# Set (output) directory name | 	# Set (output) directory name | ||||||
| 	def setdirname(self, dirname): | 	def setdirname(self, dirname): | ||||||
| 		self.dirname = dirname | 		self.dirname = dirname | ||||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | ||||||
| 		if self.stack: | 		if self.stack: | ||||||
| 			print '*** Stack not empty at the end' | 			print '*** Stack not empty at the end' | ||||||
| 			print '***', self.stack | 			print '***', self.stack | ||||||
|  | 		if self.includedepth == 0: | ||||||
|  | 		    while self.nodestack: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
| 
 | 
 | ||||||
| 	# Start saving text in a buffer instead of writing it to a file | 	# Start saving text in a buffer instead of writing it to a file | ||||||
| 	def startsaving(self): | 	def startsaving(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			print '*** Recursively saving text, expect trouble' | 			self.savestack.append (self.savetext) | ||||||
|  | 			# print '*** Recursively saving text, expect trouble' | ||||||
| 		self.savetext = '' | 		self.savetext = '' | ||||||
| 
 | 
 | ||||||
| 	# Return the text saved so far and start writing to file again | 	# Return the text saved so far and start writing to file again | ||||||
| 	def collectsavings(self): | 	def collectsavings(self): | ||||||
| 		savetext = self.savetext | 		savetext = self.savetext | ||||||
| 		self.savetext = None | 		if len (self.savestack) > 0: | ||||||
|  | 			self.savetext = self.savestack[-1] | ||||||
|  | 			del self.savestack[-1] | ||||||
|  | 		else: | ||||||
|  | 			self.savetext = None | ||||||
| 		return savetext or '' | 		return savetext or '' | ||||||
| 
 | 
 | ||||||
| 	# Write text to file, or save it in a buffer, or ignore it | 	# Write text to file, or save it in a buffer, or ignore it | ||||||
| 	def write(self, *args): | 	def write(self, *args): | ||||||
| 		text = string.joinfields(args, '') | 		try: | ||||||
|  | 			text = string.joinfields(args, '') | ||||||
|  | 		except: | ||||||
|  | 			print args | ||||||
|  | 			raise TypeError | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			self.savetext = self.savetext + text | 			self.savetext = self.savetext + text | ||||||
| 		elif self.nodefp: | 		elif self.nodefp: | ||||||
| 			self.nodefp.write(text) | 			self.nodefp.write(text) | ||||||
| 
 | 		elif self.node: | ||||||
|  | 		        self.node.write (text) | ||||||
| 	# Complete the current node -- write footnotes and close file | 	# Complete the current node -- write footnotes and close file | ||||||
| 	def endnode(self): | 	def endnode(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
|  | @ -172,7 +277,16 @@ def endnode(self): | ||||||
| 				self.write ('<HR>\n') | 				self.write ('<HR>\n') | ||||||
| 			self.write('</BODY>\n') | 			self.write('</BODY>\n') | ||||||
| 			self.nodefp.close() | 			self.nodefp.close() | ||||||
| 		self.nodefp = None | 			self.nodefp = None | ||||||
|  | 		elif self.node: | ||||||
|  | 		    if not self.cont and \ | ||||||
|  | 		       (not self.node.type or \ | ||||||
|  | 			(self.node.next and self.node.prev and self.node.up)): | ||||||
|  | 			self.node.finalize () | ||||||
|  | 			self.node.flush () | ||||||
|  | 		    else: | ||||||
|  | 			self.nodestack.append (self.node) | ||||||
|  | 		    self.node = None | ||||||
| 		self.nodename = '' | 		self.nodename = '' | ||||||
| 
 | 
 | ||||||
| 	# Process a list of lines, expanding embedded @-commands | 	# Process a list of lines, expanding embedded @-commands | ||||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | ||||||
| 		save_done = self.done | 		save_done = self.done | ||||||
| 		save_skip = self.skip | 		save_skip = self.skip | ||||||
| 		save_stack = self.stack | 		save_stack = self.stack | ||||||
|  | 		self.includedepth = self.includedepth + 1 | ||||||
| 		self.parserest(fp, 0) | 		self.parserest(fp, 0) | ||||||
|  | 		self.includedepth = self.includedepth - 1 | ||||||
| 		fp.close() | 		fp.close() | ||||||
| 		self.done = save_done | 		self.done = save_done | ||||||
| 		self.skip = save_skip | 		self.skip = save_skip | ||||||
|  | @ -364,7 +480,9 @@ def open_TeX(self): self.write('TeX') | ||||||
| 	def close_TeX(self): pass | 	def close_TeX(self): pass | ||||||
| 
 | 
 | ||||||
| 	def handle_copyright(self): self.write('(C)') | 	def handle_copyright(self): self.write('(C)') | ||||||
| 
 | 	def open_copyright(self): self.write('(C)') | ||||||
|  | 	def close_copyright(self): pass | ||||||
|  | 		 | ||||||
| 	def open_minus(self): self.write('-') | 	def open_minus(self): self.write('-') | ||||||
| 	def close_minus(self): pass | 	def close_minus(self): pass | ||||||
| 
 | 
 | ||||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | ||||||
| 	close_i = close_emph | 	close_i = close_emph | ||||||
| 
 | 
 | ||||||
| 	def open_footnote(self): | 	def open_footnote(self): | ||||||
| 		if self.savetext <> None: | 		# if self.savetext <> None: | ||||||
| 			print '*** Recursive footnote -- expect weirdness' | 		# 	print '*** Recursive footnote -- expect weirdness' | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.write('<A NAME="footnoteref', `id`, \ | 		self.write('<A NAME="footnoteref', `id`, \ | ||||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||||
| 		self.savetext = '' | 		# self.savetext = '' | ||||||
|  | 		self.startsaving () | ||||||
| 
 | 
 | ||||||
| 	def close_footnote(self): | 	def close_footnote(self): | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.footnotes.append(`id`, self.savetext) | 		# self.footnotes.append(`id`, self.savetext) | ||||||
| 		self.savetext = None | 		self.footnotes.append(`id`, self.collectsavings()) | ||||||
|  | 		# self.savetext = None | ||||||
| 
 | 
 | ||||||
| 	def writefootnotes(self): | 	def writefootnotes(self): | ||||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||||
|  | @ -534,7 +654,9 @@ def command(self, line): | ||||||
| 			try: | 			try: | ||||||
| 				func = getattr(self, 'bgn_' + cmd) | 				func = getattr(self, 'bgn_' + cmd) | ||||||
| 			except AttributeError: | 			except AttributeError: | ||||||
| 				self.unknown_cmd(cmd, args) | 				# don't complain if we are skipping anyway | ||||||
|  | 				if not self.skip: | ||||||
|  | 					self.unknown_cmd(cmd, args) | ||||||
| 				return | 				return | ||||||
| 			self.stack.append(cmd) | 			self.stack.append(cmd) | ||||||
| 			func(args) | 			func(args) | ||||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): self.skip = self.skip - 1 | ||||||
| 	def bgn_tex(self, args): self.skip = self.skip + 1 | 	def bgn_tex(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_tex(self): self.skip = self.skip - 1 | 	def end_tex(self): self.skip = self.skip - 1 | ||||||
| 
 | 
 | ||||||
| 	def bgn_set(self, args): | 	def do_set(self, args): | ||||||
| 		if args not in self.goodset: | 		fields = string.splitfields (args, ' ') | ||||||
| 			self.gooset.append(args) | 		key = fields[0] | ||||||
|  | 		if len(fields) == 1: | ||||||
|  | 			value = 1 | ||||||
|  | 		else: | ||||||
|  | 			value = string.joinfields (fields[1:], ' ') | ||||||
|  | 		self.values[key]=value | ||||||
|  | 		print self.values | ||||||
| 			 | 			 | ||||||
| 	def bgn_clear(self, args): | 	def do_clear(self, args): | ||||||
| 		if args in self.goodset: | 		self.values[args] = None | ||||||
| 			self.gooset.remove(args) |  | ||||||
| 			 | 			 | ||||||
| 	def bgn_ifset(self, args): | 	def bgn_ifset(self, args): | ||||||
| 		if args not in self.goodset: | 		if args not in self.values.keys() \ | ||||||
|  | 		   or self.values[args] is None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
|  | @ -615,14 +743,25 @@ def end_ifset(self): | ||||||
| 		del self.stackinfo[len(self.stack) + 1] | 		del self.stackinfo[len(self.stack) + 1] | ||||||
| 
 | 
 | ||||||
| 	def bgn_ifclear(self, args): | 	def bgn_ifclear(self, args): | ||||||
| 		if args in self.goodset: | 		if args in self.values.keys() \ | ||||||
|  | 		   and self.values[args] is not None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
| 			self.stackinfo[len(self.stack)] = 0 | 			self.stackinfo[len(self.stack)] = 0 | ||||||
| 		 | 		 | ||||||
| 	end_ifclear = end_ifset | 	end_ifclear = end_ifset | ||||||
| 	 | 
 | ||||||
|  | 	def open_value(self): | ||||||
|  | 		self.startsaving() | ||||||
|  | 
 | ||||||
|  | 	def close_value(self): | ||||||
|  | 		key = self.collectsavings () | ||||||
|  | 		if key in self.values.keys(): | ||||||
|  | 			self.write (self.values[key]) | ||||||
|  | 		else: | ||||||
|  | 			print '*** Undefined value: ', key | ||||||
|  | 		        | ||||||
| 	# --- Beginning a file --- | 	# --- Beginning a file --- | ||||||
| 
 | 
 | ||||||
| 	do_finalout = do_comment | 	do_finalout = do_comment | ||||||
|  | @ -630,20 +769,25 @@ def bgn_ifclear(self, args): | ||||||
| 	do_setfilename = do_comment | 	do_setfilename = do_comment | ||||||
| 
 | 
 | ||||||
| 	def do_settitle(self, args): | 	def do_settitle(self, args): | ||||||
| 		self.title = args | 		print args | ||||||
| 
 | 		self.startsaving() | ||||||
|  | 		self.expand (args) | ||||||
|  | 		self.title = self.collectsavings () | ||||||
|  | 		print self.title | ||||||
| 	def do_parskip(self, args): pass | 	def do_parskip(self, args): pass | ||||||
| 	 | 	 | ||||||
| 	# --- Ending a file --- | 	# --- Ending a file --- | ||||||
| 
 | 
 | ||||||
| 	def do_bye(self, args): | 	def do_bye(self, args): | ||||||
|  | 		self.endnode () | ||||||
| 		self.done = 1 | 		self.done = 1 | ||||||
| 
 | 
 | ||||||
| 	# --- Title page --- | 	# --- Title page --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_titlepage(self): self.skip = self.skip - 1 | 	def end_titlepage(self): self.skip = self.skip - 1 | ||||||
| 
 | 	def do_shorttitlepage(self, args): pass | ||||||
|  | 	 | ||||||
| 	def do_center(self, args): | 	def do_center(self, args): | ||||||
| 		# Actually not used outside title page... | 		# Actually not used outside title page... | ||||||
| 		self.write('<H1>') | 		self.write('<H1>') | ||||||
|  | @ -685,24 +829,28 @@ def do_node(self, args): | ||||||
| 		else: | 		else: | ||||||
| 			if self.debugging: print '--- writing', file | 			if self.debugging: print '--- writing', file | ||||||
| 		self.filenames[file] = 1 | 		self.filenames[file] = 1 | ||||||
| 		self.nodefp = open(file, 'w') | 		# self.nodefp = open(file, 'w') | ||||||
| 		self.nodename = name | 		self.nodename = name | ||||||
|  | 		if self.cont and self.nodestack: | ||||||
|  | 		    self.nodestack[-1].cont = self.nodename | ||||||
| 		if not self.topname: self.topname = name | 		if not self.topname: self.topname = name | ||||||
| 		title = name | 		title = name | ||||||
| 		if self.title: title = title + ' -- ' + self.title | 		if self.title: title = title + ' -- ' + self.title | ||||||
| 		# No idea what this means, but this is what latex2html writes | 		# No idea what this means, but this is what latex2html writes | ||||||
| 		self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||||
| 		self.write('<!- Converted with texi2html and Python>\n') | 		# self.write('<!- Converted with texi2html and Python>\n') | ||||||
| 		self.write ('<P>\n<HEAD>\n') | 		# self.write ('<P>\n<HEAD>\n') | ||||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||||
| 		self.link('Next', next) | 		# self.link('Next', next) | ||||||
| 		self.link('Prev', prev) | 		# self.link('Prev', prev) | ||||||
| 		self.link('Up', up) | 		# self.link('Up', up) | ||||||
| 		if self.nodename <> self.topname: | 		# if self.nodename <> self.topname: | ||||||
| 			self.link('Top', self.topname) | 		# 	self.link('Top', self.topname) | ||||||
| 		self.write ('<BR> <HR> <P>\n') | 		# self.write ('<BR> <HR> <P>\n') | ||||||
| 
 | 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||||
|  | 				  title, next, prev, up) | ||||||
|  | 		 | ||||||
| 	def link(self, label, nodename): | 	def link(self, label, nodename): | ||||||
| 		if nodename: | 		if nodename: | ||||||
| 			if string.lower(nodename) == '(dir)': | 			if string.lower(nodename) == '(dir)': | ||||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | ||||||
| 
 | 
 | ||||||
| 	# --- Sectioning commands --- | 	# --- Sectioning commands --- | ||||||
| 
 | 
 | ||||||
|  | 	def popstack (self, type): | ||||||
|  | 	    if (self.node): | ||||||
|  | 		self.node.type = type | ||||||
|  | 		while self.nodestack: | ||||||
|  | 		    if self.nodestack[-1].type > type: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    elif self.nodestack[-1].type == type: | ||||||
|  | 			if not self.nodestack[-1].next: | ||||||
|  | 			    self.nodestack[-1].next = self.node.name | ||||||
|  | 			if not self.node.prev: | ||||||
|  | 			    self.node.prev = self.nodestack[-1].name | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    else: | ||||||
|  | 			if type > 1 and not self.node.up: | ||||||
|  | 			    self.node.up = self.nodestack[-1].name | ||||||
|  | 			break | ||||||
|  | 
 | ||||||
| 	def do_chapter(self, args): | 	def do_chapter(self, args): | ||||||
| 		self.heading('H1', args, 0) | 		self.heading('H1', args, 0) | ||||||
|  | 		self.popstack (1) | ||||||
|  | 
 | ||||||
| 	def do_unnumbered(self, args): | 	def do_unnumbered(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_appendix(self, args): | 	def do_appendix(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_top(self, args): | 	def do_top(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 	def do_chapheading(self, args): | 	def do_chapheading(self, args): | ||||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | ||||||
| 
 | 
 | ||||||
| 	def do_section(self, args): | 	def do_section(self, args): | ||||||
| 		self.heading('H1', args, 1) | 		self.heading('H1', args, 1) | ||||||
|  | 		self.popstack (2) | ||||||
|  | 
 | ||||||
| 	def do_unnumberedsec(self, args): | 	def do_unnumberedsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	def do_appendixsec(self, args): | 	def do_appendixsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	do_appendixsection = do_appendixsec | 	do_appendixsection = do_appendixsec | ||||||
| 	def do_heading(self, args): | 	def do_heading(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsection(self, args): | 	def do_subsection(self, args): | ||||||
| 		self.heading('H2', args, 2) | 		self.heading('H2', args, 2) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_unnumberedsubsec(self, args): | 	def do_unnumberedsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_appendixsubsec(self, args): | 	def do_appendixsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_subheading(self, args): | 	def do_subheading(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsubsection(self, args): | 	def do_subsubsection(self, args): | ||||||
| 		self.heading('H3', args, 3) | 		self.heading('H3', args, 3) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_unnumberedsubsubsec(self, args): | 	def do_unnumberedsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_appendixsubsubsec(self, args): | 	def do_appendixsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_subsubheading(self, args): | 	def do_subsubheading(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
| 
 | 
 | ||||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | ||||||
| 			print '---', args | 			print '---', args | ||||||
| 
 | 
 | ||||||
| 	def do_contents(self, args): | 	def do_contents(self, args): | ||||||
| 		pass | 	        # pass | ||||||
| 		# self.listcontents('Table of Contents', 999) | 		self.listcontents('Table of Contents', 999) | ||||||
| 
 | 
 | ||||||
| 	def do_shortcontents(self, args): | 	def do_shortcontents(self, args): | ||||||
| 		pass | 		pass | ||||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | ||||||
| 	# --- Function and variable definitions --- | 	# --- Function and variable definitions --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deffn(self, args): | 	def bgn_deffn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
| 		words = splitwords(args, 2) | 		self.do_deffnx (args) | ||||||
| 		[category, name], rest = words[:2], words[2:] |  | ||||||
| 		self.expand('@b{' + name + '}') |  | ||||||
| 		for word in rest: self.expand(' ' + makevar(word)) |  | ||||||
| 		self.expand(' -- ' + category) |  | ||||||
| 		self.write('<DD>\n') |  | ||||||
| 		self.index('fn', name) |  | ||||||
| 
 | 
 | ||||||
| 	def end_deffn(self): | 	def end_deffn(self): | ||||||
| 		self.write('</DL>\n') | 		self.write('</DL>\n') | ||||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | ||||||
| 
 | 
 | ||||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||||
| 	end_defun = end_deffn | 	end_defun = end_deffn | ||||||
|  | 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||||
| 	end_defmac = end_deffn | 	end_defmac = end_deffn | ||||||
|  | 	def do_defmacx(self, args): self.do_deffnx('Macro ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | ||||||
| 	end_defspec = end_deffn | 	end_defspec = end_deffn | ||||||
|  | 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defvr(self, args): | 	def bgn_defvr(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defvrx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defvr = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_defvrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@code{' + name + '}') | 		self.expand('@code{' + name + '}') | ||||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name) | 		self.index('vr', name) | ||||||
| 
 | 
 | ||||||
| 	end_defvr = end_deffn |  | ||||||
| 
 |  | ||||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||||
| 	end_defvar = end_defvr | 	end_defvar = end_defvr | ||||||
|  | 	def do_defvarx(self, args): self.do_defvrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | ||||||
| 	end_defopt = end_defvr | 	end_defopt = end_defvr | ||||||
|  | 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for typed languages --- | 	# --- Ditto for typed languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefn(self, args): | 	def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypefnx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypefn = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypefnx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypefn = end_deffn |  | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||||
| 	end_deftypefun = end_deftypefn | 	end_deftypefun = end_deftypefn | ||||||
|  | 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypevr(self, args): | 	def bgn_deftypevr(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypevrx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypevr = end_deftypefn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypevrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypevr = end_deftypefn |  | ||||||
| 
 |  | ||||||
| 	def bgn_deftypevar(self, args): | 	def bgn_deftypevar(self, args): | ||||||
| 		self.bgn_deftypevr('Variable ' + args) | 		self.bgn_deftypevr('Variable ' + args) | ||||||
| 	end_deftypevar = end_deftypevr | 	end_deftypevar = end_deftypevr | ||||||
|  | 	def do_deftypevarx(self, args): | ||||||
|  | 		self.do_deftypevrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for object-oriented languages --- | 	# --- Ditto for object-oriented languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_defcv(self, args): | 	def bgn_defcv(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_defcvx(args) | ||||||
|  | 
 | ||||||
|  | 	end_defcv = end_deftypevr | ||||||
|  | 
 | ||||||
|  | 	def do_defcvx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defcv = end_deftypevr |  | ||||||
| 
 |  | ||||||
| 	def bgn_defivar(self, args): | 	def bgn_defivar(self, args): | ||||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | 		self.bgn_defcv('{Instance Variable} ' + args) | ||||||
| 	end_defivar = end_defcv | 	end_defivar = end_defcv | ||||||
|  | 	def do_defivarx(self, args): | ||||||
|  | 		self.do_defcvx('{Instance Variable} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defop(self, args): | 	def bgn_defop(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defopx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defop = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_defopx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defop = end_defcv |  | ||||||
| 
 |  | ||||||
| 	def bgn_defmethod(self, args): | 	def bgn_defmethod(self, args): | ||||||
| 		self.bgn_defop('Method ' + args) | 		self.bgn_defop('Method ' + args) | ||||||
| 	end_defmethod = end_defop | 	end_defmethod = end_defop | ||||||
|  | 	def do_defmethodx(self, args): | ||||||
|  | 		self.do_defopx('Method ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for data types --- | 	# --- Ditto for data types --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftp(self, args): | 	def bgn_deftp(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftpx(args) | ||||||
|  | 
 | ||||||
|  | 	end_deftp = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_deftpx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('tp', name) | 		self.index('tp', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftp = end_defcv |  | ||||||
| 
 |  | ||||||
| 	# --- Making Lists and Tables | 	# --- Making Lists and Tables | ||||||
| 
 | 
 | ||||||
| 	def bgn_enumerate(self, args): | 	def bgn_enumerate(self, args): | ||||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Characters that are perfectly safe in filenames and hyperlinks | # Characters that are perfectly safe in filenames and hyperlinks | ||||||
| goodchars = string.letters + string.digits + '!@-_=+.' | goodchars = string.letters + string.digits + '!@-=+.' | ||||||
| 
 | 
 | ||||||
| # Replace characters that aren't perfectly safe by underscores | # Replace characters that aren't perfectly safe by dashes | ||||||
|  | # Underscores are bad since Cern HTTPD treats them as delimiters for | ||||||
|  | # encoding times, so you get mismatches if you compress your files: | ||||||
|  | # a.html.gz will map to a_b.html.gz | ||||||
| def fixfunnychars(addr): | def fixfunnychars(addr): | ||||||
| 	i = 0 | 	i = 0 | ||||||
| 	while i < len(addr): | 	while i < len(addr): | ||||||
| 		c = addr[i] | 		c = addr[i] | ||||||
| 		if c not in goodchars: | 		if c not in goodchars: | ||||||
| 			c = '_' | 			c = '-' | ||||||
| 			addr = addr[:i] + c + addr[i+1:] | 			addr = addr[:i] + c + addr[i+1:] | ||||||
| 		i = i + len(c) | 		i = i + len(c) | ||||||
| 	return addr | 	return addr | ||||||
|  | @ -1252,8 +1469,11 @@ def test(): | ||||||
| 	while sys.argv[1:2] == ['-d']: | 	while sys.argv[1:2] == ['-d']: | ||||||
| 		parser.debugging = parser.debugging + 1 | 		parser.debugging = parser.debugging + 1 | ||||||
| 		del sys.argv[1:2] | 		del sys.argv[1:2] | ||||||
|  | 	if sys.argv[1] == '-c': | ||||||
|  | 	    parser.cont = 1 | ||||||
|  | 	    del sys.argv[1] | ||||||
| 	if len(sys.argv) <> 3: | 	if len(sys.argv) <> 3: | ||||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||||
| 		sys.exit(2) | 		sys.exit(2) | ||||||
| 	file = sys.argv[1] | 	file = sys.argv[1] | ||||||
| 	parser.setdirname(sys.argv[2]) | 	parser.setdirname(sys.argv[2]) | ||||||
|  | @ -1272,3 +1492,9 @@ def test(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| test() | test() | ||||||
|  | 
 | ||||||
|  | # Emacs local variables | ||||||
|  | #  | ||||||
|  | # Local Variables: | ||||||
|  | # py-indent-offset: 8 | ||||||
|  | # End: | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| # Convert GNU texinfo files into HTML, one file per node. | # Convert GNU texinfo files into HTML, one file per node. | ||||||
| # Based on Texinfo 2.14. | # Based on Texinfo 2.14. | ||||||
| # Usage: texi2html [-d] [-d] inputfile outputdirectory | # Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory | ||||||
| # The input file must be a complete texinfo file, e.g. emacs.texi. | # The input file must be a complete texinfo file, e.g. emacs.texi. | ||||||
| # This creates many files (one per info node) in the output directory, | # This creates many files (one per info node) in the output directory, | ||||||
| # overwriting existing files of the same name.  All files created have | # overwriting existing files of the same name.  All files created have | ||||||
|  | @ -17,12 +17,23 @@ | ||||||
| # - handle @exdent properly | # - handle @exdent properly | ||||||
| # - add links directly to the proper line from indices | # - add links directly to the proper line from indices | ||||||
| # - check against the definitive list of @-cmds; we still miss (among others): | # - check against the definitive list of @-cmds; we still miss (among others): | ||||||
| # - @set, @clear, @ifset, @ifclear |  | ||||||
| # - @defindex (hard) | # - @defindex (hard) | ||||||
| # - @c(omment) in the middle of a line (rarely used) | # - @c(omment) in the middle of a line (rarely used) | ||||||
| # - @this* (not really needed, only used in headers anyway) | # - @this* (not really needed, only used in headers anyway) | ||||||
| # - @today{} (ever used outside title page?) | # - @today{} (ever used outside title page?) | ||||||
| 
 | 
 | ||||||
|  | # More consistent handling of chapters/sections/etc. | ||||||
|  | # Lots of documentation | ||||||
|  | # Many more options: | ||||||
|  | #	-top	designate top node | ||||||
|  | #	-links	customize which types of links are included | ||||||
|  | #	-split  split at chapters or sections instead of nodes | ||||||
|  | #	-name	Allow different types of filename handling. Non unix systems | ||||||
|  | #		will have problems with long node names | ||||||
|  | #	... | ||||||
|  | # Support the most recent texinfo version and take a good look at HTML 3.0 | ||||||
|  | # More debugging output (customizable) and more fexible error handling | ||||||
|  | # How about icons ? | ||||||
| 
 | 
 | ||||||
| import os | import os | ||||||
| import regex | import regex | ||||||
|  | @ -39,6 +50,81 @@ | ||||||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||||
| 					# menu item (Yuck!) | 					# menu item (Yuck!) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class Node: | ||||||
|  |     __doc__ = """ | ||||||
|  |     Some of the parser's functionality is separated into this class. | ||||||
|  | 
 | ||||||
|  |     A Node accumulates its contents, takes care of links to other Nodes | ||||||
|  |     and saves itself when it is finished and all links are resolved. """ | ||||||
|  |      | ||||||
|  |     def __init__ (self, dir, name, topname, title, next, prev, up): | ||||||
|  | 	self.dirname = dir | ||||||
|  | 	self.name = name | ||||||
|  | 	if topname: | ||||||
|  | 	    self.topname = topname | ||||||
|  | 	else: | ||||||
|  | 	    self.topname = name | ||||||
|  | 	self.title = title | ||||||
|  | 	self.next = next | ||||||
|  | 	self.prev = prev | ||||||
|  | 	self.up = up | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.type = 0 | ||||||
|  | 	self.cont = '' | ||||||
|  | 	 | ||||||
|  |     def write (self, *lines): | ||||||
|  | 	for line in lines: | ||||||
|  | 	    self.lines.append (line) | ||||||
|  | 
 | ||||||
|  |     def flush (self): | ||||||
|  | 	fp = open (self.dirname + '/' + makefile(self.name), 'w') | ||||||
|  | 	fp.write (self.prologue) | ||||||
|  | 	fp.write (self.text) | ||||||
|  | 	fp.write (self.epilogue) | ||||||
|  | 	fp.close () | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def link(self, label, nodename): | ||||||
|  | 	if nodename: | ||||||
|  | 	    if string.lower(nodename) == '(dir)': | ||||||
|  | 		addr = '../dir.html' | ||||||
|  | 	    else: | ||||||
|  | 		addr = makefile(nodename) | ||||||
|  | 	    self.write(label, ': <A HREF="', addr, '" TYPE="', \ | ||||||
|  | 		       label, '">', nodename, '</A>  \n') | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def finalize(self): | ||||||
|  | 	length = len (self.lines) | ||||||
|  | 	self.text = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	self.write ('<BR> <HR>\n') | ||||||
|  | 	if self.cont != self.next: | ||||||
|  | 	    self.link('Cont', self.cont) | ||||||
|  | 	self.link('Next', self.next) | ||||||
|  | 	self.link('Prev', self.prev) | ||||||
|  | 	self.link('Up', self.up) | ||||||
|  | 	if self.name <> self.topname: | ||||||
|  | 	    self.link('Top', self.topname) | ||||||
|  | 	self.write ('<BR> <HR> <P>\n') | ||||||
|  | 	links = string.joinfields (self.lines, '') | ||||||
|  | 	self.lines = [] | ||||||
|  | 	 | ||||||
|  | 	self.prologue = \ | ||||||
|  | 		      '<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n' + \ | ||||||
|  | 		      '<!- Converted with texi2html and Python>\n' + \ | ||||||
|  | 		      '<P>\n<HEAD>\n' + \ | ||||||
|  | 		      '<TITLE>' + self.title + '</TITLE>\n' + \ | ||||||
|  | 		      '</HEAD>\n<BODY>\n<P>\n' + \ | ||||||
|  | 		      links | ||||||
|  | 	 | ||||||
|  | 	if length > 20: | ||||||
|  | 	    self.epilogue = links + '</BODY>\n' | ||||||
|  | 	else: | ||||||
|  | 	    self.epilogue = '</BODY>\n' | ||||||
|  | 	     | ||||||
|  | 
 | ||||||
| class TexinfoParser: | class TexinfoParser: | ||||||
| 
 | 
 | ||||||
| 	# Initialize an instance | 	# Initialize an instance | ||||||
|  | @ -50,6 +136,7 @@ def __init__(self): | ||||||
| 		self.nodelineno = 0	# Linenumber relative to node | 		self.nodelineno = 0	# Linenumber relative to node | ||||||
| 		self.links = None	# Links from current node | 		self.links = None	# Links from current node | ||||||
| 		self.savetext = None	# If not None, save text head instead | 		self.savetext = None	# If not None, save text head instead | ||||||
|  | 		self.savestack = []	# If not None, save text head instead | ||||||
| 		self.dirname = 'tmp'	# directory where files are created | 		self.dirname = 'tmp'	# directory where files are created | ||||||
| 		self.includedir = '.'	# directory to search @include files | 		self.includedir = '.'	# directory to search @include files | ||||||
| 		self.nodename = ''	# name of current node | 		self.nodename = ''	# name of current node | ||||||
|  | @ -59,14 +146,17 @@ def __init__(self): | ||||||
| 		self.contents = []	# Reset table of contents | 		self.contents = []	# Reset table of contents | ||||||
| 		self.numbering = []	# Reset section numbering counters | 		self.numbering = []	# Reset section numbering counters | ||||||
| 		self.nofill = 0		# Normal operation: fill paragraphs | 		self.nofill = 0		# Normal operation: fill paragraphs | ||||||
| 		self.goodset=['html']	# Names that should be parsed in ifset | 		self.values={'html': 1} # Names that should be parsed in ifset | ||||||
| 		self.stackinfo={}	# Keep track of state in the stack | 		self.stackinfo={}	# Keep track of state in the stack | ||||||
| 		# XXX The following should be reset per node?! | 		# XXX The following should be reset per node?! | ||||||
| 		self.footnotes = []	# Reset list of footnotes | 		self.footnotes = []	# Reset list of footnotes | ||||||
| 		self.itemarg = None	# Reset command used by @item | 		self.itemarg = None	# Reset command used by @item | ||||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||||
| 		self.itemindex = None	# Reset item index name | 		self.itemindex = None	# Reset item index name | ||||||
| 
 | 		self.node = None | ||||||
|  | 		self.nodestack = [] | ||||||
|  | 		self.cont = 0 | ||||||
|  | 		self.includedepth = 0 | ||||||
| 	# Set (output) directory name | 	# Set (output) directory name | ||||||
| 	def setdirname(self, dirname): | 	def setdirname(self, dirname): | ||||||
| 		self.dirname = dirname | 		self.dirname = dirname | ||||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | ||||||
| 		if self.stack: | 		if self.stack: | ||||||
| 			print '*** Stack not empty at the end' | 			print '*** Stack not empty at the end' | ||||||
| 			print '***', self.stack | 			print '***', self.stack | ||||||
|  | 		if self.includedepth == 0: | ||||||
|  | 		    while self.nodestack: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
| 
 | 
 | ||||||
| 	# Start saving text in a buffer instead of writing it to a file | 	# Start saving text in a buffer instead of writing it to a file | ||||||
| 	def startsaving(self): | 	def startsaving(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			print '*** Recursively saving text, expect trouble' | 			self.savestack.append (self.savetext) | ||||||
|  | 			# print '*** Recursively saving text, expect trouble' | ||||||
| 		self.savetext = '' | 		self.savetext = '' | ||||||
| 
 | 
 | ||||||
| 	# Return the text saved so far and start writing to file again | 	# Return the text saved so far and start writing to file again | ||||||
| 	def collectsavings(self): | 	def collectsavings(self): | ||||||
| 		savetext = self.savetext | 		savetext = self.savetext | ||||||
| 		self.savetext = None | 		if len (self.savestack) > 0: | ||||||
|  | 			self.savetext = self.savestack[-1] | ||||||
|  | 			del self.savestack[-1] | ||||||
|  | 		else: | ||||||
|  | 			self.savetext = None | ||||||
| 		return savetext or '' | 		return savetext or '' | ||||||
| 
 | 
 | ||||||
| 	# Write text to file, or save it in a buffer, or ignore it | 	# Write text to file, or save it in a buffer, or ignore it | ||||||
| 	def write(self, *args): | 	def write(self, *args): | ||||||
| 		text = string.joinfields(args, '') | 		try: | ||||||
|  | 			text = string.joinfields(args, '') | ||||||
|  | 		except: | ||||||
|  | 			print args | ||||||
|  | 			raise TypeError | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
| 			self.savetext = self.savetext + text | 			self.savetext = self.savetext + text | ||||||
| 		elif self.nodefp: | 		elif self.nodefp: | ||||||
| 			self.nodefp.write(text) | 			self.nodefp.write(text) | ||||||
| 
 | 		elif self.node: | ||||||
|  | 		        self.node.write (text) | ||||||
| 	# Complete the current node -- write footnotes and close file | 	# Complete the current node -- write footnotes and close file | ||||||
| 	def endnode(self): | 	def endnode(self): | ||||||
| 		if self.savetext <> None: | 		if self.savetext <> None: | ||||||
|  | @ -172,7 +277,16 @@ def endnode(self): | ||||||
| 				self.write ('<HR>\n') | 				self.write ('<HR>\n') | ||||||
| 			self.write('</BODY>\n') | 			self.write('</BODY>\n') | ||||||
| 			self.nodefp.close() | 			self.nodefp.close() | ||||||
| 		self.nodefp = None | 			self.nodefp = None | ||||||
|  | 		elif self.node: | ||||||
|  | 		    if not self.cont and \ | ||||||
|  | 		       (not self.node.type or \ | ||||||
|  | 			(self.node.next and self.node.prev and self.node.up)): | ||||||
|  | 			self.node.finalize () | ||||||
|  | 			self.node.flush () | ||||||
|  | 		    else: | ||||||
|  | 			self.nodestack.append (self.node) | ||||||
|  | 		    self.node = None | ||||||
| 		self.nodename = '' | 		self.nodename = '' | ||||||
| 
 | 
 | ||||||
| 	# Process a list of lines, expanding embedded @-commands | 	# Process a list of lines, expanding embedded @-commands | ||||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | ||||||
| 		save_done = self.done | 		save_done = self.done | ||||||
| 		save_skip = self.skip | 		save_skip = self.skip | ||||||
| 		save_stack = self.stack | 		save_stack = self.stack | ||||||
|  | 		self.includedepth = self.includedepth + 1 | ||||||
| 		self.parserest(fp, 0) | 		self.parserest(fp, 0) | ||||||
|  | 		self.includedepth = self.includedepth - 1 | ||||||
| 		fp.close() | 		fp.close() | ||||||
| 		self.done = save_done | 		self.done = save_done | ||||||
| 		self.skip = save_skip | 		self.skip = save_skip | ||||||
|  | @ -364,7 +480,9 @@ def open_TeX(self): self.write('TeX') | ||||||
| 	def close_TeX(self): pass | 	def close_TeX(self): pass | ||||||
| 
 | 
 | ||||||
| 	def handle_copyright(self): self.write('(C)') | 	def handle_copyright(self): self.write('(C)') | ||||||
| 
 | 	def open_copyright(self): self.write('(C)') | ||||||
|  | 	def close_copyright(self): pass | ||||||
|  | 		 | ||||||
| 	def open_minus(self): self.write('-') | 	def open_minus(self): self.write('-') | ||||||
| 	def close_minus(self): pass | 	def close_minus(self): pass | ||||||
| 
 | 
 | ||||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | ||||||
| 	close_i = close_emph | 	close_i = close_emph | ||||||
| 
 | 
 | ||||||
| 	def open_footnote(self): | 	def open_footnote(self): | ||||||
| 		if self.savetext <> None: | 		# if self.savetext <> None: | ||||||
| 			print '*** Recursive footnote -- expect weirdness' | 		# 	print '*** Recursive footnote -- expect weirdness' | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.write('<A NAME="footnoteref', `id`, \ | 		self.write('<A NAME="footnoteref', `id`, \ | ||||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||||
| 		self.savetext = '' | 		# self.savetext = '' | ||||||
|  | 		self.startsaving () | ||||||
| 
 | 
 | ||||||
| 	def close_footnote(self): | 	def close_footnote(self): | ||||||
| 		id = len(self.footnotes) + 1 | 		id = len(self.footnotes) + 1 | ||||||
| 		self.footnotes.append(`id`, self.savetext) | 		# self.footnotes.append(`id`, self.savetext) | ||||||
| 		self.savetext = None | 		self.footnotes.append(`id`, self.collectsavings()) | ||||||
|  | 		# self.savetext = None | ||||||
| 
 | 
 | ||||||
| 	def writefootnotes(self): | 	def writefootnotes(self): | ||||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||||
|  | @ -534,7 +654,9 @@ def command(self, line): | ||||||
| 			try: | 			try: | ||||||
| 				func = getattr(self, 'bgn_' + cmd) | 				func = getattr(self, 'bgn_' + cmd) | ||||||
| 			except AttributeError: | 			except AttributeError: | ||||||
| 				self.unknown_cmd(cmd, args) | 				# don't complain if we are skipping anyway | ||||||
|  | 				if not self.skip: | ||||||
|  | 					self.unknown_cmd(cmd, args) | ||||||
| 				return | 				return | ||||||
| 			self.stack.append(cmd) | 			self.stack.append(cmd) | ||||||
| 			func(args) | 			func(args) | ||||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): self.skip = self.skip - 1 | ||||||
| 	def bgn_tex(self, args): self.skip = self.skip + 1 | 	def bgn_tex(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_tex(self): self.skip = self.skip - 1 | 	def end_tex(self): self.skip = self.skip - 1 | ||||||
| 
 | 
 | ||||||
| 	def bgn_set(self, args): | 	def do_set(self, args): | ||||||
| 		if args not in self.goodset: | 		fields = string.splitfields (args, ' ') | ||||||
| 			self.gooset.append(args) | 		key = fields[0] | ||||||
|  | 		if len(fields) == 1: | ||||||
|  | 			value = 1 | ||||||
|  | 		else: | ||||||
|  | 			value = string.joinfields (fields[1:], ' ') | ||||||
|  | 		self.values[key]=value | ||||||
|  | 		print self.values | ||||||
| 			 | 			 | ||||||
| 	def bgn_clear(self, args): | 	def do_clear(self, args): | ||||||
| 		if args in self.goodset: | 		self.values[args] = None | ||||||
| 			self.gooset.remove(args) |  | ||||||
| 			 | 			 | ||||||
| 	def bgn_ifset(self, args): | 	def bgn_ifset(self, args): | ||||||
| 		if args not in self.goodset: | 		if args not in self.values.keys() \ | ||||||
|  | 		   or self.values[args] is None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
|  | @ -615,14 +743,25 @@ def end_ifset(self): | ||||||
| 		del self.stackinfo[len(self.stack) + 1] | 		del self.stackinfo[len(self.stack) + 1] | ||||||
| 
 | 
 | ||||||
| 	def bgn_ifclear(self, args): | 	def bgn_ifclear(self, args): | ||||||
| 		if args in self.goodset: | 		if args in self.values.keys() \ | ||||||
|  | 		   and self.values[args] is not None: | ||||||
| 			self.skip = self.skip + 1 | 			self.skip = self.skip + 1 | ||||||
| 			self.stackinfo[len(self.stack)] = 1 | 			self.stackinfo[len(self.stack)] = 1 | ||||||
| 		else: | 		else: | ||||||
| 			self.stackinfo[len(self.stack)] = 0 | 			self.stackinfo[len(self.stack)] = 0 | ||||||
| 		 | 		 | ||||||
| 	end_ifclear = end_ifset | 	end_ifclear = end_ifset | ||||||
| 	 | 
 | ||||||
|  | 	def open_value(self): | ||||||
|  | 		self.startsaving() | ||||||
|  | 
 | ||||||
|  | 	def close_value(self): | ||||||
|  | 		key = self.collectsavings () | ||||||
|  | 		if key in self.values.keys(): | ||||||
|  | 			self.write (self.values[key]) | ||||||
|  | 		else: | ||||||
|  | 			print '*** Undefined value: ', key | ||||||
|  | 		        | ||||||
| 	# --- Beginning a file --- | 	# --- Beginning a file --- | ||||||
| 
 | 
 | ||||||
| 	do_finalout = do_comment | 	do_finalout = do_comment | ||||||
|  | @ -630,20 +769,25 @@ def bgn_ifclear(self, args): | ||||||
| 	do_setfilename = do_comment | 	do_setfilename = do_comment | ||||||
| 
 | 
 | ||||||
| 	def do_settitle(self, args): | 	def do_settitle(self, args): | ||||||
| 		self.title = args | 		print args | ||||||
| 
 | 		self.startsaving() | ||||||
|  | 		self.expand (args) | ||||||
|  | 		self.title = self.collectsavings () | ||||||
|  | 		print self.title | ||||||
| 	def do_parskip(self, args): pass | 	def do_parskip(self, args): pass | ||||||
| 	 | 	 | ||||||
| 	# --- Ending a file --- | 	# --- Ending a file --- | ||||||
| 
 | 
 | ||||||
| 	def do_bye(self, args): | 	def do_bye(self, args): | ||||||
|  | 		self.endnode () | ||||||
| 		self.done = 1 | 		self.done = 1 | ||||||
| 
 | 
 | ||||||
| 	# --- Title page --- | 	# --- Title page --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | 	def bgn_titlepage(self, args): self.skip = self.skip + 1 | ||||||
| 	def end_titlepage(self): self.skip = self.skip - 1 | 	def end_titlepage(self): self.skip = self.skip - 1 | ||||||
| 
 | 	def do_shorttitlepage(self, args): pass | ||||||
|  | 	 | ||||||
| 	def do_center(self, args): | 	def do_center(self, args): | ||||||
| 		# Actually not used outside title page... | 		# Actually not used outside title page... | ||||||
| 		self.write('<H1>') | 		self.write('<H1>') | ||||||
|  | @ -685,24 +829,28 @@ def do_node(self, args): | ||||||
| 		else: | 		else: | ||||||
| 			if self.debugging: print '--- writing', file | 			if self.debugging: print '--- writing', file | ||||||
| 		self.filenames[file] = 1 | 		self.filenames[file] = 1 | ||||||
| 		self.nodefp = open(file, 'w') | 		# self.nodefp = open(file, 'w') | ||||||
| 		self.nodename = name | 		self.nodename = name | ||||||
|  | 		if self.cont and self.nodestack: | ||||||
|  | 		    self.nodestack[-1].cont = self.nodename | ||||||
| 		if not self.topname: self.topname = name | 		if not self.topname: self.topname = name | ||||||
| 		title = name | 		title = name | ||||||
| 		if self.title: title = title + ' -- ' + self.title | 		if self.title: title = title + ' -- ' + self.title | ||||||
| 		# No idea what this means, but this is what latex2html writes | 		# No idea what this means, but this is what latex2html writes | ||||||
| 		self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||||
| 		self.write('<!- Converted with texi2html and Python>\n') | 		# self.write('<!- Converted with texi2html and Python>\n') | ||||||
| 		self.write ('<P>\n<HEAD>\n') | 		# self.write ('<P>\n<HEAD>\n') | ||||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||||
| 		self.link('Next', next) | 		# self.link('Next', next) | ||||||
| 		self.link('Prev', prev) | 		# self.link('Prev', prev) | ||||||
| 		self.link('Up', up) | 		# self.link('Up', up) | ||||||
| 		if self.nodename <> self.topname: | 		# if self.nodename <> self.topname: | ||||||
| 			self.link('Top', self.topname) | 		# 	self.link('Top', self.topname) | ||||||
| 		self.write ('<BR> <HR> <P>\n') | 		# self.write ('<BR> <HR> <P>\n') | ||||||
| 
 | 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||||
|  | 				  title, next, prev, up) | ||||||
|  | 		 | ||||||
| 	def link(self, label, nodename): | 	def link(self, label, nodename): | ||||||
| 		if nodename: | 		if nodename: | ||||||
| 			if string.lower(nodename) == '(dir)': | 			if string.lower(nodename) == '(dir)': | ||||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | ||||||
| 
 | 
 | ||||||
| 	# --- Sectioning commands --- | 	# --- Sectioning commands --- | ||||||
| 
 | 
 | ||||||
|  | 	def popstack (self, type): | ||||||
|  | 	    if (self.node): | ||||||
|  | 		self.node.type = type | ||||||
|  | 		while self.nodestack: | ||||||
|  | 		    if self.nodestack[-1].type > type: | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    elif self.nodestack[-1].type == type: | ||||||
|  | 			if not self.nodestack[-1].next: | ||||||
|  | 			    self.nodestack[-1].next = self.node.name | ||||||
|  | 			if not self.node.prev: | ||||||
|  | 			    self.node.prev = self.nodestack[-1].name | ||||||
|  | 			self.nodestack[-1].finalize () | ||||||
|  | 			self.nodestack[-1].flush () | ||||||
|  | 			del self.nodestack [-1] | ||||||
|  | 		    else: | ||||||
|  | 			if type > 1 and not self.node.up: | ||||||
|  | 			    self.node.up = self.nodestack[-1].name | ||||||
|  | 			break | ||||||
|  | 
 | ||||||
| 	def do_chapter(self, args): | 	def do_chapter(self, args): | ||||||
| 		self.heading('H1', args, 0) | 		self.heading('H1', args, 0) | ||||||
|  | 		self.popstack (1) | ||||||
|  | 
 | ||||||
| 	def do_unnumbered(self, args): | 	def do_unnumbered(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_appendix(self, args): | 	def do_appendix(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (1) | ||||||
| 	def do_top(self, args): | 	def do_top(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 	def do_chapheading(self, args): | 	def do_chapheading(self, args): | ||||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | ||||||
| 
 | 
 | ||||||
| 	def do_section(self, args): | 	def do_section(self, args): | ||||||
| 		self.heading('H1', args, 1) | 		self.heading('H1', args, 1) | ||||||
|  | 		self.popstack (2) | ||||||
|  | 
 | ||||||
| 	def do_unnumberedsec(self, args): | 	def do_unnumberedsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	def do_appendixsec(self, args): | 	def do_appendixsec(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
|  | 		self.popstack (2) | ||||||
| 	do_appendixsection = do_appendixsec | 	do_appendixsection = do_appendixsec | ||||||
| 	def do_heading(self, args): | 	def do_heading(self, args): | ||||||
| 		self.heading('H1', args, -1) | 		self.heading('H1', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsection(self, args): | 	def do_subsection(self, args): | ||||||
| 		self.heading('H2', args, 2) | 		self.heading('H2', args, 2) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_unnumberedsubsec(self, args): | 	def do_unnumberedsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_appendixsubsec(self, args): | 	def do_appendixsubsec(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
|  | 		self.popstack (3) | ||||||
| 	def do_subheading(self, args): | 	def do_subheading(self, args): | ||||||
| 		self.heading('H2', args, -1) | 		self.heading('H2', args, -1) | ||||||
| 
 | 
 | ||||||
| 	def do_subsubsection(self, args): | 	def do_subsubsection(self, args): | ||||||
| 		self.heading('H3', args, 3) | 		self.heading('H3', args, 3) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_unnumberedsubsubsec(self, args): | 	def do_unnumberedsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_appendixsubsubsec(self, args): | 	def do_appendixsubsubsec(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
|  | 		self.popstack (4) | ||||||
| 	def do_subsubheading(self, args): | 	def do_subsubheading(self, args): | ||||||
| 		self.heading('H3', args, -1) | 		self.heading('H3', args, -1) | ||||||
| 
 | 
 | ||||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | ||||||
| 			print '---', args | 			print '---', args | ||||||
| 
 | 
 | ||||||
| 	def do_contents(self, args): | 	def do_contents(self, args): | ||||||
| 		pass | 	        # pass | ||||||
| 		# self.listcontents('Table of Contents', 999) | 		self.listcontents('Table of Contents', 999) | ||||||
| 
 | 
 | ||||||
| 	def do_shortcontents(self, args): | 	def do_shortcontents(self, args): | ||||||
| 		pass | 		pass | ||||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | ||||||
| 	# --- Function and variable definitions --- | 	# --- Function and variable definitions --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deffn(self, args): | 	def bgn_deffn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
| 		words = splitwords(args, 2) | 		self.do_deffnx (args) | ||||||
| 		[category, name], rest = words[:2], words[2:] |  | ||||||
| 		self.expand('@b{' + name + '}') |  | ||||||
| 		for word in rest: self.expand(' ' + makevar(word)) |  | ||||||
| 		self.expand(' -- ' + category) |  | ||||||
| 		self.write('<DD>\n') |  | ||||||
| 		self.index('fn', name) |  | ||||||
| 
 | 
 | ||||||
| 	def end_deffn(self): | 	def end_deffn(self): | ||||||
| 		self.write('</DL>\n') | 		self.write('</DL>\n') | ||||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | ||||||
| 
 | 
 | ||||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||||
| 	end_defun = end_deffn | 	end_defun = end_deffn | ||||||
|  | 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||||
| 	end_defmac = end_deffn | 	end_defmac = end_deffn | ||||||
|  | 	def do_defmacx(self, args): self.do_deffnx('Macro ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | 	def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) | ||||||
| 	end_defspec = end_deffn | 	end_defspec = end_deffn | ||||||
|  | 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defvr(self, args): | 	def bgn_defvr(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defvrx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defvr = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_defvrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@code{' + name + '}') | 		self.expand('@code{' + name + '}') | ||||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name) | 		self.index('vr', name) | ||||||
| 
 | 
 | ||||||
| 	end_defvr = end_deffn |  | ||||||
| 
 |  | ||||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||||
| 	end_defvar = end_defvr | 	end_defvar = end_defvr | ||||||
|  | 	def do_defvarx(self, args): self.do_defvrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | 	def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) | ||||||
| 	end_defopt = end_defvr | 	end_defopt = end_defvr | ||||||
|  | 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for typed languages --- | 	# --- Ditto for typed languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefn(self, args): | 	def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypefnx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypefn = end_deffn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypefnx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypefn = end_deffn |  | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||||
| 	end_deftypefun = end_deftypefn | 	end_deftypefun = end_deftypefn | ||||||
|  | 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftypevr(self, args): | 	def bgn_deftypevr(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_deftypevrx (args) | ||||||
|  | 	 | ||||||
|  | 	end_deftypevr = end_deftypefn | ||||||
|  | 
 | ||||||
|  | 	def do_deftypevrx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, datatype, name], rest = words[:3], words[3:] | 		[category, datatype, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name) | 		self.index('fn', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftypevr = end_deftypefn |  | ||||||
| 
 |  | ||||||
| 	def bgn_deftypevar(self, args): | 	def bgn_deftypevar(self, args): | ||||||
| 		self.bgn_deftypevr('Variable ' + args) | 		self.bgn_deftypevr('Variable ' + args) | ||||||
| 	end_deftypevar = end_deftypevr | 	end_deftypevar = end_deftypevr | ||||||
|  | 	def do_deftypevarx(self, args): | ||||||
|  | 		self.do_deftypevrx('Variable ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for object-oriented languages --- | 	# --- Ditto for object-oriented languages --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_defcv(self, args): | 	def bgn_defcv(self, args): | ||||||
|  | 		self.write('<DL>') | ||||||
|  | 		self.do_defcvx(args) | ||||||
|  | 
 | ||||||
|  | 	end_defcv = end_deftypevr | ||||||
|  | 
 | ||||||
|  | 	def do_defcvx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.write('<DL><DT>') |  | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
| 		# If there are too many arguments, show them | 		# If there are too many arguments, show them | ||||||
| 		for word in rest: self.expand(' ' + word) | 		for word in rest: self.expand(' ' + word) | ||||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defcv = end_deftypevr |  | ||||||
| 
 |  | ||||||
| 	def bgn_defivar(self, args): | 	def bgn_defivar(self, args): | ||||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | 		self.bgn_defcv('{Instance Variable} ' + args) | ||||||
| 	end_defivar = end_defcv | 	end_defivar = end_defcv | ||||||
|  | 	def do_defivarx(self, args): | ||||||
|  | 		self.do_defcvx('{Instance Variable} ' + args) | ||||||
| 
 | 
 | ||||||
| 	def bgn_defop(self, args): | 	def bgn_defop(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_defopx (args) | ||||||
|  | 
 | ||||||
|  | 	end_defop = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_defopx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 3) | 		words = splitwords(args, 3) | ||||||
| 		[category, classname, name], rest = words[:3], words[3:] | 		[category, classname, name], rest = words[:3], words[3:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||||
| 
 | 
 | ||||||
| 	end_defop = end_defcv |  | ||||||
| 
 |  | ||||||
| 	def bgn_defmethod(self, args): | 	def bgn_defmethod(self, args): | ||||||
| 		self.bgn_defop('Method ' + args) | 		self.bgn_defop('Method ' + args) | ||||||
| 	end_defmethod = end_defop | 	end_defmethod = end_defop | ||||||
|  | 	def do_defmethodx(self, args): | ||||||
|  | 		self.do_defopx('Method ' + args) | ||||||
| 
 | 
 | ||||||
| 	# --- Ditto for data types --- | 	# --- Ditto for data types --- | ||||||
| 
 | 
 | ||||||
| 	def bgn_deftp(self, args): | 	def bgn_deftp(self, args): | ||||||
| 		self.write('<DL><DT>') | 		self.write('<DL>') | ||||||
|  | 		self.do_deftpx(args) | ||||||
|  | 
 | ||||||
|  | 	end_deftp = end_defcv | ||||||
|  | 
 | ||||||
|  | 	def do_deftpx(self, args): | ||||||
|  | 		self.write('<DT>') | ||||||
| 		words = splitwords(args, 2) | 		words = splitwords(args, 2) | ||||||
| 		[category, name], rest = words[:2], words[2:] | 		[category, name], rest = words[:2], words[2:] | ||||||
| 		self.expand('@b{' + name + '}') | 		self.expand('@b{' + name + '}') | ||||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | ||||||
| 		self.write('<DD>\n') | 		self.write('<DD>\n') | ||||||
| 		self.index('tp', name) | 		self.index('tp', name) | ||||||
| 
 | 
 | ||||||
| 	end_deftp = end_defcv |  | ||||||
| 
 |  | ||||||
| 	# --- Making Lists and Tables | 	# --- Making Lists and Tables | ||||||
| 
 | 
 | ||||||
| 	def bgn_enumerate(self, args): | 	def bgn_enumerate(self, args): | ||||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Characters that are perfectly safe in filenames and hyperlinks | # Characters that are perfectly safe in filenames and hyperlinks | ||||||
| goodchars = string.letters + string.digits + '!@-_=+.' | goodchars = string.letters + string.digits + '!@-=+.' | ||||||
| 
 | 
 | ||||||
| # Replace characters that aren't perfectly safe by underscores | # Replace characters that aren't perfectly safe by dashes | ||||||
|  | # Underscores are bad since Cern HTTPD treats them as delimiters for | ||||||
|  | # encoding times, so you get mismatches if you compress your files: | ||||||
|  | # a.html.gz will map to a_b.html.gz | ||||||
| def fixfunnychars(addr): | def fixfunnychars(addr): | ||||||
| 	i = 0 | 	i = 0 | ||||||
| 	while i < len(addr): | 	while i < len(addr): | ||||||
| 		c = addr[i] | 		c = addr[i] | ||||||
| 		if c not in goodchars: | 		if c not in goodchars: | ||||||
| 			c = '_' | 			c = '-' | ||||||
| 			addr = addr[:i] + c + addr[i+1:] | 			addr = addr[:i] + c + addr[i+1:] | ||||||
| 		i = i + len(c) | 		i = i + len(c) | ||||||
| 	return addr | 	return addr | ||||||
|  | @ -1252,8 +1469,11 @@ def test(): | ||||||
| 	while sys.argv[1:2] == ['-d']: | 	while sys.argv[1:2] == ['-d']: | ||||||
| 		parser.debugging = parser.debugging + 1 | 		parser.debugging = parser.debugging + 1 | ||||||
| 		del sys.argv[1:2] | 		del sys.argv[1:2] | ||||||
|  | 	if sys.argv[1] == '-c': | ||||||
|  | 	    parser.cont = 1 | ||||||
|  | 	    del sys.argv[1] | ||||||
| 	if len(sys.argv) <> 3: | 	if len(sys.argv) <> 3: | ||||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||||
| 		sys.exit(2) | 		sys.exit(2) | ||||||
| 	file = sys.argv[1] | 	file = sys.argv[1] | ||||||
| 	parser.setdirname(sys.argv[2]) | 	parser.setdirname(sys.argv[2]) | ||||||
|  | @ -1272,3 +1492,9 @@ def test(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| test() | test() | ||||||
|  | 
 | ||||||
|  | # Emacs local variables | ||||||
|  | #  | ||||||
|  | # Local Variables: | ||||||
|  | # py-indent-offset: 8 | ||||||
|  | # End: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum