Commit 02827266 authored by Fred Drake's avatar Fred Drake

(texi2html.py): Tightened the generated HTML slightly. Added -p option to

	print section titles even when the debugging output is not enabled.
	Added -3 option to generate HTML 3.0 constructs where meaningful.

	Removed repititive garbage generation:  the old version added simple
	descriptive comments after every datadesc/funcdesc/*desc entry:

	function(args) -- function of module xxxx
	    Description....

	These comments are no longer generated:

	function(args)
	    Description....
parent 0b95abcb
...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args) ...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args)
spprog = regex.compile('[\n@{}&<>]') # Special characters in running text spprog = regex.compile('[\n@{}&<>]') # Special characters in running text
miprog = regex.compile( \ miprog = regex.compile( \
'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') '^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*')
# menu item (Yuck!) # menu item (Yuck!)
class Node: class HTMLNode:
__doc__ = """ """Some of the parser's functionality is separated into this class.
Some of the parser's functionality is separated into this class.
A Node accumulates its contents, takes care of links to other Nodes A Node accumulates its contents, takes care of links to other Nodes
and saves itself when it is finished and all links are resolved. """ and saves itself when it is finished and all links are resolved.
"""
def __init__ (self, dir, name, topname, title, next, prev, up): DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
type = 0
cont = ''
epilogue = '</BODY></HTML>\n'
def __init__(self, dir, name, topname, title, next, prev, up):
self.dirname = dir self.dirname = dir
self.name = name self.name = name
if topname: if topname:
...@@ -70,66 +76,105 @@ class Node: ...@@ -70,66 +76,105 @@ class Node:
self.prev = prev self.prev = prev
self.up = up self.up = up
self.lines = [] self.lines = []
self.type = 0
self.cont = ''
def write (self, *lines): def write(self, *lines):
map(self.lines.append, lines) map(self.lines.append, lines)
def flush (self): def flush(self):
fp = open (self.dirname + '/' + makefile(self.name), 'w') fp = open(self.dirname + '/' + makefile(self.name), 'w')
fp.write (self.prologue) fp.write(self.prologue)
fp.write (self.text) fp.write(self.text)
fp.write (self.epilogue) fp.write(self.epilogue)
fp.close () fp.close()
def link(self, label, nodename): def link(self, label, nodename, rel=None, rev=None):
if nodename: if nodename:
if string.lower(nodename) == '(dir)': if string.lower(nodename) == '(dir)':
addr = '../dir.html' addr = '../dir.html'
title = ''
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ title = ' TITLE="%s"' % nodename
label, '">', nodename, '</A> \n') self.write(label, ': <A HREF="', addr, '"', \
rel and (' REL=' + rel) or "", \
rev and (' REV=' + rev) or "", \
title, '>', nodename, '</A> \n')
def finalize(self): def finalize(self):
length = len (self.lines) length = len(self.lines)
self.text = string.joinfields (self.lines, '') self.text = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.write ('<HR>\n') self.open_links()
if self.cont != self.next: self.output_links()
self.link('Cont', self.cont) self.close_links()
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 ('<HR>\n')
links = string.joinfields(self.lines, '') links = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.prologue = ('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n' self.prologue = (
'<!-- Converted with texi2html and Python -->\n' self.DOCTYPE +
'<HEAD>\n' '\n<HTML><HEAD>\n'
' <TITLE>' + self.title + '</TITLE>\n' ' <!-- Converted with texi2html and Python -->\n'
'</HEAD><BODY>\n' + \ ' <TITLE>' + self.title + '</TITLE>\n'
links) ' <LINK REL=Next HREF="'
+ makefile(self.next) + '" TITLE="' + self.next + '">\n'
' <LINK REL=Previous HREF="'
+ makefile(self.prev) + '" TITLE="' + self.prev + '">\n'
' <LINK REL=Up HREF="'
+ makefile(self.up) + '" TITLE="' + self.up + '">\n'
'</HEAD><BODY>\n' +
links)
if length > 20: if length > 20:
self.epilogue = '<P>\n%s</BODY>\n' % links self.epilogue = '<P>\n%s</BODY></HTML>\n' % links
else:
self.epilogue = '</BODY>\n' def open_links(self):
self.write('<HR>\n')
def close_links(self):
self.write('<HR>\n')
def output_links(self):
if self.cont != self.next:
self.link(' Cont', self.cont)
self.link(' Next', self.next, rel='Next')
self.link(' Prev', self.prev, rel='Previous')
self.link(' Up', self.up, rel='Up')
if self.name <> self.topname:
self.link(' Top', self.topname)
class HTML3Node(HTMLNode):
DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML Level 3//EN//3.0">'
def open_links(self):
self.write('<DIV>\n <HR>\n')
def close_links(self):
self.write(' <HR>\n</DIV>\n')
class TexinfoParser: class TexinfoParser:
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "(%(id)s)"
FN_SOURCE_PATTERN = '<A NAME=footnoteref%(id)s' \
' HREF="#footnotetext%(id)s">' \
+ FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<A NAME=footnotetext%(id)s' \
' HREF="#footnoteref%(id)s">' \
+ FN_ID_PATTERN + '</A>\n%(text)s<P>\n'
FN_HEADER = '\n<HR NOSHADE SIZE=1 WIDTH=200>\n' \
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>'
Node = HTMLNode
# Initialize an instance # Initialize an instance
def __init__(self): def __init__(self):
self.unknown = {} # statistics about unknown @-commands self.unknown = {} # statistics about unknown @-commands
self.filenames = {} # Check for identical filenames self.filenames = {} # Check for identical filenames
self.debugging = 0 # larger values produce more output self.debugging = 0 # larger values produce more output
self.print_headers = 0 # always print headers?
self.nodefp = None # open file we're writing to self.nodefp = None # open file we're writing to
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
...@@ -209,7 +254,10 @@ class TexinfoParser: ...@@ -209,7 +254,10 @@ class TexinfoParser:
if accu: if accu:
if not self.skip: if not self.skip:
self.process(accu) self.process(accu)
self.write('<P>\n') if self.nofill:
self.write('\n')
else:
self.write('<P>\n')
accu = [] accu = []
else: else:
# Append the line including trailing \n! # Append the line including trailing \n!
...@@ -222,21 +270,21 @@ class TexinfoParser: ...@@ -222,21 +270,21 @@ class TexinfoParser:
print '***', self.stack print '***', self.stack
if self.includedepth == 0: if self.includedepth == 0:
while self.nodestack: while self.nodestack:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] 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:
self.savestack.append (self.savetext) self.savestack.append(self.savetext)
# print '*** Recursively saving text, expect trouble' # 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
if len (self.savestack) > 0: if len(self.savestack) > 0:
self.savetext = self.savestack[-1] self.savetext = self.savestack[-1]
del self.savestack[-1] del self.savestack[-1]
else: else:
...@@ -255,7 +303,7 @@ class TexinfoParser: ...@@ -255,7 +303,7 @@ class TexinfoParser:
elif self.nodefp: elif self.nodefp:
self.nodefp.write(text) self.nodefp.write(text)
elif self.node: elif self.node:
self.node.write (text) 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:
...@@ -265,14 +313,14 @@ class TexinfoParser: ...@@ -265,14 +313,14 @@ class TexinfoParser:
self.writefootnotes() self.writefootnotes()
if self.nodefp: if self.nodefp:
if self.nodelineno > 20: if self.nodelineno > 20:
self.write ('<HR>\n') self.write('<HR>\n')
[name, next, prev, up] = self.nodelinks[:4] [name, next, prev, up] = self.nodelinks[:4]
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 ('<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
...@@ -280,10 +328,10 @@ class TexinfoParser: ...@@ -280,10 +328,10 @@ class TexinfoParser:
if not self.cont and \ if not self.cont and \
(not self.node.type or \ (not self.node.type or \
(self.node.next and self.node.prev and self.node.up)): (self.node.next and self.node.prev and self.node.up)):
self.node.finalize () self.node.finalize()
self.node.flush () self.node.flush()
else: else:
self.nodestack.append (self.node) self.nodestack.append(self.node)
self.node = None self.node = None
self.nodename = '' self.nodename = ''
...@@ -309,7 +357,7 @@ class TexinfoParser: ...@@ -309,7 +357,7 @@ class TexinfoParser:
if nodename[0] == ':': nodename = label if nodename[0] == ':': nodename = label
else: nodename = line[e:f] else: nodename = line[e:f]
punct = line[g:h] punct = line[g:h]
self.write('<LI><A HREF="', self.write(' <LI><A HREF="',
makefile(nodename), makefile(nodename),
'">', nodename, '">', nodename,
'</A>', punct, '\n') '</A>', punct, '\n')
...@@ -333,10 +381,7 @@ class TexinfoParser: ...@@ -333,10 +381,7 @@ class TexinfoParser:
c = text[i] c = text[i]
i = i+1 i = i+1
if c == '\n': if c == '\n':
if self.nofill > 0: self.write('\n')
self.write('<P>\n')
else:
self.write('\n')
continue continue
if c == '<': if c == '<':
self.write('&lt;') self.write('&lt;')
...@@ -477,8 +522,8 @@ class TexinfoParser: ...@@ -477,8 +522,8 @@ class TexinfoParser:
def open_TeX(self): self.write('TeX') 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(self.COPYRIGHT_SYMBOL)
def open_copyright(self): self.write('(C)') def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL)
def close_copyright(self): pass def close_copyright(self): pass
def open_minus(self): self.write('-') def open_minus(self): self.write('-')
...@@ -569,8 +614,8 @@ class TexinfoParser: ...@@ -569,8 +614,8 @@ class TexinfoParser:
def open_code(self): self.write('<CODE>') def open_code(self): self.write('<CODE>')
def close_code(self): self.write('</CODE>') def close_code(self): self.write('</CODE>')
open_t = open_code def open_t(self): self.write('<TT>')
close_t = close_code def close_t(self): self.write('</TT>')
def open_dfn(self): self.write('<DFN>') def open_dfn(self): self.write('<DFN>')
def close_dfn(self): self.write('</DFN>') def close_dfn(self): self.write('</DFN>')
...@@ -578,31 +623,25 @@ class TexinfoParser: ...@@ -578,31 +623,25 @@ class TexinfoParser:
def open_emph(self): self.write('<EM>') def open_emph(self): self.write('<EM>')
def close_emph(self): self.write('</EM>') def close_emph(self): self.write('</EM>')
open_i = open_emph def open_i(self): self.write('<I>')
close_i = close_emph def close_i(self): self.write('</I>')
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(self.FN_SOURCE_PATTERN % {'id': `id`})
'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') self.startsaving()
# 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.collectsavings())
self.footnotes.append(`id`, self.collectsavings())
# self.savetext = None
def writefootnotes(self): def writefootnotes(self):
self.write('\n<HR NOSHADE SIZE=1 WIDTH=200>\n' self.write(self.FN_HEADER)
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>')
for id, text in self.footnotes: for id, text in self.footnotes:
self.write('<A NAME="footnotetext', id, \ self.write(self.FN_TARGET_PATTERN
'" HREF="#footnoteref', id, '">(', \ % {'id': `id`, 'text': text})
id, ')</A>\n', text, '<P>\n')
self.footnotes = [] self.footnotes = []
def open_file(self): self.write('<CODE>') def open_file(self): self.write('<CODE>')
...@@ -623,11 +662,11 @@ class TexinfoParser: ...@@ -623,11 +662,11 @@ class TexinfoParser:
def open_sc(self): self.write('<SMALLCAPS>') def open_sc(self): self.write('<SMALLCAPS>')
def close_sc(self): self.write('</SMALLCAPS>') def close_sc(self): self.write('</SMALLCAPS>')
def open_strong(self): self.write('<B>') def open_strong(self): self.write('<STRONG>')
def close_strong(self): self.write('</B>') def close_strong(self): self.write('</STRONG>')
open_b = open_strong def open_b(self): self.write('<B>')
close_b = close_strong def close_b(self): self.write('</B>')
def open_var(self): self.write('<VAR>') def open_var(self): self.write('<VAR>')
def close_var(self): self.write('</VAR>') def close_var(self): self.write('</VAR>')
...@@ -715,13 +754,13 @@ class TexinfoParser: ...@@ -715,13 +754,13 @@ class TexinfoParser:
def end_tex(self): self.skip = self.skip - 1 def end_tex(self): self.skip = self.skip - 1
def do_set(self, args): def do_set(self, args):
fields = string.splitfields (args, ' ') fields = string.splitfields(args, ' ')
key = fields[0] key = fields[0]
if len(fields) == 1: if len(fields) == 1:
value = 1 value = 1
else: else:
value = string.joinfields (fields[1:], ' ') value = string.joinfields(fields[1:], ' ')
self.values[key]=value self.values[key] = value
print self.values print self.values
def do_clear(self, args): def do_clear(self, args):
...@@ -755,9 +794,9 @@ class TexinfoParser: ...@@ -755,9 +794,9 @@ class TexinfoParser:
self.startsaving() self.startsaving()
def close_value(self): def close_value(self):
key = self.collectsavings () key = self.collectsavings()
if key in self.values.keys(): if key in self.values.keys():
self.write (self.values[key]) self.write(self.values[key])
else: else:
print '*** Undefined value: ', key print '*** Undefined value: ', key
...@@ -770,15 +809,15 @@ class TexinfoParser: ...@@ -770,15 +809,15 @@ class TexinfoParser:
def do_settitle(self, args): def do_settitle(self, args):
print args print args
self.startsaving() self.startsaving()
self.expand (args) self.expand(args)
self.title = self.collectsavings () self.title = self.collectsavings()
print self.title 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.endnode()
self.done = 1 self.done = 1
# --- Title page --- # --- Title page ---
...@@ -790,8 +829,8 @@ class TexinfoParser: ...@@ -790,8 +829,8 @@ class TexinfoParser:
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>')
self.expand (args) self.expand(args)
self.write ('</H1>\n') self.write('</H1>\n')
do_title = do_center do_title = do_center
do_subtitle = do_center do_subtitle = do_center
do_author = do_center do_author = do_center
...@@ -835,8 +874,8 @@ class TexinfoParser: ...@@ -835,8 +874,8 @@ class TexinfoParser:
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
self.node = Node (self.dirname, self.nodename, self.topname, \ self.node = self.Node(self.dirname, self.nodename, self.topname,
title, next, prev, up) title, next, prev, up)
def link(self, label, nodename): def link(self, label, nodename):
if nodename: if nodename:
...@@ -844,27 +883,27 @@ class TexinfoParser: ...@@ -844,27 +883,27 @@ class TexinfoParser:
addr = '../dir.html' addr = '../dir.html'
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ self.write(label, ': <A HREF="', addr, '" TYPE="',
label, '">', nodename, '</A> \n') label, '">', nodename, '</A> \n')
# --- Sectioning commands --- # --- Sectioning commands ---
def popstack (self, type): def popstack(self, type):
if (self.node): if (self.node):
self.node.type = type self.node.type = type
while self.nodestack: while self.nodestack:
if self.nodestack[-1].type > type: if self.nodestack[-1].type > type:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
elif self.nodestack[-1].type == type: elif self.nodestack[-1].type == type:
if not self.nodestack[-1].next: if not self.nodestack[-1].next:
self.nodestack[-1].next = self.node.name self.nodestack[-1].next = self.node.name
if not self.node.prev: if not self.node.prev:
self.node.prev = self.nodestack[-1].name self.node.prev = self.nodestack[-1].name
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
else: else:
if type > 1 and not self.node.up: if type > 1 and not self.node.up:
self.node.up = self.nodestack[-1].name self.node.up = self.nodestack[-1].name
...@@ -872,14 +911,14 @@ class TexinfoParser: ...@@ -872,14 +911,14 @@ class TexinfoParser:
def do_chapter(self, args): def do_chapter(self, args):
self.heading('H1', args, 0) self.heading('H1', args, 0)
self.popstack (1) 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) 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) 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):
...@@ -889,39 +928,39 @@ class TexinfoParser: ...@@ -889,39 +928,39 @@ class TexinfoParser:
def do_section(self, args): def do_section(self, args):
self.heading('H1', args, 1) self.heading('H1', args, 1)
self.popstack (2) 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) 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) 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) 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) 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) 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) 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) 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) self.popstack(4)
def do_subsubheading(self, args): def do_subsubheading(self, args):
self.heading('H3', args, -1) self.heading('H3', args, -1)
...@@ -939,7 +978,7 @@ class TexinfoParser: ...@@ -939,7 +978,7 @@ class TexinfoParser:
self.write('<', type, '>') self.write('<', type, '>')
self.expand(args) self.expand(args)
self.write('</', type, '>\n') self.write('</', type, '>\n')
if self.debugging: if self.debugging or self.print_headers:
print '---', args print '---', args
def do_contents(self, args): def do_contents(self, args):
...@@ -987,24 +1026,19 @@ class TexinfoParser: ...@@ -987,24 +1026,19 @@ class TexinfoParser:
# --- Line lay-out --- # --- Line lay-out ---
def do_sp(self, args): def do_sp(self, args):
# Insert <args> blank lines if self.nofill:
if args: self.write('\n')
try:
n = string.atoi(args)
except string.atoi_error:
n = 1
else: else:
n = 1 self.write('<P>\n')
self.write('<P>\n'*max(n, 0))
def do_hline(self, args): def do_hline(self, args):
self.write ('<HR>') self.write('<HR>')
# --- Function and variable definitions --- # --- Function and variable definitions ---
def bgn_deffn(self, args): def bgn_deffn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deffnx (args) self.do_deffnx(args)
def end_deffn(self): def end_deffn(self):
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1013,10 +1047,10 @@ class TexinfoParser: ...@@ -1013,10 +1047,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_defun(self, args): self.bgn_deffn('Function ' + args) def bgn_defun(self, args): self.bgn_deffn('Function ' + args)
...@@ -1033,7 +1067,7 @@ class TexinfoParser: ...@@ -1033,7 +1067,7 @@ class TexinfoParser:
def bgn_defvr(self, args): def bgn_defvr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defvrx (args) self.do_defvrx(args)
end_defvr = end_deffn end_defvr = end_deffn
...@@ -1041,11 +1075,11 @@ class TexinfoParser: ...@@ -1041,11 +1075,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name) self.index('vr', name)
def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args)
...@@ -1060,7 +1094,7 @@ class TexinfoParser: ...@@ -1060,7 +1094,7 @@ class TexinfoParser:
def bgn_deftypefn(self, args): def bgn_deftypefn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypefnx (args) self.do_deftypefnx(args)
end_deftypefn = end_deffn end_deftypefn = end_deffn
...@@ -1068,10 +1102,10 @@ class TexinfoParser: ...@@ -1068,10 +1102,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, name))
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
...@@ -1081,7 +1115,7 @@ class TexinfoParser: ...@@ -1081,7 +1115,7 @@ class TexinfoParser:
def bgn_deftypevr(self, args): def bgn_deftypevr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypevrx (args) self.do_deftypevrx(args)
end_deftypevr = end_deftypefn end_deftypevr = end_deftypefn
...@@ -1089,11 +1123,11 @@ class TexinfoParser: ...@@ -1089,11 +1123,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_deftypevar(self, args): def bgn_deftypevar(self, args):
...@@ -1114,12 +1148,12 @@ class TexinfoParser: ...@@ -1114,12 +1148,12 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category + ' of ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name + ' @r{of ' + classname + '}') self.index('vr', '%s @r{on %s}' % (name, classname))
def bgn_defivar(self, args): def bgn_defivar(self, args):
self.bgn_defcv('{Instance Variable} ' + args) self.bgn_defcv('{Instance Variable} ' + args)
...@@ -1129,7 +1163,7 @@ class TexinfoParser: ...@@ -1129,7 +1163,7 @@ class TexinfoParser:
def bgn_defop(self, args): def bgn_defop(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defopx (args) self.do_defopx(args)
end_defop = end_defcv end_defop = end_defcv
...@@ -1137,11 +1171,11 @@ class TexinfoParser: ...@@ -1137,11 +1171,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category + ' on ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name + ' @r{on ' + classname + '}') self.index('fn', '%s @r{on %s}' % (name, classname))
def bgn_defmethod(self, args): def bgn_defmethod(self, args):
self.bgn_defop('Method ' + args) self.bgn_defop('Method ' + args)
...@@ -1161,10 +1195,10 @@ class TexinfoParser: ...@@ -1161,10 +1195,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + word) for word in rest: self.expand(' ' + word)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('tp', name) self.index('tp', name)
# --- Making Lists and Tables # --- Making Lists and Tables
...@@ -1218,7 +1252,7 @@ class TexinfoParser: ...@@ -1218,7 +1252,7 @@ class TexinfoParser:
if self.stack and self.stack[-1] == 'table': if self.stack and self.stack[-1] == 'table':
self.write('<DT>') self.write('<DT>')
self.expand(args) self.expand(args)
self.write('<DD>') self.write('\n<DD>')
else: else:
self.write('<LI>') self.write('<LI>')
self.expand(args) self.expand(args)
...@@ -1273,7 +1307,8 @@ class TexinfoParser: ...@@ -1273,7 +1307,8 @@ class TexinfoParser:
def bgn_menu(self, args): def bgn_menu(self, args):
self.write('<DIR>\n') self.write('<DIR>\n')
self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n') self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n')
def end_menu(self): self.write('</DIR>\n') def end_menu(self):
self.write('</DIR>\n')
def bgn_cartouche(self, args): pass def bgn_cartouche(self, args): pass
def end_cartouche(self): pass def end_cartouche(self): pass
...@@ -1366,8 +1401,7 @@ class TexinfoParser: ...@@ -1366,8 +1401,7 @@ class TexinfoParser:
if iscodeindex: key = '@code{' + key + '}' if iscodeindex: key = '@code{' + key + '}'
if key != prevkey: if key != prevkey:
self.expand(key) self.expand(key)
self.write('<DD><A HREF="', makefile(node), \ self.write('\n<DD><A HREF="%s">%s</A>\n' % (makefile(node), node))
'">', node, '</A>\n')
prevkey, prevnode = key, node prevkey, prevnode = key, node
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1382,6 +1416,45 @@ class TexinfoParser: ...@@ -1382,6 +1416,45 @@ class TexinfoParser:
print string.ljust(cmd, 20), self.unknown[cmd] print string.ljust(cmd, 20), self.unknown[cmd]
class TexinfoParserHTML3(TexinfoParser):
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "[%(id)s]"
FN_SOURCE_PATTERN = '<A ID=footnoteref%(id)s ' \
'HREF="#footnotetext%(id)s">' + FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<FN ID=footnotetext%(id)s>\n' \
'<P><A HREF="#footnoteref%(id)s">' + FN_ID_PATTERN \
+ '</A>\n%(text)s</P></FN>\n'
FN_HEADER = '<DIV CLASS=footnotes>\n <HR NOSHADE WIDTH=200>\n' \
' <STRONG><EM>Footnotes</EM></STRONG>\n <P>\n'
Node = HTML3Node
def bgn_quotation(self, args): self.write('<BQ>')
def end_quotation(self): self.write('</BQ>\n')
def bgn_example(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=example>')
def bgn_flushleft(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=flushleft>\n')
def bgn_flushright(self, args):
self.nofill = self.nofill + 1
self.write('<DIV ALIGN=right CLASS=flushright><ADDRESS COMPACT>\n')
def end_flushright(self):
self.write('</ADDRESS></DIV>\n')
self.nofill = self.nofill - 1
def bgn_menu(self, args):
self.write('<UL PLAIN CLASS=menu>\n')
self.write(' <LH>Menu</LH>\n')
def end_menu(self):
self.write('</UL>\n')
# Put @var{} around alphabetic substrings # Put @var{} around alphabetic substrings
def makevar(str): def makevar(str):
return '@var{'+str+'}' return '@var{'+str+'}'
...@@ -1463,16 +1536,35 @@ def increment(s): ...@@ -1463,16 +1536,35 @@ def increment(s):
def test(): def test():
import sys import sys
parser = TexinfoParser() debugging = 0
print_headers = 0
cont = 0
html3 = 0
while sys.argv[1:2] == ['-d']: while sys.argv[1:2] == ['-d']:
parser.debugging = parser.debugging + 1 debugging = debugging + 1
del sys.argv[1:2] del sys.argv[1:2]
if sys.argv[1] == '-p':
print_headers = 1
del sys.argv[1]
if sys.argv[1] == '-c': if sys.argv[1] == '-c':
parser.cont = 1 cont = 1
del sys.argv[1]
if sys.argv[1] == '-3':
html3 = 1
del sys.argv[1] del sys.argv[1]
if len(sys.argv) <> 3: if len(sys.argv) <> 3:
print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' print 'usage: texi2html [-d [-d]] [-p] [-c] inputfile outputdirectory'
sys.exit(2) sys.exit(2)
if html3:
parser = TexinfoParserHTML3()
else:
parser = TexinfoParser()
parser.cont = cont
parser.debugging = debugging
parser.print_headers = print_headers
file = sys.argv[1] file = sys.argv[1]
parser.setdirname(sys.argv[2]) parser.setdirname(sys.argv[2])
if file == '-': if file == '-':
......
...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args) ...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args)
spprog = regex.compile('[\n@{}&<>]') # Special characters in running text spprog = regex.compile('[\n@{}&<>]') # Special characters in running text
miprog = regex.compile( \ miprog = regex.compile( \
'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') '^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*')
# menu item (Yuck!) # menu item (Yuck!)
class Node: class HTMLNode:
__doc__ = """ """Some of the parser's functionality is separated into this class.
Some of the parser's functionality is separated into this class.
A Node accumulates its contents, takes care of links to other Nodes A Node accumulates its contents, takes care of links to other Nodes
and saves itself when it is finished and all links are resolved. """ and saves itself when it is finished and all links are resolved.
"""
def __init__ (self, dir, name, topname, title, next, prev, up): DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
type = 0
cont = ''
epilogue = '</BODY></HTML>\n'
def __init__(self, dir, name, topname, title, next, prev, up):
self.dirname = dir self.dirname = dir
self.name = name self.name = name
if topname: if topname:
...@@ -70,66 +76,105 @@ class Node: ...@@ -70,66 +76,105 @@ class Node:
self.prev = prev self.prev = prev
self.up = up self.up = up
self.lines = [] self.lines = []
self.type = 0
self.cont = ''
def write (self, *lines): def write(self, *lines):
map(self.lines.append, lines) map(self.lines.append, lines)
def flush (self): def flush(self):
fp = open (self.dirname + '/' + makefile(self.name), 'w') fp = open(self.dirname + '/' + makefile(self.name), 'w')
fp.write (self.prologue) fp.write(self.prologue)
fp.write (self.text) fp.write(self.text)
fp.write (self.epilogue) fp.write(self.epilogue)
fp.close () fp.close()
def link(self, label, nodename): def link(self, label, nodename, rel=None, rev=None):
if nodename: if nodename:
if string.lower(nodename) == '(dir)': if string.lower(nodename) == '(dir)':
addr = '../dir.html' addr = '../dir.html'
title = ''
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ title = ' TITLE="%s"' % nodename
label, '">', nodename, '</A> \n') self.write(label, ': <A HREF="', addr, '"', \
rel and (' REL=' + rel) or "", \
rev and (' REV=' + rev) or "", \
title, '>', nodename, '</A> \n')
def finalize(self): def finalize(self):
length = len (self.lines) length = len(self.lines)
self.text = string.joinfields (self.lines, '') self.text = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.write ('<HR>\n') self.open_links()
if self.cont != self.next: self.output_links()
self.link('Cont', self.cont) self.close_links()
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 ('<HR>\n')
links = string.joinfields(self.lines, '') links = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.prologue = ('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n' self.prologue = (
'<!-- Converted with texi2html and Python -->\n' self.DOCTYPE +
'<HEAD>\n' '\n<HTML><HEAD>\n'
' <TITLE>' + self.title + '</TITLE>\n' ' <!-- Converted with texi2html and Python -->\n'
'</HEAD><BODY>\n' + \ ' <TITLE>' + self.title + '</TITLE>\n'
links) ' <LINK REL=Next HREF="'
+ makefile(self.next) + '" TITLE="' + self.next + '">\n'
' <LINK REL=Previous HREF="'
+ makefile(self.prev) + '" TITLE="' + self.prev + '">\n'
' <LINK REL=Up HREF="'
+ makefile(self.up) + '" TITLE="' + self.up + '">\n'
'</HEAD><BODY>\n' +
links)
if length > 20: if length > 20:
self.epilogue = '<P>\n%s</BODY>\n' % links self.epilogue = '<P>\n%s</BODY></HTML>\n' % links
else:
self.epilogue = '</BODY>\n' def open_links(self):
self.write('<HR>\n')
def close_links(self):
self.write('<HR>\n')
def output_links(self):
if self.cont != self.next:
self.link(' Cont', self.cont)
self.link(' Next', self.next, rel='Next')
self.link(' Prev', self.prev, rel='Previous')
self.link(' Up', self.up, rel='Up')
if self.name <> self.topname:
self.link(' Top', self.topname)
class HTML3Node(HTMLNode):
DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML Level 3//EN//3.0">'
def open_links(self):
self.write('<DIV>\n <HR>\n')
def close_links(self):
self.write(' <HR>\n</DIV>\n')
class TexinfoParser: class TexinfoParser:
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "(%(id)s)"
FN_SOURCE_PATTERN = '<A NAME=footnoteref%(id)s' \
' HREF="#footnotetext%(id)s">' \
+ FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<A NAME=footnotetext%(id)s' \
' HREF="#footnoteref%(id)s">' \
+ FN_ID_PATTERN + '</A>\n%(text)s<P>\n'
FN_HEADER = '\n<HR NOSHADE SIZE=1 WIDTH=200>\n' \
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>'
Node = HTMLNode
# Initialize an instance # Initialize an instance
def __init__(self): def __init__(self):
self.unknown = {} # statistics about unknown @-commands self.unknown = {} # statistics about unknown @-commands
self.filenames = {} # Check for identical filenames self.filenames = {} # Check for identical filenames
self.debugging = 0 # larger values produce more output self.debugging = 0 # larger values produce more output
self.print_headers = 0 # always print headers?
self.nodefp = None # open file we're writing to self.nodefp = None # open file we're writing to
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
...@@ -209,7 +254,10 @@ class TexinfoParser: ...@@ -209,7 +254,10 @@ class TexinfoParser:
if accu: if accu:
if not self.skip: if not self.skip:
self.process(accu) self.process(accu)
self.write('<P>\n') if self.nofill:
self.write('\n')
else:
self.write('<P>\n')
accu = [] accu = []
else: else:
# Append the line including trailing \n! # Append the line including trailing \n!
...@@ -222,21 +270,21 @@ class TexinfoParser: ...@@ -222,21 +270,21 @@ class TexinfoParser:
print '***', self.stack print '***', self.stack
if self.includedepth == 0: if self.includedepth == 0:
while self.nodestack: while self.nodestack:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] 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:
self.savestack.append (self.savetext) self.savestack.append(self.savetext)
# print '*** Recursively saving text, expect trouble' # 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
if len (self.savestack) > 0: if len(self.savestack) > 0:
self.savetext = self.savestack[-1] self.savetext = self.savestack[-1]
del self.savestack[-1] del self.savestack[-1]
else: else:
...@@ -255,7 +303,7 @@ class TexinfoParser: ...@@ -255,7 +303,7 @@ class TexinfoParser:
elif self.nodefp: elif self.nodefp:
self.nodefp.write(text) self.nodefp.write(text)
elif self.node: elif self.node:
self.node.write (text) 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:
...@@ -265,14 +313,14 @@ class TexinfoParser: ...@@ -265,14 +313,14 @@ class TexinfoParser:
self.writefootnotes() self.writefootnotes()
if self.nodefp: if self.nodefp:
if self.nodelineno > 20: if self.nodelineno > 20:
self.write ('<HR>\n') self.write('<HR>\n')
[name, next, prev, up] = self.nodelinks[:4] [name, next, prev, up] = self.nodelinks[:4]
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 ('<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
...@@ -280,10 +328,10 @@ class TexinfoParser: ...@@ -280,10 +328,10 @@ class TexinfoParser:
if not self.cont and \ if not self.cont and \
(not self.node.type or \ (not self.node.type or \
(self.node.next and self.node.prev and self.node.up)): (self.node.next and self.node.prev and self.node.up)):
self.node.finalize () self.node.finalize()
self.node.flush () self.node.flush()
else: else:
self.nodestack.append (self.node) self.nodestack.append(self.node)
self.node = None self.node = None
self.nodename = '' self.nodename = ''
...@@ -309,7 +357,7 @@ class TexinfoParser: ...@@ -309,7 +357,7 @@ class TexinfoParser:
if nodename[0] == ':': nodename = label if nodename[0] == ':': nodename = label
else: nodename = line[e:f] else: nodename = line[e:f]
punct = line[g:h] punct = line[g:h]
self.write('<LI><A HREF="', self.write(' <LI><A HREF="',
makefile(nodename), makefile(nodename),
'">', nodename, '">', nodename,
'</A>', punct, '\n') '</A>', punct, '\n')
...@@ -333,10 +381,7 @@ class TexinfoParser: ...@@ -333,10 +381,7 @@ class TexinfoParser:
c = text[i] c = text[i]
i = i+1 i = i+1
if c == '\n': if c == '\n':
if self.nofill > 0: self.write('\n')
self.write('<P>\n')
else:
self.write('\n')
continue continue
if c == '<': if c == '<':
self.write('&lt;') self.write('&lt;')
...@@ -477,8 +522,8 @@ class TexinfoParser: ...@@ -477,8 +522,8 @@ class TexinfoParser:
def open_TeX(self): self.write('TeX') 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(self.COPYRIGHT_SYMBOL)
def open_copyright(self): self.write('(C)') def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL)
def close_copyright(self): pass def close_copyright(self): pass
def open_minus(self): self.write('-') def open_minus(self): self.write('-')
...@@ -569,8 +614,8 @@ class TexinfoParser: ...@@ -569,8 +614,8 @@ class TexinfoParser:
def open_code(self): self.write('<CODE>') def open_code(self): self.write('<CODE>')
def close_code(self): self.write('</CODE>') def close_code(self): self.write('</CODE>')
open_t = open_code def open_t(self): self.write('<TT>')
close_t = close_code def close_t(self): self.write('</TT>')
def open_dfn(self): self.write('<DFN>') def open_dfn(self): self.write('<DFN>')
def close_dfn(self): self.write('</DFN>') def close_dfn(self): self.write('</DFN>')
...@@ -578,31 +623,25 @@ class TexinfoParser: ...@@ -578,31 +623,25 @@ class TexinfoParser:
def open_emph(self): self.write('<EM>') def open_emph(self): self.write('<EM>')
def close_emph(self): self.write('</EM>') def close_emph(self): self.write('</EM>')
open_i = open_emph def open_i(self): self.write('<I>')
close_i = close_emph def close_i(self): self.write('</I>')
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(self.FN_SOURCE_PATTERN % {'id': `id`})
'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') self.startsaving()
# 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.collectsavings())
self.footnotes.append(`id`, self.collectsavings())
# self.savetext = None
def writefootnotes(self): def writefootnotes(self):
self.write('\n<HR NOSHADE SIZE=1 WIDTH=200>\n' self.write(self.FN_HEADER)
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>')
for id, text in self.footnotes: for id, text in self.footnotes:
self.write('<A NAME="footnotetext', id, \ self.write(self.FN_TARGET_PATTERN
'" HREF="#footnoteref', id, '">(', \ % {'id': `id`, 'text': text})
id, ')</A>\n', text, '<P>\n')
self.footnotes = [] self.footnotes = []
def open_file(self): self.write('<CODE>') def open_file(self): self.write('<CODE>')
...@@ -623,11 +662,11 @@ class TexinfoParser: ...@@ -623,11 +662,11 @@ class TexinfoParser:
def open_sc(self): self.write('<SMALLCAPS>') def open_sc(self): self.write('<SMALLCAPS>')
def close_sc(self): self.write('</SMALLCAPS>') def close_sc(self): self.write('</SMALLCAPS>')
def open_strong(self): self.write('<B>') def open_strong(self): self.write('<STRONG>')
def close_strong(self): self.write('</B>') def close_strong(self): self.write('</STRONG>')
open_b = open_strong def open_b(self): self.write('<B>')
close_b = close_strong def close_b(self): self.write('</B>')
def open_var(self): self.write('<VAR>') def open_var(self): self.write('<VAR>')
def close_var(self): self.write('</VAR>') def close_var(self): self.write('</VAR>')
...@@ -715,13 +754,13 @@ class TexinfoParser: ...@@ -715,13 +754,13 @@ class TexinfoParser:
def end_tex(self): self.skip = self.skip - 1 def end_tex(self): self.skip = self.skip - 1
def do_set(self, args): def do_set(self, args):
fields = string.splitfields (args, ' ') fields = string.splitfields(args, ' ')
key = fields[0] key = fields[0]
if len(fields) == 1: if len(fields) == 1:
value = 1 value = 1
else: else:
value = string.joinfields (fields[1:], ' ') value = string.joinfields(fields[1:], ' ')
self.values[key]=value self.values[key] = value
print self.values print self.values
def do_clear(self, args): def do_clear(self, args):
...@@ -755,9 +794,9 @@ class TexinfoParser: ...@@ -755,9 +794,9 @@ class TexinfoParser:
self.startsaving() self.startsaving()
def close_value(self): def close_value(self):
key = self.collectsavings () key = self.collectsavings()
if key in self.values.keys(): if key in self.values.keys():
self.write (self.values[key]) self.write(self.values[key])
else: else:
print '*** Undefined value: ', key print '*** Undefined value: ', key
...@@ -770,15 +809,15 @@ class TexinfoParser: ...@@ -770,15 +809,15 @@ class TexinfoParser:
def do_settitle(self, args): def do_settitle(self, args):
print args print args
self.startsaving() self.startsaving()
self.expand (args) self.expand(args)
self.title = self.collectsavings () self.title = self.collectsavings()
print self.title 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.endnode()
self.done = 1 self.done = 1
# --- Title page --- # --- Title page ---
...@@ -790,8 +829,8 @@ class TexinfoParser: ...@@ -790,8 +829,8 @@ class TexinfoParser:
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>')
self.expand (args) self.expand(args)
self.write ('</H1>\n') self.write('</H1>\n')
do_title = do_center do_title = do_center
do_subtitle = do_center do_subtitle = do_center
do_author = do_center do_author = do_center
...@@ -835,8 +874,8 @@ class TexinfoParser: ...@@ -835,8 +874,8 @@ class TexinfoParser:
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
self.node = Node (self.dirname, self.nodename, self.topname, \ self.node = self.Node(self.dirname, self.nodename, self.topname,
title, next, prev, up) title, next, prev, up)
def link(self, label, nodename): def link(self, label, nodename):
if nodename: if nodename:
...@@ -844,27 +883,27 @@ class TexinfoParser: ...@@ -844,27 +883,27 @@ class TexinfoParser:
addr = '../dir.html' addr = '../dir.html'
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ self.write(label, ': <A HREF="', addr, '" TYPE="',
label, '">', nodename, '</A> \n') label, '">', nodename, '</A> \n')
# --- Sectioning commands --- # --- Sectioning commands ---
def popstack (self, type): def popstack(self, type):
if (self.node): if (self.node):
self.node.type = type self.node.type = type
while self.nodestack: while self.nodestack:
if self.nodestack[-1].type > type: if self.nodestack[-1].type > type:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
elif self.nodestack[-1].type == type: elif self.nodestack[-1].type == type:
if not self.nodestack[-1].next: if not self.nodestack[-1].next:
self.nodestack[-1].next = self.node.name self.nodestack[-1].next = self.node.name
if not self.node.prev: if not self.node.prev:
self.node.prev = self.nodestack[-1].name self.node.prev = self.nodestack[-1].name
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
else: else:
if type > 1 and not self.node.up: if type > 1 and not self.node.up:
self.node.up = self.nodestack[-1].name self.node.up = self.nodestack[-1].name
...@@ -872,14 +911,14 @@ class TexinfoParser: ...@@ -872,14 +911,14 @@ class TexinfoParser:
def do_chapter(self, args): def do_chapter(self, args):
self.heading('H1', args, 0) self.heading('H1', args, 0)
self.popstack (1) 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) 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) 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):
...@@ -889,39 +928,39 @@ class TexinfoParser: ...@@ -889,39 +928,39 @@ class TexinfoParser:
def do_section(self, args): def do_section(self, args):
self.heading('H1', args, 1) self.heading('H1', args, 1)
self.popstack (2) 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) 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) 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) 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) 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) 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) 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) 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) self.popstack(4)
def do_subsubheading(self, args): def do_subsubheading(self, args):
self.heading('H3', args, -1) self.heading('H3', args, -1)
...@@ -939,7 +978,7 @@ class TexinfoParser: ...@@ -939,7 +978,7 @@ class TexinfoParser:
self.write('<', type, '>') self.write('<', type, '>')
self.expand(args) self.expand(args)
self.write('</', type, '>\n') self.write('</', type, '>\n')
if self.debugging: if self.debugging or self.print_headers:
print '---', args print '---', args
def do_contents(self, args): def do_contents(self, args):
...@@ -987,24 +1026,19 @@ class TexinfoParser: ...@@ -987,24 +1026,19 @@ class TexinfoParser:
# --- Line lay-out --- # --- Line lay-out ---
def do_sp(self, args): def do_sp(self, args):
# Insert <args> blank lines if self.nofill:
if args: self.write('\n')
try:
n = string.atoi(args)
except string.atoi_error:
n = 1
else: else:
n = 1 self.write('<P>\n')
self.write('<P>\n'*max(n, 0))
def do_hline(self, args): def do_hline(self, args):
self.write ('<HR>') self.write('<HR>')
# --- Function and variable definitions --- # --- Function and variable definitions ---
def bgn_deffn(self, args): def bgn_deffn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deffnx (args) self.do_deffnx(args)
def end_deffn(self): def end_deffn(self):
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1013,10 +1047,10 @@ class TexinfoParser: ...@@ -1013,10 +1047,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_defun(self, args): self.bgn_deffn('Function ' + args) def bgn_defun(self, args): self.bgn_deffn('Function ' + args)
...@@ -1033,7 +1067,7 @@ class TexinfoParser: ...@@ -1033,7 +1067,7 @@ class TexinfoParser:
def bgn_defvr(self, args): def bgn_defvr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defvrx (args) self.do_defvrx(args)
end_defvr = end_deffn end_defvr = end_deffn
...@@ -1041,11 +1075,11 @@ class TexinfoParser: ...@@ -1041,11 +1075,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name) self.index('vr', name)
def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args)
...@@ -1060,7 +1094,7 @@ class TexinfoParser: ...@@ -1060,7 +1094,7 @@ class TexinfoParser:
def bgn_deftypefn(self, args): def bgn_deftypefn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypefnx (args) self.do_deftypefnx(args)
end_deftypefn = end_deffn end_deftypefn = end_deffn
...@@ -1068,10 +1102,10 @@ class TexinfoParser: ...@@ -1068,10 +1102,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, name))
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
...@@ -1081,7 +1115,7 @@ class TexinfoParser: ...@@ -1081,7 +1115,7 @@ class TexinfoParser:
def bgn_deftypevr(self, args): def bgn_deftypevr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypevrx (args) self.do_deftypevrx(args)
end_deftypevr = end_deftypefn end_deftypevr = end_deftypefn
...@@ -1089,11 +1123,11 @@ class TexinfoParser: ...@@ -1089,11 +1123,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_deftypevar(self, args): def bgn_deftypevar(self, args):
...@@ -1114,12 +1148,12 @@ class TexinfoParser: ...@@ -1114,12 +1148,12 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category + ' of ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name + ' @r{of ' + classname + '}') self.index('vr', '%s @r{on %s}' % (name, classname))
def bgn_defivar(self, args): def bgn_defivar(self, args):
self.bgn_defcv('{Instance Variable} ' + args) self.bgn_defcv('{Instance Variable} ' + args)
...@@ -1129,7 +1163,7 @@ class TexinfoParser: ...@@ -1129,7 +1163,7 @@ class TexinfoParser:
def bgn_defop(self, args): def bgn_defop(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defopx (args) self.do_defopx(args)
end_defop = end_defcv end_defop = end_defcv
...@@ -1137,11 +1171,11 @@ class TexinfoParser: ...@@ -1137,11 +1171,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category + ' on ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name + ' @r{on ' + classname + '}') self.index('fn', '%s @r{on %s}' % (name, classname))
def bgn_defmethod(self, args): def bgn_defmethod(self, args):
self.bgn_defop('Method ' + args) self.bgn_defop('Method ' + args)
...@@ -1161,10 +1195,10 @@ class TexinfoParser: ...@@ -1161,10 +1195,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + word) for word in rest: self.expand(' ' + word)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('tp', name) self.index('tp', name)
# --- Making Lists and Tables # --- Making Lists and Tables
...@@ -1218,7 +1252,7 @@ class TexinfoParser: ...@@ -1218,7 +1252,7 @@ class TexinfoParser:
if self.stack and self.stack[-1] == 'table': if self.stack and self.stack[-1] == 'table':
self.write('<DT>') self.write('<DT>')
self.expand(args) self.expand(args)
self.write('<DD>') self.write('\n<DD>')
else: else:
self.write('<LI>') self.write('<LI>')
self.expand(args) self.expand(args)
...@@ -1273,7 +1307,8 @@ class TexinfoParser: ...@@ -1273,7 +1307,8 @@ class TexinfoParser:
def bgn_menu(self, args): def bgn_menu(self, args):
self.write('<DIR>\n') self.write('<DIR>\n')
self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n') self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n')
def end_menu(self): self.write('</DIR>\n') def end_menu(self):
self.write('</DIR>\n')
def bgn_cartouche(self, args): pass def bgn_cartouche(self, args): pass
def end_cartouche(self): pass def end_cartouche(self): pass
...@@ -1366,8 +1401,7 @@ class TexinfoParser: ...@@ -1366,8 +1401,7 @@ class TexinfoParser:
if iscodeindex: key = '@code{' + key + '}' if iscodeindex: key = '@code{' + key + '}'
if key != prevkey: if key != prevkey:
self.expand(key) self.expand(key)
self.write('<DD><A HREF="', makefile(node), \ self.write('\n<DD><A HREF="%s">%s</A>\n' % (makefile(node), node))
'">', node, '</A>\n')
prevkey, prevnode = key, node prevkey, prevnode = key, node
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1382,6 +1416,45 @@ class TexinfoParser: ...@@ -1382,6 +1416,45 @@ class TexinfoParser:
print string.ljust(cmd, 20), self.unknown[cmd] print string.ljust(cmd, 20), self.unknown[cmd]
class TexinfoParserHTML3(TexinfoParser):
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "[%(id)s]"
FN_SOURCE_PATTERN = '<A ID=footnoteref%(id)s ' \
'HREF="#footnotetext%(id)s">' + FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<FN ID=footnotetext%(id)s>\n' \
'<P><A HREF="#footnoteref%(id)s">' + FN_ID_PATTERN \
+ '</A>\n%(text)s</P></FN>\n'
FN_HEADER = '<DIV CLASS=footnotes>\n <HR NOSHADE WIDTH=200>\n' \
' <STRONG><EM>Footnotes</EM></STRONG>\n <P>\n'
Node = HTML3Node
def bgn_quotation(self, args): self.write('<BQ>')
def end_quotation(self): self.write('</BQ>\n')
def bgn_example(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=example>')
def bgn_flushleft(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=flushleft>\n')
def bgn_flushright(self, args):
self.nofill = self.nofill + 1
self.write('<DIV ALIGN=right CLASS=flushright><ADDRESS COMPACT>\n')
def end_flushright(self):
self.write('</ADDRESS></DIV>\n')
self.nofill = self.nofill - 1
def bgn_menu(self, args):
self.write('<UL PLAIN CLASS=menu>\n')
self.write(' <LH>Menu</LH>\n')
def end_menu(self):
self.write('</UL>\n')
# Put @var{} around alphabetic substrings # Put @var{} around alphabetic substrings
def makevar(str): def makevar(str):
return '@var{'+str+'}' return '@var{'+str+'}'
...@@ -1463,16 +1536,35 @@ def increment(s): ...@@ -1463,16 +1536,35 @@ def increment(s):
def test(): def test():
import sys import sys
parser = TexinfoParser() debugging = 0
print_headers = 0
cont = 0
html3 = 0
while sys.argv[1:2] == ['-d']: while sys.argv[1:2] == ['-d']:
parser.debugging = parser.debugging + 1 debugging = debugging + 1
del sys.argv[1:2] del sys.argv[1:2]
if sys.argv[1] == '-p':
print_headers = 1
del sys.argv[1]
if sys.argv[1] == '-c': if sys.argv[1] == '-c':
parser.cont = 1 cont = 1
del sys.argv[1]
if sys.argv[1] == '-3':
html3 = 1
del sys.argv[1] del sys.argv[1]
if len(sys.argv) <> 3: if len(sys.argv) <> 3:
print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' print 'usage: texi2html [-d [-d]] [-p] [-c] inputfile outputdirectory'
sys.exit(2) sys.exit(2)
if html3:
parser = TexinfoParserHTML3()
else:
parser = TexinfoParser()
parser.cont = cont
parser.debugging = debugging
parser.print_headers = print_headers
file = sys.argv[1] file = sys.argv[1]
parser.setdirname(sys.argv[2]) parser.setdirname(sys.argv[2])
if file == '-': if file == '-':
......
...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args) ...@@ -48,17 +48,23 @@ kwprog = regex.compile('@[a-z]+') # Keyword (embedded, usually with {} args)
spprog = regex.compile('[\n@{}&<>]') # Special characters in running text spprog = regex.compile('[\n@{}&<>]') # Special characters in running text
miprog = regex.compile( \ miprog = regex.compile( \
'^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*') '^\* \([^:]*\):\(:\|[ \t]*\([^\t,\n.]+\)\([^ \t\n]*\)\)[ \t\n]*')
# menu item (Yuck!) # menu item (Yuck!)
class Node: class HTMLNode:
__doc__ = """ """Some of the parser's functionality is separated into this class.
Some of the parser's functionality is separated into this class.
A Node accumulates its contents, takes care of links to other Nodes A Node accumulates its contents, takes care of links to other Nodes
and saves itself when it is finished and all links are resolved. """ and saves itself when it is finished and all links are resolved.
"""
def __init__ (self, dir, name, topname, title, next, prev, up): DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
type = 0
cont = ''
epilogue = '</BODY></HTML>\n'
def __init__(self, dir, name, topname, title, next, prev, up):
self.dirname = dir self.dirname = dir
self.name = name self.name = name
if topname: if topname:
...@@ -70,66 +76,105 @@ class Node: ...@@ -70,66 +76,105 @@ class Node:
self.prev = prev self.prev = prev
self.up = up self.up = up
self.lines = [] self.lines = []
self.type = 0
self.cont = ''
def write (self, *lines): def write(self, *lines):
map(self.lines.append, lines) map(self.lines.append, lines)
def flush (self): def flush(self):
fp = open (self.dirname + '/' + makefile(self.name), 'w') fp = open(self.dirname + '/' + makefile(self.name), 'w')
fp.write (self.prologue) fp.write(self.prologue)
fp.write (self.text) fp.write(self.text)
fp.write (self.epilogue) fp.write(self.epilogue)
fp.close () fp.close()
def link(self, label, nodename): def link(self, label, nodename, rel=None, rev=None):
if nodename: if nodename:
if string.lower(nodename) == '(dir)': if string.lower(nodename) == '(dir)':
addr = '../dir.html' addr = '../dir.html'
title = ''
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ title = ' TITLE="%s"' % nodename
label, '">', nodename, '</A> \n') self.write(label, ': <A HREF="', addr, '"', \
rel and (' REL=' + rel) or "", \
rev and (' REV=' + rev) or "", \
title, '>', nodename, '</A> \n')
def finalize(self): def finalize(self):
length = len (self.lines) length = len(self.lines)
self.text = string.joinfields (self.lines, '') self.text = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.write ('<HR>\n') self.open_links()
if self.cont != self.next: self.output_links()
self.link('Cont', self.cont) self.close_links()
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 ('<HR>\n')
links = string.joinfields(self.lines, '') links = string.joinfields(self.lines, '')
self.lines = [] self.lines = []
self.prologue = ('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n' self.prologue = (
'<!-- Converted with texi2html and Python -->\n' self.DOCTYPE +
'<HEAD>\n' '\n<HTML><HEAD>\n'
' <TITLE>' + self.title + '</TITLE>\n' ' <!-- Converted with texi2html and Python -->\n'
'</HEAD><BODY>\n' + \ ' <TITLE>' + self.title + '</TITLE>\n'
links) ' <LINK REL=Next HREF="'
+ makefile(self.next) + '" TITLE="' + self.next + '">\n'
' <LINK REL=Previous HREF="'
+ makefile(self.prev) + '" TITLE="' + self.prev + '">\n'
' <LINK REL=Up HREF="'
+ makefile(self.up) + '" TITLE="' + self.up + '">\n'
'</HEAD><BODY>\n' +
links)
if length > 20: if length > 20:
self.epilogue = '<P>\n%s</BODY>\n' % links self.epilogue = '<P>\n%s</BODY></HTML>\n' % links
else:
self.epilogue = '</BODY>\n' def open_links(self):
self.write('<HR>\n')
def close_links(self):
self.write('<HR>\n')
def output_links(self):
if self.cont != self.next:
self.link(' Cont', self.cont)
self.link(' Next', self.next, rel='Next')
self.link(' Prev', self.prev, rel='Previous')
self.link(' Up', self.up, rel='Up')
if self.name <> self.topname:
self.link(' Top', self.topname)
class HTML3Node(HTMLNode):
DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML Level 3//EN//3.0">'
def open_links(self):
self.write('<DIV>\n <HR>\n')
def close_links(self):
self.write(' <HR>\n</DIV>\n')
class TexinfoParser: class TexinfoParser:
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "(%(id)s)"
FN_SOURCE_PATTERN = '<A NAME=footnoteref%(id)s' \
' HREF="#footnotetext%(id)s">' \
+ FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<A NAME=footnotetext%(id)s' \
' HREF="#footnoteref%(id)s">' \
+ FN_ID_PATTERN + '</A>\n%(text)s<P>\n'
FN_HEADER = '\n<HR NOSHADE SIZE=1 WIDTH=200>\n' \
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>'
Node = HTMLNode
# Initialize an instance # Initialize an instance
def __init__(self): def __init__(self):
self.unknown = {} # statistics about unknown @-commands self.unknown = {} # statistics about unknown @-commands
self.filenames = {} # Check for identical filenames self.filenames = {} # Check for identical filenames
self.debugging = 0 # larger values produce more output self.debugging = 0 # larger values produce more output
self.print_headers = 0 # always print headers?
self.nodefp = None # open file we're writing to self.nodefp = None # open file we're writing to
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
...@@ -209,7 +254,10 @@ class TexinfoParser: ...@@ -209,7 +254,10 @@ class TexinfoParser:
if accu: if accu:
if not self.skip: if not self.skip:
self.process(accu) self.process(accu)
self.write('<P>\n') if self.nofill:
self.write('\n')
else:
self.write('<P>\n')
accu = [] accu = []
else: else:
# Append the line including trailing \n! # Append the line including trailing \n!
...@@ -222,21 +270,21 @@ class TexinfoParser: ...@@ -222,21 +270,21 @@ class TexinfoParser:
print '***', self.stack print '***', self.stack
if self.includedepth == 0: if self.includedepth == 0:
while self.nodestack: while self.nodestack:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] 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:
self.savestack.append (self.savetext) self.savestack.append(self.savetext)
# print '*** Recursively saving text, expect trouble' # 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
if len (self.savestack) > 0: if len(self.savestack) > 0:
self.savetext = self.savestack[-1] self.savetext = self.savestack[-1]
del self.savestack[-1] del self.savestack[-1]
else: else:
...@@ -255,7 +303,7 @@ class TexinfoParser: ...@@ -255,7 +303,7 @@ class TexinfoParser:
elif self.nodefp: elif self.nodefp:
self.nodefp.write(text) self.nodefp.write(text)
elif self.node: elif self.node:
self.node.write (text) 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:
...@@ -265,14 +313,14 @@ class TexinfoParser: ...@@ -265,14 +313,14 @@ class TexinfoParser:
self.writefootnotes() self.writefootnotes()
if self.nodefp: if self.nodefp:
if self.nodelineno > 20: if self.nodelineno > 20:
self.write ('<HR>\n') self.write('<HR>\n')
[name, next, prev, up] = self.nodelinks[:4] [name, next, prev, up] = self.nodelinks[:4]
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 ('<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
...@@ -280,10 +328,10 @@ class TexinfoParser: ...@@ -280,10 +328,10 @@ class TexinfoParser:
if not self.cont and \ if not self.cont and \
(not self.node.type or \ (not self.node.type or \
(self.node.next and self.node.prev and self.node.up)): (self.node.next and self.node.prev and self.node.up)):
self.node.finalize () self.node.finalize()
self.node.flush () self.node.flush()
else: else:
self.nodestack.append (self.node) self.nodestack.append(self.node)
self.node = None self.node = None
self.nodename = '' self.nodename = ''
...@@ -309,7 +357,7 @@ class TexinfoParser: ...@@ -309,7 +357,7 @@ class TexinfoParser:
if nodename[0] == ':': nodename = label if nodename[0] == ':': nodename = label
else: nodename = line[e:f] else: nodename = line[e:f]
punct = line[g:h] punct = line[g:h]
self.write('<LI><A HREF="', self.write(' <LI><A HREF="',
makefile(nodename), makefile(nodename),
'">', nodename, '">', nodename,
'</A>', punct, '\n') '</A>', punct, '\n')
...@@ -333,10 +381,7 @@ class TexinfoParser: ...@@ -333,10 +381,7 @@ class TexinfoParser:
c = text[i] c = text[i]
i = i+1 i = i+1
if c == '\n': if c == '\n':
if self.nofill > 0: self.write('\n')
self.write('<P>\n')
else:
self.write('\n')
continue continue
if c == '<': if c == '<':
self.write('&lt;') self.write('&lt;')
...@@ -477,8 +522,8 @@ class TexinfoParser: ...@@ -477,8 +522,8 @@ class TexinfoParser:
def open_TeX(self): self.write('TeX') 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(self.COPYRIGHT_SYMBOL)
def open_copyright(self): self.write('(C)') def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL)
def close_copyright(self): pass def close_copyright(self): pass
def open_minus(self): self.write('-') def open_minus(self): self.write('-')
...@@ -569,8 +614,8 @@ class TexinfoParser: ...@@ -569,8 +614,8 @@ class TexinfoParser:
def open_code(self): self.write('<CODE>') def open_code(self): self.write('<CODE>')
def close_code(self): self.write('</CODE>') def close_code(self): self.write('</CODE>')
open_t = open_code def open_t(self): self.write('<TT>')
close_t = close_code def close_t(self): self.write('</TT>')
def open_dfn(self): self.write('<DFN>') def open_dfn(self): self.write('<DFN>')
def close_dfn(self): self.write('</DFN>') def close_dfn(self): self.write('</DFN>')
...@@ -578,31 +623,25 @@ class TexinfoParser: ...@@ -578,31 +623,25 @@ class TexinfoParser:
def open_emph(self): self.write('<EM>') def open_emph(self): self.write('<EM>')
def close_emph(self): self.write('</EM>') def close_emph(self): self.write('</EM>')
open_i = open_emph def open_i(self): self.write('<I>')
close_i = close_emph def close_i(self): self.write('</I>')
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(self.FN_SOURCE_PATTERN % {'id': `id`})
'" HREF="#footnotetext', `id`, '">(', `id`, ')</A>') self.startsaving()
# 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.collectsavings())
self.footnotes.append(`id`, self.collectsavings())
# self.savetext = None
def writefootnotes(self): def writefootnotes(self):
self.write('\n<HR NOSHADE SIZE=1 WIDTH=200>\n' self.write(self.FN_HEADER)
'<STRONG><EM>Footnotes</EM></STRONG>\n<P>')
for id, text in self.footnotes: for id, text in self.footnotes:
self.write('<A NAME="footnotetext', id, \ self.write(self.FN_TARGET_PATTERN
'" HREF="#footnoteref', id, '">(', \ % {'id': `id`, 'text': text})
id, ')</A>\n', text, '<P>\n')
self.footnotes = [] self.footnotes = []
def open_file(self): self.write('<CODE>') def open_file(self): self.write('<CODE>')
...@@ -623,11 +662,11 @@ class TexinfoParser: ...@@ -623,11 +662,11 @@ class TexinfoParser:
def open_sc(self): self.write('<SMALLCAPS>') def open_sc(self): self.write('<SMALLCAPS>')
def close_sc(self): self.write('</SMALLCAPS>') def close_sc(self): self.write('</SMALLCAPS>')
def open_strong(self): self.write('<B>') def open_strong(self): self.write('<STRONG>')
def close_strong(self): self.write('</B>') def close_strong(self): self.write('</STRONG>')
open_b = open_strong def open_b(self): self.write('<B>')
close_b = close_strong def close_b(self): self.write('</B>')
def open_var(self): self.write('<VAR>') def open_var(self): self.write('<VAR>')
def close_var(self): self.write('</VAR>') def close_var(self): self.write('</VAR>')
...@@ -715,13 +754,13 @@ class TexinfoParser: ...@@ -715,13 +754,13 @@ class TexinfoParser:
def end_tex(self): self.skip = self.skip - 1 def end_tex(self): self.skip = self.skip - 1
def do_set(self, args): def do_set(self, args):
fields = string.splitfields (args, ' ') fields = string.splitfields(args, ' ')
key = fields[0] key = fields[0]
if len(fields) == 1: if len(fields) == 1:
value = 1 value = 1
else: else:
value = string.joinfields (fields[1:], ' ') value = string.joinfields(fields[1:], ' ')
self.values[key]=value self.values[key] = value
print self.values print self.values
def do_clear(self, args): def do_clear(self, args):
...@@ -755,9 +794,9 @@ class TexinfoParser: ...@@ -755,9 +794,9 @@ class TexinfoParser:
self.startsaving() self.startsaving()
def close_value(self): def close_value(self):
key = self.collectsavings () key = self.collectsavings()
if key in self.values.keys(): if key in self.values.keys():
self.write (self.values[key]) self.write(self.values[key])
else: else:
print '*** Undefined value: ', key print '*** Undefined value: ', key
...@@ -770,15 +809,15 @@ class TexinfoParser: ...@@ -770,15 +809,15 @@ class TexinfoParser:
def do_settitle(self, args): def do_settitle(self, args):
print args print args
self.startsaving() self.startsaving()
self.expand (args) self.expand(args)
self.title = self.collectsavings () self.title = self.collectsavings()
print self.title 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.endnode()
self.done = 1 self.done = 1
# --- Title page --- # --- Title page ---
...@@ -790,8 +829,8 @@ class TexinfoParser: ...@@ -790,8 +829,8 @@ class TexinfoParser:
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>')
self.expand (args) self.expand(args)
self.write ('</H1>\n') self.write('</H1>\n')
do_title = do_center do_title = do_center
do_subtitle = do_center do_subtitle = do_center
do_author = do_center do_author = do_center
...@@ -835,8 +874,8 @@ class TexinfoParser: ...@@ -835,8 +874,8 @@ class TexinfoParser:
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
self.node = Node (self.dirname, self.nodename, self.topname, \ self.node = self.Node(self.dirname, self.nodename, self.topname,
title, next, prev, up) title, next, prev, up)
def link(self, label, nodename): def link(self, label, nodename):
if nodename: if nodename:
...@@ -844,27 +883,27 @@ class TexinfoParser: ...@@ -844,27 +883,27 @@ class TexinfoParser:
addr = '../dir.html' addr = '../dir.html'
else: else:
addr = makefile(nodename) addr = makefile(nodename)
self.write(label, ': <A HREF="', addr, '" TYPE="', \ self.write(label, ': <A HREF="', addr, '" TYPE="',
label, '">', nodename, '</A> \n') label, '">', nodename, '</A> \n')
# --- Sectioning commands --- # --- Sectioning commands ---
def popstack (self, type): def popstack(self, type):
if (self.node): if (self.node):
self.node.type = type self.node.type = type
while self.nodestack: while self.nodestack:
if self.nodestack[-1].type > type: if self.nodestack[-1].type > type:
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
elif self.nodestack[-1].type == type: elif self.nodestack[-1].type == type:
if not self.nodestack[-1].next: if not self.nodestack[-1].next:
self.nodestack[-1].next = self.node.name self.nodestack[-1].next = self.node.name
if not self.node.prev: if not self.node.prev:
self.node.prev = self.nodestack[-1].name self.node.prev = self.nodestack[-1].name
self.nodestack[-1].finalize () self.nodestack[-1].finalize()
self.nodestack[-1].flush () self.nodestack[-1].flush()
del self.nodestack [-1] del self.nodestack[-1]
else: else:
if type > 1 and not self.node.up: if type > 1 and not self.node.up:
self.node.up = self.nodestack[-1].name self.node.up = self.nodestack[-1].name
...@@ -872,14 +911,14 @@ class TexinfoParser: ...@@ -872,14 +911,14 @@ class TexinfoParser:
def do_chapter(self, args): def do_chapter(self, args):
self.heading('H1', args, 0) self.heading('H1', args, 0)
self.popstack (1) 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) 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) 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):
...@@ -889,39 +928,39 @@ class TexinfoParser: ...@@ -889,39 +928,39 @@ class TexinfoParser:
def do_section(self, args): def do_section(self, args):
self.heading('H1', args, 1) self.heading('H1', args, 1)
self.popstack (2) 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) 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) 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) 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) 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) 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) 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) 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) self.popstack(4)
def do_subsubheading(self, args): def do_subsubheading(self, args):
self.heading('H3', args, -1) self.heading('H3', args, -1)
...@@ -939,7 +978,7 @@ class TexinfoParser: ...@@ -939,7 +978,7 @@ class TexinfoParser:
self.write('<', type, '>') self.write('<', type, '>')
self.expand(args) self.expand(args)
self.write('</', type, '>\n') self.write('</', type, '>\n')
if self.debugging: if self.debugging or self.print_headers:
print '---', args print '---', args
def do_contents(self, args): def do_contents(self, args):
...@@ -987,24 +1026,19 @@ class TexinfoParser: ...@@ -987,24 +1026,19 @@ class TexinfoParser:
# --- Line lay-out --- # --- Line lay-out ---
def do_sp(self, args): def do_sp(self, args):
# Insert <args> blank lines if self.nofill:
if args: self.write('\n')
try:
n = string.atoi(args)
except string.atoi_error:
n = 1
else: else:
n = 1 self.write('<P>\n')
self.write('<P>\n'*max(n, 0))
def do_hline(self, args): def do_hline(self, args):
self.write ('<HR>') self.write('<HR>')
# --- Function and variable definitions --- # --- Function and variable definitions ---
def bgn_deffn(self, args): def bgn_deffn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deffnx (args) self.do_deffnx(args)
def end_deffn(self): def end_deffn(self):
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1013,10 +1047,10 @@ class TexinfoParser: ...@@ -1013,10 +1047,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_defun(self, args): self.bgn_deffn('Function ' + args) def bgn_defun(self, args): self.bgn_deffn('Function ' + args)
...@@ -1033,7 +1067,7 @@ class TexinfoParser: ...@@ -1033,7 +1067,7 @@ class TexinfoParser:
def bgn_defvr(self, args): def bgn_defvr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defvrx (args) self.do_defvrx(args)
end_defvr = end_deffn end_defvr = end_deffn
...@@ -1041,11 +1075,11 @@ class TexinfoParser: ...@@ -1041,11 +1075,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name) self.index('vr', name)
def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args)
...@@ -1060,7 +1094,7 @@ class TexinfoParser: ...@@ -1060,7 +1094,7 @@ class TexinfoParser:
def bgn_deftypefn(self, args): def bgn_deftypefn(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypefnx (args) self.do_deftypefnx(args)
end_deftypefn = end_deffn end_deftypefn = end_deffn
...@@ -1068,10 +1102,10 @@ class TexinfoParser: ...@@ -1068,10 +1102,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, name))
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
...@@ -1081,7 +1115,7 @@ class TexinfoParser: ...@@ -1081,7 +1115,7 @@ class TexinfoParser:
def bgn_deftypevr(self, args): def bgn_deftypevr(self, args):
self.write('<DL>') self.write('<DL>')
self.do_deftypevrx (args) self.do_deftypevrx(args)
end_deftypevr = end_deftypefn end_deftypevr = end_deftypefn
...@@ -1089,11 +1123,11 @@ class TexinfoParser: ...@@ -1089,11 +1123,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s} @b{%s}' % (datatype, 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)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name) self.index('fn', name)
def bgn_deftypevar(self, args): def bgn_deftypevar(self, args):
...@@ -1114,12 +1148,12 @@ class TexinfoParser: ...@@ -1114,12 +1148,12 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % 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)
self.expand(' -- ' + category + ' of ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('vr', name + ' @r{of ' + classname + '}') self.index('vr', '%s @r{on %s}' % (name, classname))
def bgn_defivar(self, args): def bgn_defivar(self, args):
self.bgn_defcv('{Instance Variable} ' + args) self.bgn_defcv('{Instance Variable} ' + args)
...@@ -1129,7 +1163,7 @@ class TexinfoParser: ...@@ -1129,7 +1163,7 @@ class TexinfoParser:
def bgn_defop(self, args): def bgn_defop(self, args):
self.write('<DL>') self.write('<DL>')
self.do_defopx (args) self.do_defopx(args)
end_defop = end_defcv end_defop = end_defcv
...@@ -1137,11 +1171,11 @@ class TexinfoParser: ...@@ -1137,11 +1171,11 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + makevar(word)) for word in rest: self.expand(' ' + makevar(word))
self.expand(' -- ' + category + ' on ' + classname) #self.expand(' -- %s of @code{%s}' % (category, classname))
self.write('<DD>\n') self.write('\n<DD>')
self.index('fn', name + ' @r{on ' + classname + '}') self.index('fn', '%s @r{on %s}' % (name, classname))
def bgn_defmethod(self, args): def bgn_defmethod(self, args):
self.bgn_defop('Method ' + args) self.bgn_defop('Method ' + args)
...@@ -1161,10 +1195,10 @@ class TexinfoParser: ...@@ -1161,10 +1195,10 @@ class TexinfoParser:
self.write('<DT>') 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{%s}' % name)
for word in rest: self.expand(' ' + word) for word in rest: self.expand(' ' + word)
self.expand(' -- ' + category) #self.expand(' -- ' + category)
self.write('<DD>\n') self.write('\n<DD>')
self.index('tp', name) self.index('tp', name)
# --- Making Lists and Tables # --- Making Lists and Tables
...@@ -1218,7 +1252,7 @@ class TexinfoParser: ...@@ -1218,7 +1252,7 @@ class TexinfoParser:
if self.stack and self.stack[-1] == 'table': if self.stack and self.stack[-1] == 'table':
self.write('<DT>') self.write('<DT>')
self.expand(args) self.expand(args)
self.write('<DD>') self.write('\n<DD>')
else: else:
self.write('<LI>') self.write('<LI>')
self.expand(args) self.expand(args)
...@@ -1273,7 +1307,8 @@ class TexinfoParser: ...@@ -1273,7 +1307,8 @@ class TexinfoParser:
def bgn_menu(self, args): def bgn_menu(self, args):
self.write('<DIR>\n') self.write('<DIR>\n')
self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n') self.write(' <STRONG><EM>Menu</EM></STRONG><P>\n')
def end_menu(self): self.write('</DIR>\n') def end_menu(self):
self.write('</DIR>\n')
def bgn_cartouche(self, args): pass def bgn_cartouche(self, args): pass
def end_cartouche(self): pass def end_cartouche(self): pass
...@@ -1366,8 +1401,7 @@ class TexinfoParser: ...@@ -1366,8 +1401,7 @@ class TexinfoParser:
if iscodeindex: key = '@code{' + key + '}' if iscodeindex: key = '@code{' + key + '}'
if key != prevkey: if key != prevkey:
self.expand(key) self.expand(key)
self.write('<DD><A HREF="', makefile(node), \ self.write('\n<DD><A HREF="%s">%s</A>\n' % (makefile(node), node))
'">', node, '</A>\n')
prevkey, prevnode = key, node prevkey, prevnode = key, node
self.write('</DL>\n') self.write('</DL>\n')
...@@ -1382,6 +1416,45 @@ class TexinfoParser: ...@@ -1382,6 +1416,45 @@ class TexinfoParser:
print string.ljust(cmd, 20), self.unknown[cmd] print string.ljust(cmd, 20), self.unknown[cmd]
class TexinfoParserHTML3(TexinfoParser):
COPYRIGHT_SYMBOL = "&copy;"
FN_ID_PATTERN = "[%(id)s]"
FN_SOURCE_PATTERN = '<A ID=footnoteref%(id)s ' \
'HREF="#footnotetext%(id)s">' + FN_ID_PATTERN + '</A>'
FN_TARGET_PATTERN = '<FN ID=footnotetext%(id)s>\n' \
'<P><A HREF="#footnoteref%(id)s">' + FN_ID_PATTERN \
+ '</A>\n%(text)s</P></FN>\n'
FN_HEADER = '<DIV CLASS=footnotes>\n <HR NOSHADE WIDTH=200>\n' \
' <STRONG><EM>Footnotes</EM></STRONG>\n <P>\n'
Node = HTML3Node
def bgn_quotation(self, args): self.write('<BQ>')
def end_quotation(self): self.write('</BQ>\n')
def bgn_example(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=example>')
def bgn_flushleft(self, args):
self.nofill = self.nofill + 1
self.write('<PRE CLASS=flushleft>\n')
def bgn_flushright(self, args):
self.nofill = self.nofill + 1
self.write('<DIV ALIGN=right CLASS=flushright><ADDRESS COMPACT>\n')
def end_flushright(self):
self.write('</ADDRESS></DIV>\n')
self.nofill = self.nofill - 1
def bgn_menu(self, args):
self.write('<UL PLAIN CLASS=menu>\n')
self.write(' <LH>Menu</LH>\n')
def end_menu(self):
self.write('</UL>\n')
# Put @var{} around alphabetic substrings # Put @var{} around alphabetic substrings
def makevar(str): def makevar(str):
return '@var{'+str+'}' return '@var{'+str+'}'
...@@ -1463,16 +1536,35 @@ def increment(s): ...@@ -1463,16 +1536,35 @@ def increment(s):
def test(): def test():
import sys import sys
parser = TexinfoParser() debugging = 0
print_headers = 0
cont = 0
html3 = 0
while sys.argv[1:2] == ['-d']: while sys.argv[1:2] == ['-d']:
parser.debugging = parser.debugging + 1 debugging = debugging + 1
del sys.argv[1:2] del sys.argv[1:2]
if sys.argv[1] == '-p':
print_headers = 1
del sys.argv[1]
if sys.argv[1] == '-c': if sys.argv[1] == '-c':
parser.cont = 1 cont = 1
del sys.argv[1]
if sys.argv[1] == '-3':
html3 = 1
del sys.argv[1] del sys.argv[1]
if len(sys.argv) <> 3: if len(sys.argv) <> 3:
print 'usage: texi2html [-d] [-d] [-c] inputfile outputdirectory' print 'usage: texi2html [-d [-d]] [-p] [-c] inputfile outputdirectory'
sys.exit(2) sys.exit(2)
if html3:
parser = TexinfoParserHTML3()
else:
parser = TexinfoParser()
parser.cont = cont
parser.debugging = debugging
parser.print_headers = print_headers
file = sys.argv[1] file = sys.argv[1]
parser.setdirname(sys.argv[2]) parser.setdirname(sys.argv[2])
if file == '-': if file == '-':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment