1- #! /usr/local/ bin/python
1+ #! /usr/bin/env python
22
33# Convert GNU texinfo files into HTML, one file per node.
44# Based on Texinfo 2.14.
3636# How about icons ?
3737
3838import os
39- import regex
40- import regsub
4139import string
40+ import re
4241
4342MAGIC = '\\ input texinfo'
4443
45- cmprog = regex .compile ('^@\([a-z]+\)\([ \t ]\|$\)' ) # Command (line-oriented)
46- blprog = regex .compile ('^[ \t ]*$' ) # Blank line
47- kwprog = regex .compile ('@[a-z]+' ) # Keyword (embedded, usually with {} args)
48- spprog = regex .compile ('[\n @{}&<>]' ) # Special characters in running text
49- miprog = regex .compile ( \
50- '^\* \([^:]*\):\(:\|[ \t ]*\([^\t ,\n .]+\)\([^ \t \n ]*\)\)[ \t \n ]*' )
51- # menu item (Yuck!)
44+ cmprog = re .compile ('^@([a-z]+)([ \t ]|$)' ) # Command (line-oriented)
45+ blprog = re .compile ('^[ \t ]*$' ) # Blank line
46+ kwprog = re .compile ('@[a-z]+' ) # Keyword (embedded, usually
47+ # with {} args)
48+ spprog = re .compile ('[\n @{}&<>]' ) # Special characters in
49+ # running text
50+ #
51+ # menu item (Yuck!)
52+ miprog = re .compile ('^\* ([^:]*):(:|[ \t ]*([^\t ,\n .]+)([^ \t \n ]*))[ \t \n ]*' )
5253
5354
55+
5456class HTMLNode :
5557 """Some of the parser's functionality is separated into this class.
5658
@@ -212,7 +214,7 @@ def setincludedir(self, includedir):
212214 def parse (self , fp ):
213215 line = fp .readline ()
214216 lineno = 1
215- while line and (line [0 ] == '%' or blprog .match (line ) >= 0 ):
217+ while line and (line [0 ] == '%' or blprog .match (line )):
216218 line = fp .readline ()
217219 lineno = lineno + 1
218220 if line [:len (MAGIC )] <> MAGIC :
@@ -237,8 +239,9 @@ def parserest(self, fp, initial_lineno):
237239 print '*** EOF before @bye'
238240 break
239241 lineno = lineno + 1
240- if cmprog .match (line ) >= 0 :
241- a , b = cmprog .regs [1 ]
242+ mo = cmprog .match (line )
243+ if mo :
244+ a , b = mo .span (1 )
242245 cmd = line [a :b ]
243246 if cmd in ('noindent' , 'refill' ):
244247 accu .append (line )
@@ -247,8 +250,8 @@ def parserest(self, fp, initial_lineno):
247250 if not self .skip :
248251 self .process (accu )
249252 accu = []
250- self .command (line )
251- elif blprog .match (line ) >= 0 and \
253+ self .command (line , mo )
254+ elif blprog .match (line ) and \
252255 'format' not in self .stack and \
253256 'example' not in self .stack :
254257 if accu :
@@ -346,12 +349,16 @@ def process(self, accu):
346349 if self .stack and self .stack [- 1 ] == 'menu' :
347350 # XXX should be done differently
348351 for line in accu :
349- if miprog .match (line ) < 0 :
352+ mo = miprog .match (line )
353+ if not mo :
350354 line = string .strip (line ) + '\n '
351355 self .expand (line )
352356 continue
353- (bgn , end ), (a , b ), (c , d ), (e , f ), (g , h ) = \
354- miprog .regs [:5 ]
357+ bgn , end = mo .span (0 )
358+ a , b = mo .span (1 )
359+ c , d = mo .span (2 )
360+ e , f = mo .span (3 )
361+ g , h = mo .span (4 )
355362 label = line [a :b ]
356363 nodename = line [c :d ]
357364 if nodename [0 ] == ':' : nodename = label
@@ -373,8 +380,10 @@ def expand(self, text):
373380 n = len (text )
374381 while i < n :
375382 start = i
376- i = spprog .search (text , i )
377- if i < 0 :
383+ mo = spprog .search (text , i )
384+ if mo :
385+ i = mo .start ()
386+ else :
378387 self .write (text [start :])
379388 break
380389 self .write (text [start :i ])
@@ -674,14 +683,24 @@ def close_var(self): self.write('</VAR>')
674683 def open_w (self ): self .write ('<NOBREAK>' )
675684 def close_w (self ): self .write ('</NOBREAK>' )
676685
686+ def open_url (self ): self .startsaving ()
687+ def close_url (self ):
688+ text = self .collectsavings ()
689+ self .write ('<A HREF="' , text , '">' , text , '</A>' )
690+
691+ def open_email (self ): self .startsaving ()
692+ def close_email (self ):
693+ text = self .collectsavings ()
694+ self .write ('<A HREF="mailto:' , text , '">' , text , '</A>' )
695+
677696 open_titlefont = open_
678697 close_titlefont = close_
679698
680699 def open_small (self ): pass
681700 def close_small (self ): pass
682701
683- def command (self , line ):
684- a , b = cmprog . regs [ 1 ]
702+ def command (self , line , mo ):
703+ a , b = mo . span ( 1 )
685704 cmd = line [a :b ]
686705 args = string .strip (line [b :])
687706 if self .debugging > 1 :
@@ -1378,15 +1397,17 @@ def prindex(self, name):
13781397 print '--- Generating' , self .indextitle [name ], 'index'
13791398 # The node already provides a title
13801399 index1 = []
1381- junkprog = regex .compile ('^\ (@[a-z]+\ )?{' )
1400+ junkprog = re .compile ('^(@[a-z]+)?{' )
13821401 for key , node in index :
13831402 sortkey = string .lower (key )
13841403 # Remove leading `@cmd{' from sort key
13851404 # -- don't bother about the matching `}'
13861405 oldsortkey = sortkey
13871406 while 1 :
1388- i = junkprog .match (sortkey )
1389- if i < 0 : break
1407+ mo = junkprog .match (sortkey )
1408+ if not mo :
1409+ break
1410+ i = mo .end ()
13901411 sortkey = sortkey [i :]
13911412 index1 .append (sortkey , key , node )
13921413 del index [:]
@@ -1481,12 +1502,14 @@ def splitwords(str, minlength):
14811502
14821503
14831504# Find the end of a "word", matching braces and interpreting @@ @{ @}
1484- fwprog = regex .compile ('[@{} ]' )
1505+ fwprog = re .compile ('[@{} ]' )
14851506def findwordend (str , i , n ):
14861507 level = 0
14871508 while i < n :
1488- i = fwprog .search (str , i )
1489- if i < 0 : break
1509+ mo = fwprog .search (str , i )
1510+ if not mo :
1511+ break
1512+ i = mo .start ()
14901513 c = str [i ]; i = i + 1
14911514 if c == '@' : i = i + 1 # Next character is not special
14921515 elif c == '{' : level = level + 1
0 commit comments