mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +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
				
			
		
							
								
								
									
										354
									
								
								Doc/texi2html.py
									
										
									
									
									
								
							
							
						
						
									
										354
									
								
								Doc/texi2html.py
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| # Convert GNU texinfo files into HTML, one file per node. | ||||
| # 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. | ||||
| # This creates many files (one per info node) in the output directory, | ||||
| # overwriting existing files of the same name.  All files created have | ||||
|  | @ -17,12 +17,23 @@ | |||
| # - handle @exdent properly | ||||
| # - add links directly to the proper line from indices | ||||
| # - check against the definitive list of @-cmds; we still miss (among others): | ||||
| # - @set, @clear, @ifset, @ifclear | ||||
| # - @defindex (hard) | ||||
| # - @c(omment) in the middle of a line (rarely used) | ||||
| # - @this* (not really needed, only used in headers anyway) | ||||
| # - @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 regex | ||||
|  | @ -39,6 +50,81 @@ | |||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||
| 					# 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: | ||||
| 
 | ||||
| 	# Initialize an instance | ||||
|  | @ -50,6 +136,7 @@ def __init__(self): | |||
| 		self.nodelineno = 0	# Linenumber relative to node | ||||
| 		self.links = None	# Links from current node | ||||
| 		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.includedir = '.'	# directory to search @include files | ||||
| 		self.nodename = ''	# name of current node | ||||
|  | @ -59,14 +146,17 @@ def __init__(self): | |||
| 		self.contents = []	# Reset table of contents | ||||
| 		self.numbering = []	# Reset section numbering counters | ||||
| 		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 | ||||
| 		# XXX The following should be reset per node?! | ||||
| 		self.footnotes = []	# Reset list of footnotes | ||||
| 		self.itemarg = None	# Reset command used by @item | ||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||
| 		self.itemindex = None	# Reset item index name | ||||
| 
 | ||||
| 		self.node = None | ||||
| 		self.nodestack = [] | ||||
| 		self.cont = 0 | ||||
| 		self.includedepth = 0 | ||||
| 	# Set (output) directory name | ||||
| 	def setdirname(self, dirname): | ||||
| 		self.dirname = dirname | ||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | |||
| 		if self.stack: | ||||
| 			print '*** Stack not empty at the end' | ||||
| 			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 | ||||
| 	def startsaving(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursively saving text, expect trouble' | ||||
| 			self.savestack.append (self.savetext) | ||||
| 			# print '*** Recursively saving text, expect trouble' | ||||
| 		self.savetext = '' | ||||
| 
 | ||||
| 	# Return the text saved so far and start writing to file again | ||||
| 	def collectsavings(self): | ||||
| 		savetext = self.savetext | ||||
| 		if len (self.savestack) > 0: | ||||
| 			self.savetext = self.savestack[-1] | ||||
| 			del self.savestack[-1] | ||||
| 		else: | ||||
| 			self.savetext = None | ||||
| 		return savetext or '' | ||||
| 
 | ||||
| 	# Write text to file, or save it in a buffer, or ignore it | ||||
| 	def write(self, *args): | ||||
| 		try: | ||||
| 			text = string.joinfields(args, '') | ||||
| 		except: | ||||
| 			print args | ||||
| 			raise TypeError | ||||
| 		if self.savetext <> None: | ||||
| 			self.savetext = self.savetext + text | ||||
| 		elif self.nodefp: | ||||
| 			self.nodefp.write(text) | ||||
| 
 | ||||
| 		elif self.node: | ||||
| 		        self.node.write (text) | ||||
| 	# Complete the current node -- write footnotes and close file | ||||
| 	def endnode(self): | ||||
| 		if self.savetext <> None: | ||||
|  | @ -173,6 +278,15 @@ def endnode(self): | |||
| 			self.write('</BODY>\n') | ||||
| 			self.nodefp.close() | ||||
| 			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 = '' | ||||
| 
 | ||||
| 	# Process a list of lines, expanding embedded @-commands | ||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | |||
| 		save_done = self.done | ||||
| 		save_skip = self.skip | ||||
| 		save_stack = self.stack | ||||
| 		self.includedepth = self.includedepth + 1 | ||||
| 		self.parserest(fp, 0) | ||||
| 		self.includedepth = self.includedepth - 1 | ||||
| 		fp.close() | ||||
| 		self.done = save_done | ||||
| 		self.skip = save_skip | ||||
|  | @ -364,6 +480,8 @@ def open_TeX(self): self.write('TeX') | |||
| 	def close_TeX(self): pass | ||||
| 
 | ||||
| 	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 close_minus(self): pass | ||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | |||
| 	close_i = close_emph | ||||
| 
 | ||||
| 	def open_footnote(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursive footnote -- expect weirdness' | ||||
| 		# if self.savetext <> None: | ||||
| 		# 	print '*** Recursive footnote -- expect weirdness' | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.write('<A NAME="footnoteref', `id`, \ | ||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||
| 		self.savetext = '' | ||||
| 		# self.savetext = '' | ||||
| 		self.startsaving () | ||||
| 
 | ||||
| 	def close_footnote(self): | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.footnotes.append(`id`, self.savetext) | ||||
| 		self.savetext = None | ||||
| 		# self.footnotes.append(`id`, self.savetext) | ||||
| 		self.footnotes.append(`id`, self.collectsavings()) | ||||
| 		# self.savetext = None | ||||
| 
 | ||||
| 	def writefootnotes(self): | ||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||
|  | @ -534,6 +654,8 @@ def command(self, line): | |||
| 			try: | ||||
| 				func = getattr(self, 'bgn_' + cmd) | ||||
| 			except AttributeError: | ||||
| 				# don't complain if we are skipping anyway | ||||
| 				if not self.skip: | ||||
| 					self.unknown_cmd(cmd, args) | ||||
| 				return | ||||
| 			self.stack.append(cmd) | ||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): 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 bgn_set(self, args): | ||||
| 		if args not in self.goodset: | ||||
| 			self.gooset.append(args) | ||||
| 	def do_set(self, args): | ||||
| 		fields = string.splitfields (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): | ||||
| 		if args in self.goodset: | ||||
| 			self.gooset.remove(args) | ||||
| 	def do_clear(self, args): | ||||
| 		self.values[args] = None | ||||
| 			 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -615,7 +743,8 @@ def end_ifset(self): | |||
| 		del self.stackinfo[len(self.stack) + 1] | ||||
| 
 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -623,6 +752,16 @@ def bgn_ifclear(self, args): | |||
| 		 | ||||
| 	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 --- | ||||
| 
 | ||||
| 	do_finalout = do_comment | ||||
|  | @ -630,19 +769,24 @@ def bgn_ifclear(self, args): | |||
| 	do_setfilename = do_comment | ||||
| 
 | ||||
| 	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 | ||||
| 	 | ||||
| 	# --- Ending a file --- | ||||
| 
 | ||||
| 	def do_bye(self, args): | ||||
| 		self.endnode () | ||||
| 		self.done = 1 | ||||
| 
 | ||||
| 	# --- Title page --- | ||||
| 
 | ||||
| 	def bgn_titlepage(self, args): 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): | ||||
| 		# Actually not used outside title page... | ||||
|  | @ -685,23 +829,27 @@ def do_node(self, args): | |||
| 		else: | ||||
| 			if self.debugging: print '--- writing', file | ||||
| 		self.filenames[file] = 1 | ||||
| 		self.nodefp = open(file, 'w') | ||||
| 		# self.nodefp = open(file, 'w') | ||||
| 		self.nodename = name | ||||
| 		if self.cont and self.nodestack: | ||||
| 		    self.nodestack[-1].cont = self.nodename | ||||
| 		if not self.topname: self.topname = name | ||||
| 		title = name | ||||
| 		if self.title: title = title + ' -- ' + self.title | ||||
| 		# 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('<!- Converted with texi2html and Python>\n') | ||||
| 		self.write ('<P>\n<HEAD>\n') | ||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		self.link('Next', next) | ||||
| 		self.link('Prev', prev) | ||||
| 		self.link('Up', up) | ||||
| 		if self.nodename <> self.topname: | ||||
| 			self.link('Top', self.topname) | ||||
| 		self.write ('<BR> <HR> <P>\n') | ||||
| 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||
| 		# self.write('<!- Converted with texi2html and Python>\n') | ||||
| 		# self.write ('<P>\n<HEAD>\n') | ||||
| 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		# self.link('Next', next) | ||||
| 		# self.link('Prev', prev) | ||||
| 		# self.link('Up', up) | ||||
| 		# if self.nodename <> self.topname: | ||||
| 		# 	self.link('Top', self.topname) | ||||
| 		# self.write ('<BR> <HR> <P>\n') | ||||
| 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||
| 				  title, next, prev, up) | ||||
| 		 | ||||
| 	def link(self, label, nodename): | ||||
| 		if nodename: | ||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | |||
| 
 | ||||
| 	# --- 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): | ||||
| 		self.heading('H1', args, 0) | ||||
| 		self.popstack (1) | ||||
| 
 | ||||
| 	def do_unnumbered(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_appendix(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_top(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 	def do_chapheading(self, args): | ||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | |||
| 
 | ||||
| 	def do_section(self, args): | ||||
| 		self.heading('H1', args, 1) | ||||
| 		self.popstack (2) | ||||
| 
 | ||||
| 	def do_unnumberedsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	def do_appendixsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	do_appendixsection = do_appendixsec | ||||
| 	def do_heading(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 
 | ||||
| 	def do_subsection(self, args): | ||||
| 		self.heading('H2', args, 2) | ||||
| 		self.popstack (3) | ||||
| 	def do_unnumberedsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_appendixsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_subheading(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 
 | ||||
| 	def do_subsubsection(self, args): | ||||
| 		self.heading('H3', args, 3) | ||||
| 		self.popstack (4) | ||||
| 	def do_unnumberedsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_appendixsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_subsubheading(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 
 | ||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | |||
| 			print '---', args | ||||
| 
 | ||||
| 	def do_contents(self, args): | ||||
| 		pass | ||||
| 		# self.listcontents('Table of Contents', 999) | ||||
| 	        # pass | ||||
| 		self.listcontents('Table of Contents', 999) | ||||
| 
 | ||||
| 	def do_shortcontents(self, args): | ||||
| 		pass | ||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | |||
| 	# --- Function and variable definitions --- | ||||
| 
 | ||||
| 	def bgn_deffn(self, args): | ||||
| 		self.write('<DL><DT>') | ||||
| 		words = splitwords(args, 2) | ||||
| 		[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) | ||||
| 		self.write('<DL>') | ||||
| 		self.do_deffnx (args) | ||||
| 
 | ||||
| 	def end_deffn(self): | ||||
| 		self.write('</DL>\n') | ||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | |||
| 
 | ||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||
| 	end_defun = end_deffn | ||||
| 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||
| 
 | ||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||
| 	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) | ||||
| 	end_defspec = end_deffn | ||||
| 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + 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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@code{' + name + '}') | ||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name) | ||||
| 
 | ||||
| 	end_defvr = end_deffn | ||||
| 
 | ||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||
| 	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) | ||||
| 	end_defopt = end_defvr | ||||
| 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for typed languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypefn = end_deffn | ||||
| 
 | ||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||
| 	end_deftypefun = end_deftypefn | ||||
| 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + 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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypevr = end_deftypefn | ||||
| 
 | ||||
| 	def bgn_deftypevar(self, args): | ||||
| 		self.bgn_deftypevr('Variable ' + args) | ||||
| 	end_deftypevar = end_deftypevr | ||||
| 	def do_deftypevarx(self, args): | ||||
| 		self.do_deftypevrx('Variable ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for object-oriented languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||
| 
 | ||||
| 	end_defcv = end_deftypevr | ||||
| 
 | ||||
| 	def bgn_defivar(self, args): | ||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | ||||
| 	end_defivar = end_defcv | ||||
| 	def do_defivarx(self, args): | ||||
| 		self.do_defcvx('{Instance Variable} ' + 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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||
| 
 | ||||
| 	end_defop = end_defcv | ||||
| 
 | ||||
| 	def bgn_defmethod(self, args): | ||||
| 		self.bgn_defop('Method ' + args) | ||||
| 	end_defmethod = end_defop | ||||
| 	def do_defmethodx(self, args): | ||||
| 		self.do_defopx('Method ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for data types --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('tp', name) | ||||
| 
 | ||||
| 	end_deftp = end_defcv | ||||
| 
 | ||||
| 	# --- Making Lists and Tables | ||||
| 
 | ||||
| 	def bgn_enumerate(self, args): | ||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | |||
| 
 | ||||
| 
 | ||||
| # 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): | ||||
| 	i = 0 | ||||
| 	while i < len(addr): | ||||
| 		c = addr[i] | ||||
| 		if c not in goodchars: | ||||
| 			c = '_' | ||||
| 			c = '-' | ||||
| 			addr = addr[:i] + c + addr[i+1:] | ||||
| 		i = i + len(c) | ||||
| 	return addr | ||||
|  | @ -1252,8 +1469,11 @@ def test(): | |||
| 	while sys.argv[1:2] == ['-d']: | ||||
| 		parser.debugging = parser.debugging + 1 | ||||
| 		del sys.argv[1:2] | ||||
| 	if sys.argv[1] == '-c': | ||||
| 	    parser.cont = 1 | ||||
| 	    del sys.argv[1] | ||||
| 	if len(sys.argv) <> 3: | ||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | ||||
| 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||
| 		sys.exit(2) | ||||
| 	file = sys.argv[1] | ||||
| 	parser.setdirname(sys.argv[2]) | ||||
|  | @ -1272,3 +1492,9 @@ def 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. | ||||
| # 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. | ||||
| # This creates many files (one per info node) in the output directory, | ||||
| # overwriting existing files of the same name.  All files created have | ||||
|  | @ -17,12 +17,23 @@ | |||
| # - handle @exdent properly | ||||
| # - add links directly to the proper line from indices | ||||
| # - check against the definitive list of @-cmds; we still miss (among others): | ||||
| # - @set, @clear, @ifset, @ifclear | ||||
| # - @defindex (hard) | ||||
| # - @c(omment) in the middle of a line (rarely used) | ||||
| # - @this* (not really needed, only used in headers anyway) | ||||
| # - @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 regex | ||||
|  | @ -39,6 +50,81 @@ | |||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||
| 					# 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: | ||||
| 
 | ||||
| 	# Initialize an instance | ||||
|  | @ -50,6 +136,7 @@ def __init__(self): | |||
| 		self.nodelineno = 0	# Linenumber relative to node | ||||
| 		self.links = None	# Links from current node | ||||
| 		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.includedir = '.'	# directory to search @include files | ||||
| 		self.nodename = ''	# name of current node | ||||
|  | @ -59,14 +146,17 @@ def __init__(self): | |||
| 		self.contents = []	# Reset table of contents | ||||
| 		self.numbering = []	# Reset section numbering counters | ||||
| 		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 | ||||
| 		# XXX The following should be reset per node?! | ||||
| 		self.footnotes = []	# Reset list of footnotes | ||||
| 		self.itemarg = None	# Reset command used by @item | ||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||
| 		self.itemindex = None	# Reset item index name | ||||
| 
 | ||||
| 		self.node = None | ||||
| 		self.nodestack = [] | ||||
| 		self.cont = 0 | ||||
| 		self.includedepth = 0 | ||||
| 	# Set (output) directory name | ||||
| 	def setdirname(self, dirname): | ||||
| 		self.dirname = dirname | ||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | |||
| 		if self.stack: | ||||
| 			print '*** Stack not empty at the end' | ||||
| 			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 | ||||
| 	def startsaving(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursively saving text, expect trouble' | ||||
| 			self.savestack.append (self.savetext) | ||||
| 			# print '*** Recursively saving text, expect trouble' | ||||
| 		self.savetext = '' | ||||
| 
 | ||||
| 	# Return the text saved so far and start writing to file again | ||||
| 	def collectsavings(self): | ||||
| 		savetext = self.savetext | ||||
| 		if len (self.savestack) > 0: | ||||
| 			self.savetext = self.savestack[-1] | ||||
| 			del self.savestack[-1] | ||||
| 		else: | ||||
| 			self.savetext = None | ||||
| 		return savetext or '' | ||||
| 
 | ||||
| 	# Write text to file, or save it in a buffer, or ignore it | ||||
| 	def write(self, *args): | ||||
| 		try: | ||||
| 			text = string.joinfields(args, '') | ||||
| 		except: | ||||
| 			print args | ||||
| 			raise TypeError | ||||
| 		if self.savetext <> None: | ||||
| 			self.savetext = self.savetext + text | ||||
| 		elif self.nodefp: | ||||
| 			self.nodefp.write(text) | ||||
| 
 | ||||
| 		elif self.node: | ||||
| 		        self.node.write (text) | ||||
| 	# Complete the current node -- write footnotes and close file | ||||
| 	def endnode(self): | ||||
| 		if self.savetext <> None: | ||||
|  | @ -173,6 +278,15 @@ def endnode(self): | |||
| 			self.write('</BODY>\n') | ||||
| 			self.nodefp.close() | ||||
| 			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 = '' | ||||
| 
 | ||||
| 	# Process a list of lines, expanding embedded @-commands | ||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | |||
| 		save_done = self.done | ||||
| 		save_skip = self.skip | ||||
| 		save_stack = self.stack | ||||
| 		self.includedepth = self.includedepth + 1 | ||||
| 		self.parserest(fp, 0) | ||||
| 		self.includedepth = self.includedepth - 1 | ||||
| 		fp.close() | ||||
| 		self.done = save_done | ||||
| 		self.skip = save_skip | ||||
|  | @ -364,6 +480,8 @@ def open_TeX(self): self.write('TeX') | |||
| 	def close_TeX(self): pass | ||||
| 
 | ||||
| 	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 close_minus(self): pass | ||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | |||
| 	close_i = close_emph | ||||
| 
 | ||||
| 	def open_footnote(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursive footnote -- expect weirdness' | ||||
| 		# if self.savetext <> None: | ||||
| 		# 	print '*** Recursive footnote -- expect weirdness' | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.write('<A NAME="footnoteref', `id`, \ | ||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||
| 		self.savetext = '' | ||||
| 		# self.savetext = '' | ||||
| 		self.startsaving () | ||||
| 
 | ||||
| 	def close_footnote(self): | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.footnotes.append(`id`, self.savetext) | ||||
| 		self.savetext = None | ||||
| 		# self.footnotes.append(`id`, self.savetext) | ||||
| 		self.footnotes.append(`id`, self.collectsavings()) | ||||
| 		# self.savetext = None | ||||
| 
 | ||||
| 	def writefootnotes(self): | ||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||
|  | @ -534,6 +654,8 @@ def command(self, line): | |||
| 			try: | ||||
| 				func = getattr(self, 'bgn_' + cmd) | ||||
| 			except AttributeError: | ||||
| 				# don't complain if we are skipping anyway | ||||
| 				if not self.skip: | ||||
| 					self.unknown_cmd(cmd, args) | ||||
| 				return | ||||
| 			self.stack.append(cmd) | ||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): 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 bgn_set(self, args): | ||||
| 		if args not in self.goodset: | ||||
| 			self.gooset.append(args) | ||||
| 	def do_set(self, args): | ||||
| 		fields = string.splitfields (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): | ||||
| 		if args in self.goodset: | ||||
| 			self.gooset.remove(args) | ||||
| 	def do_clear(self, args): | ||||
| 		self.values[args] = None | ||||
| 			 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -615,7 +743,8 @@ def end_ifset(self): | |||
| 		del self.stackinfo[len(self.stack) + 1] | ||||
| 
 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -623,6 +752,16 @@ def bgn_ifclear(self, args): | |||
| 		 | ||||
| 	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 --- | ||||
| 
 | ||||
| 	do_finalout = do_comment | ||||
|  | @ -630,19 +769,24 @@ def bgn_ifclear(self, args): | |||
| 	do_setfilename = do_comment | ||||
| 
 | ||||
| 	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 | ||||
| 	 | ||||
| 	# --- Ending a file --- | ||||
| 
 | ||||
| 	def do_bye(self, args): | ||||
| 		self.endnode () | ||||
| 		self.done = 1 | ||||
| 
 | ||||
| 	# --- Title page --- | ||||
| 
 | ||||
| 	def bgn_titlepage(self, args): 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): | ||||
| 		# Actually not used outside title page... | ||||
|  | @ -685,23 +829,27 @@ def do_node(self, args): | |||
| 		else: | ||||
| 			if self.debugging: print '--- writing', file | ||||
| 		self.filenames[file] = 1 | ||||
| 		self.nodefp = open(file, 'w') | ||||
| 		# self.nodefp = open(file, 'w') | ||||
| 		self.nodename = name | ||||
| 		if self.cont and self.nodestack: | ||||
| 		    self.nodestack[-1].cont = self.nodename | ||||
| 		if not self.topname: self.topname = name | ||||
| 		title = name | ||||
| 		if self.title: title = title + ' -- ' + self.title | ||||
| 		# 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('<!- Converted with texi2html and Python>\n') | ||||
| 		self.write ('<P>\n<HEAD>\n') | ||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		self.link('Next', next) | ||||
| 		self.link('Prev', prev) | ||||
| 		self.link('Up', up) | ||||
| 		if self.nodename <> self.topname: | ||||
| 			self.link('Top', self.topname) | ||||
| 		self.write ('<BR> <HR> <P>\n') | ||||
| 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||
| 		# self.write('<!- Converted with texi2html and Python>\n') | ||||
| 		# self.write ('<P>\n<HEAD>\n') | ||||
| 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		# self.link('Next', next) | ||||
| 		# self.link('Prev', prev) | ||||
| 		# self.link('Up', up) | ||||
| 		# if self.nodename <> self.topname: | ||||
| 		# 	self.link('Top', self.topname) | ||||
| 		# self.write ('<BR> <HR> <P>\n') | ||||
| 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||
| 				  title, next, prev, up) | ||||
| 		 | ||||
| 	def link(self, label, nodename): | ||||
| 		if nodename: | ||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | |||
| 
 | ||||
| 	# --- 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): | ||||
| 		self.heading('H1', args, 0) | ||||
| 		self.popstack (1) | ||||
| 
 | ||||
| 	def do_unnumbered(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_appendix(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_top(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 	def do_chapheading(self, args): | ||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | |||
| 
 | ||||
| 	def do_section(self, args): | ||||
| 		self.heading('H1', args, 1) | ||||
| 		self.popstack (2) | ||||
| 
 | ||||
| 	def do_unnumberedsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	def do_appendixsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	do_appendixsection = do_appendixsec | ||||
| 	def do_heading(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 
 | ||||
| 	def do_subsection(self, args): | ||||
| 		self.heading('H2', args, 2) | ||||
| 		self.popstack (3) | ||||
| 	def do_unnumberedsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_appendixsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_subheading(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 
 | ||||
| 	def do_subsubsection(self, args): | ||||
| 		self.heading('H3', args, 3) | ||||
| 		self.popstack (4) | ||||
| 	def do_unnumberedsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_appendixsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_subsubheading(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 
 | ||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | |||
| 			print '---', args | ||||
| 
 | ||||
| 	def do_contents(self, args): | ||||
| 		pass | ||||
| 		# self.listcontents('Table of Contents', 999) | ||||
| 	        # pass | ||||
| 		self.listcontents('Table of Contents', 999) | ||||
| 
 | ||||
| 	def do_shortcontents(self, args): | ||||
| 		pass | ||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | |||
| 	# --- Function and variable definitions --- | ||||
| 
 | ||||
| 	def bgn_deffn(self, args): | ||||
| 		self.write('<DL><DT>') | ||||
| 		words = splitwords(args, 2) | ||||
| 		[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) | ||||
| 		self.write('<DL>') | ||||
| 		self.do_deffnx (args) | ||||
| 
 | ||||
| 	def end_deffn(self): | ||||
| 		self.write('</DL>\n') | ||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | |||
| 
 | ||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||
| 	end_defun = end_deffn | ||||
| 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||
| 
 | ||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||
| 	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) | ||||
| 	end_defspec = end_deffn | ||||
| 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + 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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@code{' + name + '}') | ||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name) | ||||
| 
 | ||||
| 	end_defvr = end_deffn | ||||
| 
 | ||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||
| 	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) | ||||
| 	end_defopt = end_defvr | ||||
| 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for typed languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypefn = end_deffn | ||||
| 
 | ||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||
| 	end_deftypefun = end_deftypefn | ||||
| 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + 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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypevr = end_deftypefn | ||||
| 
 | ||||
| 	def bgn_deftypevar(self, args): | ||||
| 		self.bgn_deftypevr('Variable ' + args) | ||||
| 	end_deftypevar = end_deftypevr | ||||
| 	def do_deftypevarx(self, args): | ||||
| 		self.do_deftypevrx('Variable ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for object-oriented languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||
| 
 | ||||
| 	end_defcv = end_deftypevr | ||||
| 
 | ||||
| 	def bgn_defivar(self, args): | ||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | ||||
| 	end_defivar = end_defcv | ||||
| 	def do_defivarx(self, args): | ||||
| 		self.do_defcvx('{Instance Variable} ' + 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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||
| 
 | ||||
| 	end_defop = end_defcv | ||||
| 
 | ||||
| 	def bgn_defmethod(self, args): | ||||
| 		self.bgn_defop('Method ' + args) | ||||
| 	end_defmethod = end_defop | ||||
| 	def do_defmethodx(self, args): | ||||
| 		self.do_defopx('Method ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for data types --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('tp', name) | ||||
| 
 | ||||
| 	end_deftp = end_defcv | ||||
| 
 | ||||
| 	# --- Making Lists and Tables | ||||
| 
 | ||||
| 	def bgn_enumerate(self, args): | ||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | |||
| 
 | ||||
| 
 | ||||
| # 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): | ||||
| 	i = 0 | ||||
| 	while i < len(addr): | ||||
| 		c = addr[i] | ||||
| 		if c not in goodchars: | ||||
| 			c = '_' | ||||
| 			c = '-' | ||||
| 			addr = addr[:i] + c + addr[i+1:] | ||||
| 		i = i + len(c) | ||||
| 	return addr | ||||
|  | @ -1252,8 +1469,11 @@ def test(): | |||
| 	while sys.argv[1:2] == ['-d']: | ||||
| 		parser.debugging = parser.debugging + 1 | ||||
| 		del sys.argv[1:2] | ||||
| 	if sys.argv[1] == '-c': | ||||
| 	    parser.cont = 1 | ||||
| 	    del sys.argv[1] | ||||
| 	if len(sys.argv) <> 3: | ||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | ||||
| 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||
| 		sys.exit(2) | ||||
| 	file = sys.argv[1] | ||||
| 	parser.setdirname(sys.argv[2]) | ||||
|  | @ -1272,3 +1492,9 @@ def 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. | ||||
| # 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. | ||||
| # This creates many files (one per info node) in the output directory, | ||||
| # overwriting existing files of the same name.  All files created have | ||||
|  | @ -17,12 +17,23 @@ | |||
| # - handle @exdent properly | ||||
| # - add links directly to the proper line from indices | ||||
| # - check against the definitive list of @-cmds; we still miss (among others): | ||||
| # - @set, @clear, @ifset, @ifclear | ||||
| # - @defindex (hard) | ||||
| # - @c(omment) in the middle of a line (rarely used) | ||||
| # - @this* (not really needed, only used in headers anyway) | ||||
| # - @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 regex | ||||
|  | @ -39,6 +50,81 @@ | |||
| 	'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') | ||||
| 					# 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: | ||||
| 
 | ||||
| 	# Initialize an instance | ||||
|  | @ -50,6 +136,7 @@ def __init__(self): | |||
| 		self.nodelineno = 0	# Linenumber relative to node | ||||
| 		self.links = None	# Links from current node | ||||
| 		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.includedir = '.'	# directory to search @include files | ||||
| 		self.nodename = ''	# name of current node | ||||
|  | @ -59,14 +146,17 @@ def __init__(self): | |||
| 		self.contents = []	# Reset table of contents | ||||
| 		self.numbering = []	# Reset section numbering counters | ||||
| 		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 | ||||
| 		# XXX The following should be reset per node?! | ||||
| 		self.footnotes = []	# Reset list of footnotes | ||||
| 		self.itemarg = None	# Reset command used by @item | ||||
| 		self.itemnumber = None	# Reset number for @item in @enumerate | ||||
| 		self.itemindex = None	# Reset item index name | ||||
| 
 | ||||
| 		self.node = None | ||||
| 		self.nodestack = [] | ||||
| 		self.cont = 0 | ||||
| 		self.includedepth = 0 | ||||
| 	# Set (output) directory name | ||||
| 	def setdirname(self, dirname): | ||||
| 		self.dirname = dirname | ||||
|  | @ -132,27 +222,42 @@ def parserest(self, fp, initial_lineno): | |||
| 		if self.stack: | ||||
| 			print '*** Stack not empty at the end' | ||||
| 			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 | ||||
| 	def startsaving(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursively saving text, expect trouble' | ||||
| 			self.savestack.append (self.savetext) | ||||
| 			# print '*** Recursively saving text, expect trouble' | ||||
| 		self.savetext = '' | ||||
| 
 | ||||
| 	# Return the text saved so far and start writing to file again | ||||
| 	def collectsavings(self): | ||||
| 		savetext = self.savetext | ||||
| 		if len (self.savestack) > 0: | ||||
| 			self.savetext = self.savestack[-1] | ||||
| 			del self.savestack[-1] | ||||
| 		else: | ||||
| 			self.savetext = None | ||||
| 		return savetext or '' | ||||
| 
 | ||||
| 	# Write text to file, or save it in a buffer, or ignore it | ||||
| 	def write(self, *args): | ||||
| 		try: | ||||
| 			text = string.joinfields(args, '') | ||||
| 		except: | ||||
| 			print args | ||||
| 			raise TypeError | ||||
| 		if self.savetext <> None: | ||||
| 			self.savetext = self.savetext + text | ||||
| 		elif self.nodefp: | ||||
| 			self.nodefp.write(text) | ||||
| 
 | ||||
| 		elif self.node: | ||||
| 		        self.node.write (text) | ||||
| 	# Complete the current node -- write footnotes and close file | ||||
| 	def endnode(self): | ||||
| 		if self.savetext <> None: | ||||
|  | @ -173,6 +278,15 @@ def endnode(self): | |||
| 			self.write('</BODY>\n') | ||||
| 			self.nodefp.close() | ||||
| 			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 = '' | ||||
| 
 | ||||
| 	# Process a list of lines, expanding embedded @-commands | ||||
|  | @ -341,7 +455,9 @@ def do_include(self, args): | |||
| 		save_done = self.done | ||||
| 		save_skip = self.skip | ||||
| 		save_stack = self.stack | ||||
| 		self.includedepth = self.includedepth + 1 | ||||
| 		self.parserest(fp, 0) | ||||
| 		self.includedepth = self.includedepth - 1 | ||||
| 		fp.close() | ||||
| 		self.done = save_done | ||||
| 		self.skip = save_skip | ||||
|  | @ -364,6 +480,8 @@ def open_TeX(self): self.write('TeX') | |||
| 	def close_TeX(self): pass | ||||
| 
 | ||||
| 	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 close_minus(self): pass | ||||
|  | @ -466,17 +584,19 @@ def close_emph(self): self.write('</I>') | |||
| 	close_i = close_emph | ||||
| 
 | ||||
| 	def open_footnote(self): | ||||
| 		if self.savetext <> None: | ||||
| 			print '*** Recursive footnote -- expect weirdness' | ||||
| 		# if self.savetext <> None: | ||||
| 		# 	print '*** Recursive footnote -- expect weirdness' | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.write('<A NAME="footnoteref', `id`, \ | ||||
| 			'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') | ||||
| 		self.savetext = '' | ||||
| 		# self.savetext = '' | ||||
| 		self.startsaving () | ||||
| 
 | ||||
| 	def close_footnote(self): | ||||
| 		id = len(self.footnotes) + 1 | ||||
| 		self.footnotes.append(`id`, self.savetext) | ||||
| 		self.savetext = None | ||||
| 		# self.footnotes.append(`id`, self.savetext) | ||||
| 		self.footnotes.append(`id`, self.collectsavings()) | ||||
| 		# self.savetext = None | ||||
| 
 | ||||
| 	def writefootnotes(self): | ||||
| 		self.write('<H2>---------- Footnotes ----------</H2>\n') | ||||
|  | @ -534,6 +654,8 @@ def command(self, line): | |||
| 			try: | ||||
| 				func = getattr(self, 'bgn_' + cmd) | ||||
| 			except AttributeError: | ||||
| 				# don't complain if we are skipping anyway | ||||
| 				if not self.skip: | ||||
| 					self.unknown_cmd(cmd, args) | ||||
| 				return | ||||
| 			self.stack.append(cmd) | ||||
|  | @ -593,16 +715,22 @@ def end_ignore(self): 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 bgn_set(self, args): | ||||
| 		if args not in self.goodset: | ||||
| 			self.gooset.append(args) | ||||
| 	def do_set(self, args): | ||||
| 		fields = string.splitfields (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): | ||||
| 		if args in self.goodset: | ||||
| 			self.gooset.remove(args) | ||||
| 	def do_clear(self, args): | ||||
| 		self.values[args] = None | ||||
| 			 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -615,7 +743,8 @@ def end_ifset(self): | |||
| 		del self.stackinfo[len(self.stack) + 1] | ||||
| 
 | ||||
| 	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.stackinfo[len(self.stack)] = 1 | ||||
| 		else: | ||||
|  | @ -623,6 +752,16 @@ def bgn_ifclear(self, args): | |||
| 		 | ||||
| 	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 --- | ||||
| 
 | ||||
| 	do_finalout = do_comment | ||||
|  | @ -630,19 +769,24 @@ def bgn_ifclear(self, args): | |||
| 	do_setfilename = do_comment | ||||
| 
 | ||||
| 	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 | ||||
| 	 | ||||
| 	# --- Ending a file --- | ||||
| 
 | ||||
| 	def do_bye(self, args): | ||||
| 		self.endnode () | ||||
| 		self.done = 1 | ||||
| 
 | ||||
| 	# --- Title page --- | ||||
| 
 | ||||
| 	def bgn_titlepage(self, args): 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): | ||||
| 		# Actually not used outside title page... | ||||
|  | @ -685,23 +829,27 @@ def do_node(self, args): | |||
| 		else: | ||||
| 			if self.debugging: print '--- writing', file | ||||
| 		self.filenames[file] = 1 | ||||
| 		self.nodefp = open(file, 'w') | ||||
| 		# self.nodefp = open(file, 'w') | ||||
| 		self.nodename = name | ||||
| 		if self.cont and self.nodestack: | ||||
| 		    self.nodestack[-1].cont = self.nodename | ||||
| 		if not self.topname: self.topname = name | ||||
| 		title = name | ||||
| 		if self.title: title = title + ' -- ' + self.title | ||||
| 		# 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('<!- Converted with texi2html and Python>\n') | ||||
| 		self.write ('<P>\n<HEAD>\n') | ||||
| 		self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		self.link('Next', next) | ||||
| 		self.link('Prev', prev) | ||||
| 		self.link('Up', up) | ||||
| 		if self.nodename <> self.topname: | ||||
| 			self.link('Top', self.topname) | ||||
| 		self.write ('<BR> <HR> <P>\n') | ||||
| 		# self.write('<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">\n') | ||||
| 		# self.write('<!- Converted with texi2html and Python>\n') | ||||
| 		# self.write ('<P>\n<HEAD>\n') | ||||
| 		# self.write('<TITLE>', title, '</TITLE>\n') | ||||
| 		# self.write ('</HEAD>\n<BODY>\n<P>\n<BR> <HR>\n') | ||||
| 		# self.link('Next', next) | ||||
| 		# self.link('Prev', prev) | ||||
| 		# self.link('Up', up) | ||||
| 		# if self.nodename <> self.topname: | ||||
| 		# 	self.link('Top', self.topname) | ||||
| 		# self.write ('<BR> <HR> <P>\n') | ||||
| 		self.node = Node (self.dirname, self.nodename, self.topname, \ | ||||
| 				  title, next, prev, up) | ||||
| 		 | ||||
| 	def link(self, label, nodename): | ||||
| 		if nodename: | ||||
|  | @ -714,12 +862,37 @@ def link(self, label, nodename): | |||
| 
 | ||||
| 	# --- 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): | ||||
| 		self.heading('H1', args, 0) | ||||
| 		self.popstack (1) | ||||
| 
 | ||||
| 	def do_unnumbered(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_appendix(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (1) | ||||
| 	def do_top(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 	def do_chapheading(self, args): | ||||
|  | @ -729,29 +902,39 @@ def do_majorheading(self, args): | |||
| 
 | ||||
| 	def do_section(self, args): | ||||
| 		self.heading('H1', args, 1) | ||||
| 		self.popstack (2) | ||||
| 
 | ||||
| 	def do_unnumberedsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	def do_appendixsec(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 		self.popstack (2) | ||||
| 	do_appendixsection = do_appendixsec | ||||
| 	def do_heading(self, args): | ||||
| 		self.heading('H1', args, -1) | ||||
| 
 | ||||
| 	def do_subsection(self, args): | ||||
| 		self.heading('H2', args, 2) | ||||
| 		self.popstack (3) | ||||
| 	def do_unnumberedsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_appendixsubsec(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 		self.popstack (3) | ||||
| 	def do_subheading(self, args): | ||||
| 		self.heading('H2', args, -1) | ||||
| 
 | ||||
| 	def do_subsubsection(self, args): | ||||
| 		self.heading('H3', args, 3) | ||||
| 		self.popstack (4) | ||||
| 	def do_unnumberedsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_appendixsubsubsec(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 		self.popstack (4) | ||||
| 	def do_subsubheading(self, args): | ||||
| 		self.heading('H3', args, -1) | ||||
| 
 | ||||
|  | @ -773,8 +956,8 @@ def heading(self, type, args, level): | |||
| 			print '---', args | ||||
| 
 | ||||
| 	def do_contents(self, args): | ||||
| 		pass | ||||
| 		# self.listcontents('Table of Contents', 999) | ||||
| 	        # pass | ||||
| 		self.listcontents('Table of Contents', 999) | ||||
| 
 | ||||
| 	def do_shortcontents(self, args): | ||||
| 		pass | ||||
|  | @ -821,14 +1004,8 @@ def do_hline(self, args): | |||
| 	# --- Function and variable definitions --- | ||||
| 
 | ||||
| 	def bgn_deffn(self, args): | ||||
| 		self.write('<DL><DT>') | ||||
| 		words = splitwords(args, 2) | ||||
| 		[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) | ||||
| 		self.write('<DL>') | ||||
| 		self.do_deffnx (args) | ||||
| 
 | ||||
| 	def end_deffn(self): | ||||
| 		self.write('</DL>\n') | ||||
|  | @ -845,15 +1022,24 @@ def do_deffnx(self, args): | |||
| 
 | ||||
| 	def bgn_defun(self, args): self.bgn_deffn('Function ' + args) | ||||
| 	end_defun = end_deffn | ||||
| 	def do_defunx(self, args): self.do_deffnx('Function ' + args) | ||||
| 
 | ||||
| 	def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) | ||||
| 	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) | ||||
| 	end_defspec = end_deffn | ||||
| 	def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + 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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@code{' + name + '}') | ||||
|  | @ -863,18 +1049,24 @@ def bgn_defvr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name) | ||||
| 
 | ||||
| 	end_defvr = end_deffn | ||||
| 
 | ||||
| 	def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) | ||||
| 	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) | ||||
| 	end_defopt = end_defvr | ||||
| 	def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for typed languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
|  | @ -883,15 +1075,21 @@ def bgn_deftypefn(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypefn = end_deffn | ||||
| 
 | ||||
| 	def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) | ||||
| 	end_deftypefun = end_deftypefn | ||||
| 	def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + 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) | ||||
| 		[category, datatype, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@code{' + datatype + '} @b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -899,18 +1097,24 @@ def bgn_deftypevr(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name) | ||||
| 
 | ||||
| 	end_deftypevr = end_deftypefn | ||||
| 
 | ||||
| 	def bgn_deftypevar(self, args): | ||||
| 		self.bgn_deftypevr('Variable ' + args) | ||||
| 	end_deftypevar = end_deftypevr | ||||
| 	def do_deftypevarx(self, args): | ||||
| 		self.do_deftypevrx('Variable ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for object-oriented languages --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.write('<DL><DT>') | ||||
| 		self.expand('@b{' + name + '}') | ||||
| 		# If there are too many arguments, show them | ||||
| 		for word in rest: self.expand(' ' + word) | ||||
|  | @ -918,14 +1122,20 @@ def bgn_defcv(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('vr', name + ' @r{of ' + classname + '}') | ||||
| 
 | ||||
| 	end_defcv = end_deftypevr | ||||
| 
 | ||||
| 	def bgn_defivar(self, args): | ||||
| 		self.bgn_defcv('{Instance Variable} ' + args) | ||||
| 	end_defivar = end_defcv | ||||
| 	def do_defivarx(self, args): | ||||
| 		self.do_defcvx('{Instance Variable} ' + 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) | ||||
| 		[category, classname, name], rest = words[:3], words[3:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -934,16 +1144,22 @@ def bgn_defop(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('fn', name + ' @r{on ' + classname + '}') | ||||
| 
 | ||||
| 	end_defop = end_defcv | ||||
| 
 | ||||
| 	def bgn_defmethod(self, args): | ||||
| 		self.bgn_defop('Method ' + args) | ||||
| 	end_defmethod = end_defop | ||||
| 	def do_defmethodx(self, args): | ||||
| 		self.do_defopx('Method ' + args) | ||||
| 
 | ||||
| 	# --- Ditto for data types --- | ||||
| 
 | ||||
| 	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) | ||||
| 		[category, name], rest = words[:2], words[2:] | ||||
| 		self.expand('@b{' + name + '}') | ||||
|  | @ -952,8 +1168,6 @@ def bgn_deftp(self, args): | |||
| 		self.write('<DD>\n') | ||||
| 		self.index('tp', name) | ||||
| 
 | ||||
| 	end_deftp = end_defcv | ||||
| 
 | ||||
| 	# --- Making Lists and Tables | ||||
| 
 | ||||
| 	def bgn_enumerate(self, args): | ||||
|  | @ -1211,15 +1425,18 @@ def makefile(nodename): | |||
| 
 | ||||
| 
 | ||||
| # 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): | ||||
| 	i = 0 | ||||
| 	while i < len(addr): | ||||
| 		c = addr[i] | ||||
| 		if c not in goodchars: | ||||
| 			c = '_' | ||||
| 			c = '-' | ||||
| 			addr = addr[:i] + c + addr[i+1:] | ||||
| 		i = i + len(c) | ||||
| 	return addr | ||||
|  | @ -1252,8 +1469,11 @@ def test(): | |||
| 	while sys.argv[1:2] == ['-d']: | ||||
| 		parser.debugging = parser.debugging + 1 | ||||
| 		del sys.argv[1:2] | ||||
| 	if sys.argv[1] == '-c': | ||||
| 	    parser.cont = 1 | ||||
| 	    del sys.argv[1] | ||||
| 	if len(sys.argv) <> 3: | ||||
| 		print 'usage: texi2html [-d] [-d] inputfile outputdirectory' | ||||
| 		print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' | ||||
| 		sys.exit(2) | ||||
| 	file = sys.argv[1] | ||||
| 	parser.setdirname(sys.argv[2]) | ||||
|  | @ -1272,3 +1492,9 @@ def 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