blob: fd71ff6414664f302f2b55019c20efbfbc6cef51 [file] [log] [blame]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001#
2# partparse.py: parse a by-Guido-written-and-by-Jan-Hein-edited LaTeX file,
3# and generate texinfo source.
4#
5# This is *not* a good example of good programming practices. In fact, this
6# file could use a complete rewrite, in order to become faster, more
Guido van Rossum36f219d1996-09-11 21:30:40 +00007# easily extensible and maintainable.
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00008#
9# However, I added some comments on a few places for the pityful person who
10# would ever need to take a look into this file.
11#
12# Have I been clear enough??
13#
14# -jh
Guido van Rossum36f219d1996-09-11 21:30:40 +000015#
16# Yup. I made some performance improvements and hope this lasts a while;
17# I don't want to be the schmuck who ends up re-writting it!
18#
19# -fld
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000020
Guido van Rossum7a2dba21993-11-05 14:45:11 +000021import sys, string, regex, getopt, os
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000022
Guido van Rossum49604d31996-09-10 22:19:51 +000023from types import IntType, ListType, StringType, TupleType
24
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000025# Different parse modes for phase 1
26MODE_REGULAR = 0
27MODE_VERBATIM = 1
28MODE_CS_SCAN = 2
29MODE_COMMENT = 3
30MODE_MATH = 4
31MODE_DMATH = 5
32MODE_GOBBLEWHITE = 6
33
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000034the_modes = (MODE_REGULAR, MODE_VERBATIM, MODE_CS_SCAN, MODE_COMMENT,
Guido van Rossum36f219d1996-09-11 21:30:40 +000035 MODE_MATH, MODE_DMATH, MODE_GOBBLEWHITE)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000036
37# Show the neighbourhood of the scanned buffer
38def epsilon(buf, where):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000039 wmt, wpt = where - 10, where + 10
40 if wmt < 0:
41 wmt = 0
42 if wpt > len(buf):
43 wpt = len(buf)
44 return ' Context ' + `buf[wmt:where]` + '.' + `buf[where:wpt]` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000045
46# Should return the line number. never worked
47def lin():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000048 global lineno
49 return ' Line ' + `lineno` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000050
51# Displays the recursion level.
52def lv(lvl):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000053 return ' Level ' + `lvl` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000054
55# Combine the three previous functions. Used often.
56def lle(lvl, buf, where):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000057 return lv(lvl) + lin() + epsilon(buf, where)
58
59
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000060# This class is only needed for _symbolic_ representation of the parse mode.
61class Mode:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000062 def __init__(self, arg):
63 if arg not in the_modes:
64 raise ValueError, 'mode not in the_modes'
65 self.mode = arg
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000066
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000067 def __cmp__(self, other):
68 if type(self) != type(other):
Guido van Rossum36f219d1996-09-11 21:30:40 +000069 other = mode[other]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000070 return cmp(self.mode, other.mode)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000071
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000072 def __repr__(self):
73 if self.mode == MODE_REGULAR:
74 return 'MODE_REGULAR'
75 elif self.mode == MODE_VERBATIM:
76 return 'MODE_VERBATIM'
77 elif self.mode == MODE_CS_SCAN:
78 return 'MODE_CS_SCAN'
79 elif self.mode == MODE_COMMENT:
80 return 'MODE_COMMENT'
81 elif self.mode == MODE_MATH:
82 return 'MODE_MATH'
83 elif self.mode == MODE_DMATH:
84 return 'MODE_DMATH'
85 elif self.mode == MODE_GOBBLEWHITE:
86 return 'MODE_GOBBLEWHITE'
87 else:
88 raise ValueError, 'mode not in the_modes'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000089
90# just a wrapper around a class initialisation
Guido van Rossum36f219d1996-09-11 21:30:40 +000091mode = {}
92for t in the_modes:
93 mode[t] = Mode(t)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000094
95
96# After phase 1, the text consists of chunks, with a certain type
97# this type will be assigned to the chtype member of the chunk
98# the where-field contains the file position where this is found
99# and the data field contains (1): a tuple describing start- end end
100# positions of the substring (can be used as slice for the buf-variable),
101# (2) just a string, mostly generated by the changeit routine,
102# or (3) a list, describing a (recursive) subgroup of chunks
103PLAIN = 0 # ASSUME PLAINTEXT, data = the text
104GROUP = 1 # GROUP ({}), data = [chunk, chunk,..]
105CSNAME = 2 # CONTROL SEQ TOKEN, data = the command
106COMMENT = 3 # data is the actual comment
107DMATH = 4 # DISPLAYMATH, data = [chunk, chunk,..]
108MATH = 5 # MATH, see DISPLAYMATH
109OTHER = 6 # CHAR WITH CATCODE OTHER, data = char
110ACTIVE = 7 # ACTIVE CHAR
111GOBBLEDWHITE = 8 # Gobbled LWSP, after CSNAME
112ENDLINE = 9 # END-OF-LINE, data = '\n'
113DENDLINE = 10 # DOUBLE EOL, data='\n', indicates \par
114ENV = 11 # LaTeX-environment
Guido van Rossum36f219d1996-09-11 21:30:40 +0000115 # data =(envname,[ch,ch,ch,.])
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000116CSLINE = 12 # for texi: next chunk will be one group
Guido van Rossum36f219d1996-09-11 21:30:40 +0000117 # of args. Will be set all on 1 line
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000118IGNORE = 13 # IGNORE this data
119ENDENV = 14 # TEMP END OF GROUP INDICATOR
120IF = 15 # IF-directive
Guido van Rossum36f219d1996-09-11 21:30:40 +0000121 # data = (flag,negate,[ch, ch, ch,...])
122
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000123the_types = (PLAIN, GROUP, CSNAME, COMMENT, DMATH, MATH, OTHER, ACTIVE,
Guido van Rossum36f219d1996-09-11 21:30:40 +0000124 GOBBLEDWHITE, ENDLINE, DENDLINE, ENV, CSLINE, IGNORE, ENDENV, IF)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000125
126# class, just to display symbolic name
127class ChunkType:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000128 def __init__(self, chunk_type):
129 if chunk_type not in the_types:
130 raise ValueError, 'chunk_type not in the_types'
131 self.chunk_type = chunk_type
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000132
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000133 def __cmp__(self, other):
134 if type(self) != type(other):
Guido van Rossum36f219d1996-09-11 21:30:40 +0000135 other = chunk_type[other]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000136 return cmp(self.chunk_type, other.chunk_type)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000137
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000138 def __repr__(self):
139 if self.chunk_type == PLAIN:
140 return 'PLAIN'
141 elif self.chunk_type == GROUP:
142 return 'GROUP'
143 elif self.chunk_type == CSNAME:
144 return 'CSNAME'
145 elif self.chunk_type == COMMENT:
146 return 'COMMENT'
147 elif self.chunk_type == DMATH:
148 return 'DMATH'
149 elif self.chunk_type == MATH:
150 return 'MATH'
151 elif self.chunk_type == OTHER:
152 return 'OTHER'
153 elif self.chunk_type == ACTIVE:
154 return 'ACTIVE'
155 elif self.chunk_type == GOBBLEDWHITE:
156 return 'GOBBLEDWHITE'
157 elif self.chunk_type == DENDLINE:
158 return 'DENDLINE'
159 elif self.chunk_type == ENDLINE:
160 return 'ENDLINE'
161 elif self.chunk_type == ENV:
162 return 'ENV'
163 elif self.chunk_type == CSLINE:
164 return 'CSLINE'
165 elif self.chunk_type == IGNORE:
166 return 'IGNORE'
167 elif self.chunk_type == ENDENV:
168 return 'ENDENV'
169 elif self.chunk_type == IF:
170 return 'IF'
171 else:
172 raise ValueError, 'chunk_type not in the_types'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000173
174# ...and the wrapper
Guido van Rossum36f219d1996-09-11 21:30:40 +0000175chunk_type = {}
Guido van Rossum49604d31996-09-10 22:19:51 +0000176for t in the_types:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000177 chunk_type[t] = ChunkType(t)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000178
179# store a type object of the ChunkType-class-instance...
Guido van Rossum36f219d1996-09-11 21:30:40 +0000180chunk_type_type = type(chunk_type[PLAIN])
Guido van Rossum49604d31996-09-10 22:19:51 +0000181
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000182# this class contains a part of the parsed buffer
183class Chunk:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000184 def __init__(self, chtype, where, data):
185 if type(chtype) != chunk_type_type:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000186 chtype = chunk_type[chtype]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000187 self.chtype = chtype
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000188 self.where = where
189 self.data = data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000190
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000191 def __repr__(self):
192 return 'chunk' + `self.chtype, self.where, self.data`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000193
194# and the wrapper
Guido van Rossum49604d31996-09-10 22:19:51 +0000195chunk = Chunk
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000196
197
198error = 'partparse.error'
199
200#
201# TeX's catcodes...
202#
203CC_ESCAPE = 0
204CC_LBRACE = 1
205CC_RBRACE = 2
206CC_MATHSHIFT = 3
207CC_ALIGNMENT = 4
208CC_ENDLINE = 5
209CC_PARAMETER = 6
210CC_SUPERSCRIPT = 7
211CC_SUBSCRIPT = 8
212CC_IGNORE = 9
213CC_WHITE = 10
214CC_LETTER = 11
215CC_OTHER = 12
216CC_ACTIVE = 13
217CC_COMMENT = 14
218CC_INVALID = 15
219
220# and the names
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000221cc_names = [
222 'CC_ESCAPE',
223 'CC_LBRACE',
224 'CC_RBRACE',
225 'CC_MATHSHIFT',
226 'CC_ALIGNMENT',
227 'CC_ENDLINE',
228 'CC_PARAMETER',
229 'CC_SUPERSCRIPT',
230 'CC_SUBSCRIPT',
231 'CC_IGNORE',
232 'CC_WHITE',
233 'CC_LETTER',
234 'CC_OTHER',
235 'CC_ACTIVE',
236 'CC_COMMENT',
237 'CC_INVALID',
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000238 ]
239
240# Show a list of catcode-name-symbols
241def pcl(codelist):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000242 result = ''
243 for i in codelist:
244 result = result + cc_names[i] + ', '
245 return '[' + result[:-2] + ']'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000246
247# the name of the catcode (ACTIVE, OTHER, etc.)
248def pc(code):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000249 return cc_names[code]
250
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000251
252# Which catcodes make the parser stop parsing regular plaintext
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000253regular_stopcodes = [CC_ESCAPE, CC_LBRACE, CC_RBRACE, CC_MATHSHIFT,
254 CC_ALIGNMENT, CC_PARAMETER, CC_SUPERSCRIPT, CC_SUBSCRIPT,
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000255 CC_IGNORE, CC_ACTIVE, CC_COMMENT, CC_INVALID, CC_ENDLINE]
256
257# same for scanning a control sequence name
258csname_scancodes = [CC_LETTER]
259
260# same for gobbling LWSP
261white_scancodes = [CC_WHITE]
262##white_scancodes = [CC_WHITE, CC_ENDLINE]
263
264# make a list of all catcode id's, except for catcode ``other''
265all_but_other_codes = range(16)
266del all_but_other_codes[CC_OTHER]
267##print all_but_other_codes
268
269# when does a comment end
270comment_stopcodes = [CC_ENDLINE]
271
272# gather all characters together, specified by a list of catcodes
273def code2string(cc, codelist):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000274 ##print 'code2string: codelist = ' + pcl(codelist),
275 result = ''
276 for category in codelist:
277 if cc[category]:
278 result = result + cc[category]
279 ##print 'result = ' + `result`
280 return result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000281
282# automatically generate all characters of catcode other, being the
283# complement set in the ASCII range (128 characters)
284def make_other_codes(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000285 otherchars = range(256) # could be made 256, no problem
286 for category in all_but_other_codes:
287 if cc[category]:
288 for c in cc[category]:
289 otherchars[ord(c)] = None
290 result = ''
291 for i in otherchars:
292 if i != None:
293 result = result + chr(i)
294 return result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000295
296# catcode dump (which characters have which catcodes).
297def dump_cc(name, cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000298 ##print '\t' + name
299 ##print '=' * (8+len(name))
300 if len(cc) != 16:
301 raise TypeError, 'cc not good cat class'
Guido van Rossum7a2dba21993-11-05 14:45:11 +0000302## for i in range(16):
303## print pc(i) + '\t' + `cc[i]`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000304
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000305
306# In the beginning,....
307epoch_cc = [None] * 16
308##dump_cc('epoch_cc', epoch_cc)
309
310
311# INITEX
312initex_cc = epoch_cc[:]
313initex_cc[CC_ESCAPE] = '\\'
314initex_cc[CC_ENDLINE], initex_cc[CC_IGNORE], initex_cc[CC_WHITE] = \
315 '\n', '\0', ' '
316initex_cc[CC_LETTER] = string.uppercase + string.lowercase
317initex_cc[CC_COMMENT], initex_cc[CC_INVALID] = '%', '\x7F'
318#initex_cc[CC_OTHER] = make_other_codes(initex_cc) I don't need them, anyway
319##dump_cc('initex_cc', initex_cc)
320
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000321
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000322# LPLAIN: LaTeX catcode setting (see lplain.tex)
323lplain_cc = initex_cc[:]
324lplain_cc[CC_LBRACE], lplain_cc[CC_RBRACE] = '{', '}'
325lplain_cc[CC_MATHSHIFT] = '$'
326lplain_cc[CC_ALIGNMENT] = '&'
327lplain_cc[CC_PARAMETER] = '#'
328lplain_cc[CC_SUPERSCRIPT] = '^\x0B' # '^' and C-k
329lplain_cc[CC_SUBSCRIPT] = '_\x01' # '_' and C-a
330lplain_cc[CC_WHITE] = lplain_cc[CC_WHITE] + '\t'
331lplain_cc[CC_ACTIVE] = '~\x0C' # '~' and C-l
332lplain_cc[CC_OTHER] = make_other_codes(lplain_cc)
333##dump_cc('lplain_cc', lplain_cc)
334
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000335
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000336# Guido's LaTeX environment catcoded '_' as ``other''
337# my own purpose catlist
338my_cc = lplain_cc[:]
339my_cc[CC_SUBSCRIPT] = my_cc[CC_SUBSCRIPT][1:] # remove '_' here
340my_cc[CC_OTHER] = my_cc[CC_OTHER] + '_' # add it to OTHER list
341dump_cc('my_cc', my_cc)
342
343
344
345# needed for un_re, my equivalent for regexp-quote in Emacs
346re_meaning = '\\[]^$'
347
348def un_re(str):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000349 result = ''
350 for i in str:
351 if i in re_meaning:
352 result = result + '\\'
353 result = result + i
354 return result
355
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000356# NOTE the negate ('^') operator in *some* of the regexps below
357def make_rc_regular(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000358 # problems here if '[]' are included!!
359 return regex.compile('[' + code2string(cc, regular_stopcodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000360
361def make_rc_cs_scan(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000362 return regex.compile('[^' + code2string(cc, csname_scancodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000363
364def make_rc_comment(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000365 return regex.compile('[' + code2string(cc, comment_stopcodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000366
367def make_rc_endwhite(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000368 return regex.compile('[^' + code2string(cc, white_scancodes) + ']')
369
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000370
371
372# regular: normal mode:
373rc_regular = make_rc_regular(my_cc)
374
375# scan: scan a command sequence e.g. `newlength' or `mbox' or `;', `,' or `$'
376rc_cs_scan = make_rc_cs_scan(my_cc)
377rc_comment = make_rc_comment(my_cc)
378rc_endwhite = make_rc_endwhite(my_cc)
379
380
Guido van Rossum36f219d1996-09-11 21:30:40 +0000381# parseit (BUF, PARSEMODE=mode[MODE_REGULAR], START=0, RECURSION-LEVEL=0)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000382# RECURSION-LEVEL will is incremented on entry.
383# result contains the list of chunks returned
384# together with this list, the buffer position is returned
385
386# RECURSION-LEVEL will be set to zero *again*, when recursively a
387# {,D}MATH-mode scan has been enetered.
388# This has been done in order to better check for environment-mismatches
389
Guido van Rossum36f219d1996-09-11 21:30:40 +0000390def parseit(buf, parsemode=mode[MODE_REGULAR], start=0, lvl=0):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000391 global lineno
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000392
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000393 result = []
394 end = len(buf)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000395 if lvl == 0 and parsemode == mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000396 lineno = 1
397 lvl = lvl + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000398
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000399 ##print 'parseit(' + epsilon(buf, start) + ', ' + `parsemode` + ', ' + `start` + ', ' + `lvl` + ')'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000400
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000401 #
402 # some of the more regular modes...
403 #
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000404
Guido van Rossum36f219d1996-09-11 21:30:40 +0000405 if parsemode in (mode[MODE_REGULAR], mode[MODE_DMATH], mode[MODE_MATH]):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000406 cstate = []
407 newpos = start
408 curpmode = parsemode
409 while 1:
410 where = newpos
411 #print '\tnew round: ' + epsilon(buf, where)
412 if where == end:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000413 if lvl > 1 or curpmode != mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000414 # not the way we started...
415 raise EOFError, 'premature end of file.' + lle(lvl, buf, where)
416 # the real ending of lvl-1 parse
417 return end, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000418
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000419 pos = rc_regular.search(buf, where)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000420
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000421 if pos < 0:
422 pos = end
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000423
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000424 if pos != where:
425 newpos, c = pos, chunk(PLAIN, where, (where, pos))
426 result.append(c)
427 continue
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000428
429
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000430 #
431 # ok, pos == where and pos != end
432 #
433 foundchar = buf[where]
434 if foundchar in my_cc[CC_LBRACE]:
435 # recursive subgroup parse...
436 newpos, data = parseit(buf, curpmode, where+1, lvl)
437 result.append(chunk(GROUP, where, data))
438
439 elif foundchar in my_cc[CC_RBRACE]:
440 if lvl <= 1:
441 raise error, 'ENDGROUP while in base level.' + lle(lvl, buf, where)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000442 if lvl == 1 and mode != mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000443 raise error, 'endgroup while in math mode. +lin() + epsilon(buf, where)'
444 return where + 1, result
445
446 elif foundchar in my_cc[CC_ESCAPE]:
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000447 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000448 # call the routine that actually deals with
449 # this problem. If do_ret is None, than
450 # return the value of do_ret
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000451 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000452 # Note that handle_cs might call this routine
453 # recursively again...
454 #
455 do_ret, newpos = handlecs(buf, where,
456 curpmode, lvl, result, end)
457 if do_ret != None:
458 return do_ret
459
460 elif foundchar in my_cc[CC_COMMENT]:
461 newpos, data = parseit(buf,
Guido van Rossum36f219d1996-09-11 21:30:40 +0000462 mode[MODE_COMMENT], where+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000463 result.append(chunk(COMMENT, where, data))
464
465 elif foundchar in my_cc[CC_MATHSHIFT]:
466 # note that recursive calls to math-mode
467 # scanning are called with recursion-level 0
468 # again, in order to check for bad mathend
469 #
470 if where + 1 != end and buf[where + 1] in my_cc[CC_MATHSHIFT]:
471 #
472 # double mathshift, e.g. '$$'
473 #
Guido van Rossum36f219d1996-09-11 21:30:40 +0000474 if curpmode == mode[MODE_REGULAR]:
475 newpos, data = parseit(buf, mode[MODE_DMATH],
476 where + 2, 0)
477 result.append(chunk(DMATH, where, data))
478 elif curpmode == mode[MODE_MATH]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000479 raise error, 'wrong math delimiiter' + lin() + epsilon(buf, where)
480 elif lvl != 1:
481 raise error, 'bad mathend.' + lle(lvl, buf, where)
482 else:
483 return where + 2, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000484 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000485 #
486 # single math shift, e.g. '$'
487 #
Guido van Rossum36f219d1996-09-11 21:30:40 +0000488 if curpmode == mode[MODE_REGULAR]:
489 newpos, data = parseit(buf, mode[MODE_MATH],
490 where + 1, 0)
491 result.append(chunk(MATH, where, data))
492 elif curpmode == mode[MODE_DMATH]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000493 raise error, 'wrong math delimiiter' + lin() + epsilon(buf, where)
494 elif lvl != 1:
495 raise error, 'bad mathend.' + lv(lvl, buf, where)
496 else:
497 return where + 1, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000498
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000499 elif foundchar in my_cc[CC_IGNORE]:
500 print 'warning: ignored char', `foundchar`
501 newpos = where + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000502
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000503 elif foundchar in my_cc[CC_ACTIVE]:
504 result.append(chunk(ACTIVE, where, foundchar))
505 newpos = where + 1
506
507 elif foundchar in my_cc[CC_INVALID]:
508 raise error, 'invalid char ' + `foundchar`
509 newpos = where + 1
510
511 elif foundchar in my_cc[CC_ENDLINE]:
512 #
513 # after an end of line, eat the rest of
514 # whitespace on the beginning of the next line
515 # this is what LaTeX more or less does
516 #
517 # also, try to indicate double newlines (\par)
518 #
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000519 lineno = lineno + 1
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000520 savedwhere = where
Guido van Rossum36f219d1996-09-11 21:30:40 +0000521 newpos, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], where + 1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000522 if newpos != end and buf[newpos] in my_cc[CC_ENDLINE]:
523 result.append(chunk(DENDLINE, savedwhere, foundchar))
524 else:
525 result.append(chunk(ENDLINE, savedwhere, foundchar))
526 else:
527 result.append(chunk(OTHER, where, foundchar))
528 newpos = where + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000529
Guido van Rossum36f219d1996-09-11 21:30:40 +0000530 elif parsemode == mode[MODE_CS_SCAN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000531 #
532 # scan for a control sequence token. `\ape', `\nut' or `\%'
533 #
534 if start == end:
535 raise EOFError, 'can\'t find end of csname'
536 pos = rc_cs_scan.search(buf, start)
537 if pos < 0:
538 pos = end
539 if pos == start:
540 # first non-letter right where we started the search
541 # ---> the control sequence name consists of one single
542 # character. Also: don't eat white space...
543 if buf[pos] in my_cc[CC_ENDLINE]:
544 lineno = lineno + 1
545 pos = pos + 1
546 return pos, (start, pos)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000547 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000548 spos = pos
549 if buf[pos] == '\n':
550 lineno = lineno + 1
551 spos = pos + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000552 pos2, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], spos, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000553 return pos2, (start, pos)
554
Guido van Rossum36f219d1996-09-11 21:30:40 +0000555 elif parsemode == mode[MODE_GOBBLEWHITE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000556 if start == end:
557 return start, ''
558 pos = rc_endwhite.search(buf, start)
559 if pos < 0:
560 pos = start
561 return pos, (start, pos)
562
Guido van Rossum36f219d1996-09-11 21:30:40 +0000563 elif parsemode == mode[MODE_COMMENT]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000564 pos = rc_comment.search(buf, start)
565 lineno = lineno + 1
566 if pos < 0:
567 print 'no newline perhaps?'
568 raise EOFError, 'can\'t find end of comment'
569 pos = pos + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000570 pos2, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], pos, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000571 return pos2, (start, pos)
572
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000573 else:
574 raise error, 'Unknown mode (' + `parsemode` + ')'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000575
576
577#moreresult = cswitch(buf[x1:x2], buf, newpos, parsemode, lvl)
578
579#boxcommands = 'mbox', 'fbox'
580#defcommands = 'def', 'newcommand'
581
582endverbstr = '\\end{verbatim}'
583
584re_endverb = regex.compile(un_re(endverbstr))
585
586#
587# handlecs: helper function for parseit, for the special thing we might
588# wanna do after certain command control sequences
589# returns: None or return_data, newpos
590#
591# in the latter case, the calling function is instructed to immediately
592# return with the data in return_data
593#
594def handlecs(buf, where, curpmode, lvl, result, end):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000595 global lineno
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000596
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000597 # get the control sequence name...
Guido van Rossum36f219d1996-09-11 21:30:40 +0000598 newpos, data = parseit(buf, mode[MODE_CS_SCAN], where+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000599 saveddata = data
Guido van Rossum36f219d1996-09-11 21:30:40 +0000600 s_buf_data = s(buf, data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000601
Guido van Rossum36f219d1996-09-11 21:30:40 +0000602 if s_buf_data in ('begin', 'end'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000603 # skip the expected '{' and get the LaTeX-envname '}'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000604 newpos, data = parseit(buf, mode[MODE_REGULAR], newpos+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000605 if len(data) != 1:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000606 raise error, 'expected 1 chunk of data.' + lle(lvl, buf, where)
Guido van Rossum49604d31996-09-10 22:19:51 +0000607
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000608 # yucky, we've got an environment
609 envname = s(buf, data[0].data)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000610 s_buf_saveddata = s(buf, saveddata)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000611 ##print 'FOUND ' + s(buf, saveddata) + '. Name ' + `envname` + '.' + lv(lvl)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000612 if s_buf_saveddata == 'begin' and envname == 'verbatim':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000613 # verbatim deserves special treatment
614 pos = re_endverb.search(buf, newpos)
615 if pos < 0:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000616 raise error, "%s not found.%s" \
617 % (`endverbstr`, lle(lvl, buf, where))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000618 result.append(chunk(ENV, where, (envname, [chunk(PLAIN, newpos, (newpos, pos))])))
619 newpos = pos + len(endverbstr)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000620
Guido van Rossum36f219d1996-09-11 21:30:40 +0000621 elif s_buf_saveddata == 'begin':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000622 # start parsing recursively... If that parse returns
623 # from an '\end{...}', then should the last item of
624 # the returned data be a string containing the ended
625 # environment
626 newpos, data = parseit(buf, curpmode, newpos, lvl)
627 if not data or type(data[-1]) is not StringType:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000628 raise error, "missing 'end'" + lle(lvl, buf, where) \
629 + epsilon(buf, newpos)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000630 retenv = data[-1]
631 del data[-1]
632 if retenv != envname:
633 #[`retenv`, `envname`]
Guido van Rossum36f219d1996-09-11 21:30:40 +0000634 raise error, 'environments do not match.%s%s' \
635 % (lle(lvl, buf, where), epsilon(buf, newpos))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000636 result.append(chunk(ENV, where, (retenv, data)))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000637 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000638 # 'end'... append the environment name, as just
639 # pointed out, and order parsit to return...
640 result.append(envname)
641 ##print 'POINT of return: ' + epsilon(buf, newpos)
642 # the tuple will be returned by parseit
643 return (newpos, result), newpos
644
645 # end of \begin ... \end handling
646
Guido van Rossum36f219d1996-09-11 21:30:40 +0000647 elif s_buf_data[0:2] == 'if':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000648 # another scary monster: the 'if' directive
Guido van Rossum36f219d1996-09-11 21:30:40 +0000649 flag = s_buf_data[2:]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000650
651 # recursively call parseit, just like environment above..
652 # the last item of data should contain the if-termination
653 # e.g., 'else' of 'fi'
654 newpos, data = parseit(buf, curpmode, newpos, lvl)
655 if not data or data[-1] not in ('else', 'fi'):
656 raise error, 'wrong if... termination' + \
657 lle(lvl, buf, where) + epsilon(buf, newpos)
658
659 ifterm = data[-1]
660 del data[-1]
661 # 0 means dont_negate flag
662 result.append(chunk(IF, where, (flag, 0, data)))
663 if ifterm == 'else':
664 # do the whole thing again, there is only one way
665 # to end this one, by 'fi'
666 newpos, data = parseit(buf, curpmode, newpos, lvl)
667 if not data or data[-1] not in ('fi', ):
668 raise error, 'wrong if...else... termination' \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000669 + lle(lvl, buf, where) \
670 + epsilon(buf, newpos)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000671
672 ifterm = data[-1]
673 del data[-1]
674 result.append(chunk(IF, where, (flag, 1, data)))
675 #done implicitely: return None, newpos
676
Guido van Rossum36f219d1996-09-11 21:30:40 +0000677 elif s_buf_data in ('else', 'fi'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000678 result.append(s(buf, data))
679 # order calling party to return tuple
680 return (newpos, result), newpos
681
682 # end of \if, \else, ... \fi handling
683
684 elif s(buf, saveddata) == 'verb':
685 x2 = saveddata[1]
686 result.append(chunk(CSNAME, where, data))
687 if x2 == end:
688 raise error, 'premature end of command.' + lle(lvl, buf, where)
689 delimchar = buf[x2]
690 ##print 'VERB: delimchar ' + `delimchar`
691 pos = regex.compile(un_re(delimchar)).search(buf, x2 + 1)
692 if pos < 0:
693 raise error, 'end of \'verb\' argument (' + \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000694 `delimchar` + ') not found.' + \
695 lle(lvl, buf, where)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000696 result.append(chunk(GROUP, x2, [chunk(PLAIN, x2+1, (x2+1, pos))]))
697 newpos = pos + 1
698 else:
699 result.append(chunk(CSNAME, where, data))
700 return None, newpos
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000701
702# this is just a function to get the string value if the possible data-tuple
703def s(buf, data):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000704 if type(data) is StringType:
705 return data
706 if len(data) != 2 or not (type(data[0]) is type(data[1]) is IntType):
707 raise TypeError, 'expected tuple of 2 integers'
708 x1, x2 = data
709 return buf[x1:x2]
Guido van Rossum49604d31996-09-10 22:19:51 +0000710
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000711
712##length, data1, i = getnextarg(length, buf, pp, i + 1)
713
714# make a deep-copy of some chunks
715def crcopy(r):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000716 return map(chunkcopy, r)
Guido van Rossum49604d31996-09-10 22:19:51 +0000717
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000718
719# copy a chunk, would better be a method of class Chunk...
720def chunkcopy(ch):
Guido van Rossum36f219d1996-09-11 21:30:40 +0000721 if ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000722 return chunk(GROUP, ch.where, map(chunkcopy, ch.data))
723 else:
724 return chunk(ch.chtype, ch.where, ch.data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000725
726
727# get next argument for TeX-macro, flatten a group (insert between)
728# or return Command Sequence token, or give back one character
729def getnextarg(length, buf, pp, item):
730
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000731 ##wobj = Wobj()
732 ##dumpit(buf, wobj.write, pp[item:min(length, item + 5)])
733 ##print 'GETNEXTARG, (len, item) =', `length, item` + ' ---> ' + wobj.data + ' <---'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000734
Guido van Rossum36f219d1996-09-11 21:30:40 +0000735 while item < length and pp[item].chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000736 del pp[item]
737 length = length - 1
738 if item >= length:
739 raise error, 'no next arg.' + epsilon(buf, pp[-1].where)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000740 if pp[item].chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000741 newpp = pp[item].data
742 del pp[item]
743 length = length - 1
744 changeit(buf, newpp)
745 length = length + len(newpp)
746 pp[item:item] = newpp
747 item = item + len(newpp)
748 if len(newpp) < 10:
749 wobj = Wobj()
750 dumpit(buf, wobj.write, newpp)
751 ##print 'GETNEXTARG: inserted ' + `wobj.data`
752 return length, item
Guido van Rossum36f219d1996-09-11 21:30:40 +0000753 elif pp[item].chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000754 #grab one char
755 print 'WARNING: grabbing one char'
756 if len(s(buf, pp[item].data)) > 1:
757 pp.insert(item, chunk(PLAIN, pp[item].where, s(buf, pp[item].data)[:1]))
758 item, length = item+1, length+1
759 pp[item].data = s(buf, pp[item].data)[1:]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000760 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000761 item = item+1
762 return length, item
763 else:
764 ch = pp[item]
765 try:
766 str = `s(buf, ch.data)`
767 except TypeError:
768 str = `ch.data`
769 if len(str) > 400:
770 str = str[:400] + '...'
771 print 'GETNEXTARG:', ch.chtype, 'not handled, data ' + str
772 return length, item
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000773
774
775# this one is needed to find the end of LaTeX's optional argument, like
776# item[...]
777re_endopt = regex.compile(']')
778
779# get a LaTeX-optional argument, you know, the square braces '[' and ']'
780def getoptarg(length, buf, pp, item):
781
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000782 wobj = Wobj()
783 dumpit(buf, wobj.write, pp[item:min(length, item + 5)])
784 ##print 'GETOPTARG, (len, item) =', `length, item` + ' ---> ' + wobj.data + ' <---'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000785
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000786 if item >= length or \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000787 pp[item].chtype != chunk_type[PLAIN] or \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000788 s(buf, pp[item].data)[0] != '[':
789 return length, item
790
791 pp[item].data = s(buf, pp[item].data)[1:]
792 if len(pp[item].data) == 0:
793 del pp[item]
794 length = length-1
795
796 while 1:
797 if item == length:
798 raise error, 'No end of optional arg found'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000799 if pp[item].chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000800 text = s(buf, pp[item].data)
801 pos = re_endopt.search(text)
802 if pos >= 0:
803 pp[item].data = text[:pos]
804 if pos == 0:
805 del pp[item]
806 length = length-1
807 else:
808 item=item+1
809 text = text[pos+1:]
810
811 while text and text[0] in ' \t':
812 text = text[1:]
813
814 if text:
815 pp.insert(item, chunk(PLAIN, 0, text))
816 length = length + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000817 return length, item
818
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000819 item = item+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000820
821
822# Wobj just add write-requests to the ``data'' attribute
823class Wobj:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000824 data = ''
Guido van Rossum49604d31996-09-10 22:19:51 +0000825
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000826 def write(self, data):
827 self.data = self.data + data
Guido van Rossumb819bdf1995-03-15 11:26:26 +0000828
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000829# ignore these commands
Fred Drake43c93501997-12-29 21:40:35 +0000830ignoredcommands = ('bcode', 'ecode', 'hline', 'small', '/')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000831# map commands like these to themselves as plaintext
Guido van Rossum7760cde1995-03-17 16:03:11 +0000832wordsselves = ('UNIX', 'ABC', 'C', 'ASCII', 'EOF', 'LaTeX')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000833# \{ --> {, \} --> }, etc
Guido van Rossum36f219d1996-09-11 21:30:40 +0000834themselves = ('{', '}', ',', '.', '@', ' ', '\n') + wordsselves
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000835# these ones also themselves (see argargs macro in myformat.sty)
836inargsselves = (',', '[', ']', '(', ')')
837# this is how *I* would show the difference between emph and strong
838# code 1 means: fold to uppercase
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000839markcmds = {'code': ('', ''), 'var': 1, 'emph': ('_', '_'),
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000840 'strong': ('*', '*')}
841
842# recognise patter {\FONTCHANGE-CMD TEXT} to \MAPPED-FC-CMD{TEXT}
843fontchanges = {'rm': 'r', 'it': 'i', 'em': 'emph', 'bf': 'b', 'tt': 't'}
844
845# transparent for these commands
Guido van Rossum7760cde1995-03-17 16:03:11 +0000846for_texi = ('emph', 'var', 'strong', 'code', 'kbd', 'key', 'dfn', 'samp',
847 'file', 'r', 'i', 't')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000848
849
850# try to remove macros and return flat text
851def flattext(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000852 pp = crcopy(pp)
853 ##print '---> FLATTEXT ' + `pp`
854 wobj = Wobj()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000855
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000856 i, length = 0, len(pp)
857 while 1:
858 if len(pp) != length:
859 raise 'FATAL', 'inconsistent length'
860 if i >= length:
861 break
862 ch = pp[i]
863 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000864 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000865 pass
Guido van Rossum36f219d1996-09-11 21:30:40 +0000866 elif ch.chtype == chunk_type[CSNAME]:
867 s_buf_data = s(buf, ch.data)
868 if s_buf_data in themselves or hist.inargs and s_buf_data in inargsselves:
869 ch.chtype = chunk_type[PLAIN]
870 elif s_buf_data == 'e':
871 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000872 ch.data = '\\'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000873 elif len(s_buf_data) == 1 \
874 and s_buf_data in onlylatexspecial:
875 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000876 # if it is followed by an empty group,
877 # remove that group, it was needed for
878 # a true space
879 if i < length \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000880 and pp[i].chtype==chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000881 and len(pp[i].data) == 0:
882 del pp[i]
883 length = length-1
884
Guido van Rossum36f219d1996-09-11 21:30:40 +0000885 elif s_buf_data in markcmds.keys():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000886 length, newi = getnextarg(length, buf, pp, i)
887 str = flattext(buf, pp[i:newi])
888 del pp[i:newi]
889 length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000890 ch.chtype = chunk_type[PLAIN]
891 markcmd = s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000892 x = markcmds[markcmd]
893 if type(x) == TupleType:
894 pre, after = x
895 str = pre+str+after
896 elif x == 1:
897 str = string.upper(str)
898 else:
899 raise 'FATAL', 'corrupt markcmds'
900 ch.data = str
901 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000902 if s_buf_data not in ignoredcommands:
903 print 'WARNING: deleting command ' + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000904 print 'PP' + `pp[i-1]`
905 del pp[i-1]
906 i, length = i-1, length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000907 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000908 length, newi = getnextarg(length, buf, pp, i-1)
909 i = i-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000910## str = flattext(buf, crcopy(pp[i-1:newi]))
911## del pp[i:newi]
912## length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000913## ch.chtype = chunk_type[PLAIN]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000914## ch.data = str
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000915 else:
916 pass
917
918 dumpit(buf, wobj.write, pp)
919 ##print 'FLATTEXT: RETURNING ' + `wobj.data`
920 return wobj.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000921
922# try to generate node names (a bit shorter than the chapter title)
923# note that the \nodename command (see elsewhere) overules these efforts
924def invent_node_names(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000925 words = string.split(text)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000926
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000927 ##print 'WORDS ' + `words`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000928
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000929 if len(words) == 2 \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000930 and string.lower(words[0]) == 'built-in' \
931 and string.lower(words[1]) not in ('modules', 'functions'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000932 return words[1]
933 if len(words) == 3 and string.lower(words[1]) == 'module':
934 return words[2]
935 if len(words) == 3 and string.lower(words[1]) == 'object':
936 return string.join(words[0:2])
Guido van Rossum36f219d1996-09-11 21:30:40 +0000937 if len(words) > 4 \
938 and (string.lower(string.join(words[-4:])) \
939 == 'methods and data attributes'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000940 return string.join(words[:2])
941 return text
942
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000943re_commas_etc = regex.compile('[,`\'@{}]')
944
945re_whitespace = regex.compile('[ \t]*')
946
947
948##nodenamecmd = next_command_p(length, buf, pp, newi, 'nodename')
949
950# look if the next non-white stuff is also a command, resulting in skipping
951# double endlines (DENDLINE) too, and thus omitting \par's
952# Sometimes this is too much, maybe consider DENDLINE's as stop
953def next_command_p(length, buf, pp, i, cmdname):
954
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000955 while 1:
956 if i >= len(pp):
957 break
958 ch = pp[i]
959 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000960 if ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000961 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000962 if ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000963 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000964 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000965 if re_whitespace.search(s(buf, ch.data)) == 0 and \
966 re_whitespace.match(s(buf, ch.data)) == len(s(buf, ch.data)):
967 continue
968 return -1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000969 if ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000970 if s(buf, ch.data) == cmdname:
971 return i # _after_ the command
972 return -1
973 return -1
974
975
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000976# things that are special to LaTeX, but not to texi..
977onlylatexspecial = '_~^$#&%'
978
Guido van Rossum23301a91993-05-24 14:19:37 +0000979class Struct: pass
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000980
981hist = Struct()
982out = Struct()
983
984def startchange():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000985 global hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000986
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000987 hist.inenv = []
988 hist.nodenames = []
989 hist.cindex = []
990 hist.inargs = 0
991 hist.enumeratenesting, hist.itemizenesting = 0, 0
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000992
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000993 out.doublenodes = []
994 out.doublecindeces = []
995
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000996
997spacech = [chunk(PLAIN, 0, ' ')]
998commach = [chunk(PLAIN, 0, ', ')]
999cindexch = [chunk(CSLINE, 0, 'cindex')]
1000
1001# the standard variation in symbols for itemize
1002itemizesymbols = ['bullet', 'minus', 'dots']
1003
1004# same for enumerate
1005enumeratesymbols = ['1', 'A', 'a']
1006
1007##
1008## \begin{ {func,data,exc}desc }{name}...
1009## the resulting texi-code is dependent on the contents of indexsubitem
1010##
1011
1012# indexsubitem: `['XXX', 'function']
1013# funcdesc:
1014# deffn {`idxsi`} NAME (FUNCARGS)
1015
1016# indexsubitem: `['XXX', 'method']`
1017# funcdesc:
1018# defmethod {`idxsi[0]`} NAME (FUNCARGS)
1019
1020# indexsubitem: `['in', 'module', 'MODNAME']'
1021# datadesc:
1022# defcv data {`idxsi[1:]`} NAME
1023# excdesc:
1024# defcv exception {`idxsi[1:]`} NAME
1025# funcdesc:
1026# deffn {function of `idxsi[1:]`} NAME (FUNCARGS)
1027
1028# indexsubitem: `['OBJECT', 'attribute']'
1029# datadesc
1030# defcv attribute {`OBJECT`} NAME
1031
1032
1033## this routine will be called on \begin{funcdesc}{NAME}{ARGS}
1034## or \funcline{NAME}{ARGS}
1035##
1036def do_funcdesc(length, buf, pp, i):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001037 startpoint = i-1
1038 ch = pp[startpoint]
1039 wh = ch.where
1040 length, newi = getnextarg(length, buf, pp, i)
1041 funcname = chunk(GROUP, wh, pp[i:newi])
1042 del pp[i:newi]
1043 length = length - (newi-i)
1044 save = hist.inargs
1045 hist.inargs = 1
1046 length, newi = getnextarg(length, buf, pp, i)
1047 hist.inargs = save
1048 del save
1049 the_args = [chunk(PLAIN, wh, '()'[0])] + pp[i:newi] + \
Fred Drake7edd8d31996-10-09 16:11:26 +00001050 [chunk(PLAIN, wh, '()'[1])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001051 del pp[i:newi]
1052 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001053
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001054 idxsi = hist.indexsubitem # words
1055 command = ''
1056 cat_class = ''
Fred Drakeacc87541996-10-14 16:20:42 +00001057 if idxsi and idxsi[-1] in ('method', 'protocol', 'attribute'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001058 command = 'defmethod'
1059 cat_class = string.join(idxsi[:-1])
1060 elif len(idxsi) == 2 and idxsi[1] == 'function':
1061 command = 'deffn'
1062 cat_class = string.join(idxsi)
1063 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1064 command = 'deffn'
1065 cat_class = 'function of ' + string.join(idxsi[1:])
Fred Drakea4541af1997-12-29 17:19:22 +00001066 elif len(idxsi) > 3 and idxsi[:2] == ['in', 'modules']:
1067 command = 'deffn'
1068 cat_class = 'function of ' + string.join(idxsi[1:])
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001069
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001070 if not command:
1071 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001072
Guido van Rossum36f219d1996-09-11 21:30:40 +00001073 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001074 ch.data = command
1075
1076 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1077 cslinearg.append(chunk(PLAIN, wh, ' '))
1078 cslinearg.append(funcname)
1079 cslinearg.append(chunk(PLAIN, wh, ' '))
1080 l = len(cslinearg)
1081 cslinearg[l:l] = the_args
1082
1083 pp.insert(i, chunk(GROUP, wh, cslinearg))
1084 i, length = i+1, length+1
1085 hist.command = command
1086 return length, i
1087
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001088
1089## this routine will be called on \begin{excdesc}{NAME}
1090## or \excline{NAME}
1091##
1092def do_excdesc(length, buf, pp, i):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001093 startpoint = i-1
1094 ch = pp[startpoint]
1095 wh = ch.where
1096 length, newi = getnextarg(length, buf, pp, i)
1097 excname = chunk(GROUP, wh, pp[i:newi])
1098 del pp[i:newi]
1099 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001100
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001101 idxsi = hist.indexsubitem # words
1102 command = ''
1103 cat_class = ''
1104 class_class = ''
1105 if len(idxsi) == 2 and idxsi[1] == 'exception':
1106 command = 'defvr'
1107 cat_class = string.join(idxsi)
1108 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1109 command = 'defcv'
1110 cat_class = 'exception'
1111 class_class = string.join(idxsi[1:])
1112 elif len(idxsi) == 4 and idxsi[:3] == ['exception', 'in', 'module']:
1113 command = 'defcv'
1114 cat_class = 'exception'
1115 class_class = string.join(idxsi[2:])
Fred Drakea4541af1997-12-29 17:19:22 +00001116 elif idxsi == ['built-in', 'exception', 'base', 'class']:
1117 command = 'defcv'
1118 cat_class = 'exception'
1119 class_class = "exception base class"
1120 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001121 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
1122
Guido van Rossum36f219d1996-09-11 21:30:40 +00001123 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001124 ch.data = command
1125
1126 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1127 cslinearg.append(chunk(PLAIN, wh, ' '))
1128 if class_class:
1129 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001130 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001131 cslinearg.append(excname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001132
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001133 pp.insert(i, chunk(GROUP, wh, cslinearg))
1134 i, length = i+1, length+1
1135 hist.command = command
1136 return length, i
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001137
1138## same for datadesc or dataline...
1139def do_datadesc(length, buf, pp, i):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001140 startpoint = i-1
1141 ch = pp[startpoint]
1142 wh = ch.where
1143 length, newi = getnextarg(length, buf, pp, i)
1144 dataname = chunk(GROUP, wh, pp[i:newi])
1145 del pp[i:newi]
1146 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001147
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001148 idxsi = hist.indexsubitem # words
1149 command = ''
1150 cat_class = ''
1151 class_class = ''
1152 if idxsi[-1] in ('attribute', 'option'):
1153 command = 'defcv'
1154 cat_class = idxsi[-1]
1155 class_class = string.join(idxsi[:-1])
1156 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1157 command = 'defcv'
1158 cat_class = 'data'
1159 class_class = string.join(idxsi[1:])
1160 elif len(idxsi) == 4 and idxsi[:3] == ['data', 'in', 'module']:
1161 command = 'defcv'
1162 cat_class = 'data'
1163 class_class = string.join(idxsi[2:])
Fred Drake11b6d241996-10-10 20:09:56 +00001164 else:
1165 command = 'defcv'
1166 cat_class = 'data'
1167 class_class = string.join(idxsi)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001168
Guido van Rossum36f219d1996-09-11 21:30:40 +00001169 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001170 ch.data = command
1171
1172 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1173 cslinearg.append(chunk(PLAIN, wh, ' '))
1174 if class_class:
1175 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001176 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001177 cslinearg.append(dataname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001178
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001179 pp.insert(i, chunk(GROUP, wh, cslinearg))
1180 i, length = i+1, length+1
1181 hist.command = command
1182 return length, i
1183
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001184
Fred Drakea4541af1997-12-29 17:19:22 +00001185def do_opcodedesc(length, buf, pp, i):
1186 startpoint = i-1
1187 ch = pp[startpoint]
1188 wh = ch.where
1189 length, newi = getnextarg(length, buf, pp, i)
1190 dataname = chunk(GROUP, wh, pp[i:newi])
1191 del pp[i:newi]
1192 length = length - (newi-i)
1193
Fred Drake43c93501997-12-29 21:40:35 +00001194 ch.chtype = CSLINE
1195 ch.data = "deffn"
Fred Drakea4541af1997-12-29 17:19:22 +00001196
Fred Drake43c93501997-12-29 21:40:35 +00001197 cslinearg = [#chunk(GROUP, wh, [chunk(PLAIN, wh, "exception")]),
1198 chunk(PLAIN, wh, 'exception '),
Fred Drakea4541af1997-12-29 17:19:22 +00001199 chunk(GROUP, wh, [chunk(PLAIN, wh, "byte code instruction")]),
1200 chunk(PLAIN, wh, ' '),
1201 dataname,
Fred Drake43c93501997-12-29 21:40:35 +00001202 chunk(PLAIN, wh, ' '),
1203 pp[i],
Fred Drakea4541af1997-12-29 17:19:22 +00001204 ]
1205
Fred Drake43c93501997-12-29 21:40:35 +00001206 pp[i] = chunk(GROUP, wh, cslinearg)
Fred Drakea4541af1997-12-29 17:19:22 +00001207 hist.command = ch.data
1208 return length, i
1209
1210
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001211# regular indices: those that are not set in tt font by default....
1212regindices = ('cindex', )
1213
1214# remove illegal characters from node names
1215def rm_commas_etc(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001216 result = ''
1217 changed = 0
1218 while 1:
1219 pos = re_commas_etc.search(text)
1220 if pos >= 0:
1221 changed = 1
1222 result = result + text[:pos]
1223 text = text[pos+1:]
1224 else:
1225 result = result + text
1226 break
1227 if changed:
Fred Drake43c93501997-12-29 21:40:35 +00001228 print 'Warning: nodename changed to ' + `result`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001229
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001230 return result
1231
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001232# boolean flags
1233flags = {'texi': 1}
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001234
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001235
Fred Drake43c93501997-12-29 21:40:35 +00001236# map of \label{} to node names
1237label_nodes = {}
1238
1239
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001240##
1241## changeit: the actual routine, that changes the contents of the parsed
1242## chunks
1243##
1244
1245def changeit(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001246 global onlylatexspecial, hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001247
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001248 i, length = 0, len(pp)
1249 while 1:
1250 # sanity check: length should always equal len(pp)
1251 if len(pp) != length:
1252 raise 'FATAL', 'inconsistent length. thought ' + `length` + ', but should really be ' + `len(pp)`
1253 if i >= length:
1254 break
1255 ch = pp[i]
1256 i = i + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001257
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001258 if type(ch) is StringType:
1259 #normally, only chunks are present in pp,
1260 # but in some cases, some extra info
1261 # has been inserted, e.g., the \end{...} clauses
1262 raise 'FATAL', 'got string, probably too many ' + `end`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001263
Guido van Rossum36f219d1996-09-11 21:30:40 +00001264 if ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001265 # check for {\em ...} constructs
1266 if ch.data and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001267 ch.data[0].chtype == chunk_type[CSNAME] and \
Fred Drake43c93501997-12-29 21:40:35 +00001268 fontchanges.has_key(s(buf, ch.data[0].data)):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001269 k = s(buf, ch.data[0].data)
1270 del ch.data[0]
1271 pp.insert(i-1, chunk(CSNAME, ch.where, fontchanges[k]))
1272 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001273
Fred Drake43c93501997-12-29 21:40:35 +00001274 elif ch.data:
1275 k = s(buf, ch.data[0].data)
1276 if k == "fulllineitems":
1277 del ch.data[0]
1278 data = ch.data
1279 pp[i-1:i] = data
1280 i = i - 1
1281 length = length + len(data) - 1
1282 continue
1283
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001284 # recursively parse the contents of the group
1285 changeit(buf, ch.data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001286
Guido van Rossum36f219d1996-09-11 21:30:40 +00001287 elif ch.chtype == chunk_type[IF]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001288 # \if...
1289 flag, negate, data = ch.data
1290 ##print 'IF: flag, negate = ' + `flag, negate`
1291 if flag not in flags.keys():
1292 raise error, 'unknown flag ' + `flag`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001293
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001294 value = flags[flag]
1295 if negate:
1296 value = (not value)
1297 del pp[i-1]
1298 length, i = length-1, i-1
1299 if value:
1300 pp[i:i] = data
1301 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001302
1303
Guido van Rossum36f219d1996-09-11 21:30:40 +00001304 elif ch.chtype == chunk_type[ENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001305 # \begin{...} ....
1306 envname, data = ch.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001307
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001308 #push this environment name on stack
1309 hist.inenv.insert(0, envname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001310
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001311 #append an endenv chunk after grouped data
1312 data.append(chunk(ENDENV, ch.where, envname))
1313 ##[`data`]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001314
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001315 #delete this object
1316 del pp[i-1]
1317 i, length = i-1, length-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001318
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001319 #insert found data
1320 pp[i:i] = data
1321 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001322
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001323 if envname == 'verbatim':
1324 pp[i:i] = [chunk(CSLINE, ch.where, 'example'),
1325 chunk(GROUP, ch.where, [])]
1326 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001327
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001328 elif envname == 'itemize':
1329 if hist.itemizenesting > len(itemizesymbols):
1330 raise error, 'too deep itemize nesting'
1331 ingroupch = [chunk(CSNAME, ch.where,
1332 itemizesymbols[hist.itemizenesting])]
1333 hist.itemizenesting = hist.itemizenesting + 1
1334 pp[i:i] = [chunk(CSLINE, ch.where, 'itemize'),
1335 chunk(GROUP, ch.where, ingroupch)]
1336 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001337
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001338 elif envname == 'enumerate':
1339 if hist.enumeratenesting > len(enumeratesymbols):
1340 raise error, 'too deep enumerate nesting'
1341 ingroupch = [chunk(PLAIN, ch.where,
1342 enumeratesymbols[hist.enumeratenesting])]
1343 hist.enumeratenesting = hist.enumeratenesting + 1
1344 pp[i:i] = [chunk(CSLINE, ch.where, 'enumerate'),
1345 chunk(GROUP, ch.where, ingroupch)]
1346 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001347
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001348 elif envname == 'description':
1349 ingroupch = [chunk(CSNAME, ch.where, 'b')]
1350 pp[i:i] = [chunk(CSLINE, ch.where, 'table'),
1351 chunk(GROUP, ch.where, ingroupch)]
1352 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001353
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001354 elif (envname == 'tableiii') or (envname == 'tableii'):
1355 if (envname == 'tableii'):
1356 ltable = 2
1357 else:
1358 ltable = 3
1359 wh = ch.where
1360 newcode = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001361
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001362 #delete tabular format description
1363 # e.g., {|l|c|l|}
1364 length, newi = getnextarg(length, buf, pp, i)
1365 del pp[i:newi]
1366 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001367
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001368 newcode.append(chunk(CSLINE, wh, 'table'))
1369 ingroupch = [chunk(CSNAME, wh, 'asis')]
1370 newcode.append(chunk(GROUP, wh, ingroupch))
1371 newcode.append(chunk(CSLINE, wh, 'item'))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001372
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001373 #get the name of macro for @item
1374 # e.g., {code}
1375 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001376
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001377 if newi-i != 1:
1378 raise error, 'Sorry, expected 1 chunk argument'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001379 if pp[i].chtype != chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001380 raise error, 'Sorry, expected plain text argument'
1381 hist.itemargmacro = s(buf, pp[i].data)
1382 del pp[i:newi]
1383 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001384
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001385 itembody = []
1386 for count in range(ltable):
1387 length, newi = getnextarg(length, buf, pp, i)
1388 emphgroup = [
1389 chunk(CSNAME, wh, 'emph'),
1390 chunk(GROUP, 0, pp[i:newi])]
1391 del pp[i:newi]
1392 length = length - (newi-i)
1393 if count == 0:
1394 itemarg = emphgroup
1395 elif count == ltable-1:
1396 itembody = itembody + \
1397 [chunk(PLAIN, wh, ' --- ')] + emphgroup
1398 else:
1399 itembody = emphgroup
1400 newcode.append(chunk(GROUP, wh, itemarg))
1401 newcode = newcode + itembody + [chunk(DENDLINE, wh, '\n')]
1402 pp[i:i] = newcode
1403 l = len(newcode)
1404 length, i = length+l, i+l
1405 del newcode, l
1406
1407 if length != len(pp):
1408 raise 'STILL, SOMETHING wrong', `i`
1409
1410
1411 elif envname == 'funcdesc':
1412 pp.insert(i, chunk(PLAIN, ch.where, ''))
1413 i, length = i+1, length+1
1414 length, i = do_funcdesc(length, buf, pp, i)
1415
1416 elif envname == 'excdesc':
1417 pp.insert(i, chunk(PLAIN, ch.where, ''))
1418 i, length = i+1, length+1
1419 length, i = do_excdesc(length, buf, pp, i)
1420
1421 elif envname == 'datadesc':
1422 pp.insert(i, chunk(PLAIN, ch.where, ''))
1423 i, length = i+1, length+1
1424 length, i = do_datadesc(length, buf, pp, i)
1425
Fred Drakea4541af1997-12-29 17:19:22 +00001426 elif envname == 'opcodedesc':
1427 pp.insert(i, chunk(PLAIN, ch.where, ''))
1428 i, length = i+1, length+1
1429 length, i = do_opcodedesc(length, buf, pp, i)
1430
1431 elif envname == 'seealso':
1432 chunks = [chunk(ENDLINE, ch.where, "\n"),
1433 chunk(CSNAME, ch.where, "b"),
1434 chunk(GROUP, ch.where, [
1435 chunk(PLAIN, ch.where, "See also: ")]),
1436 chunk(ENDLINE, ch.where, "\n"),
1437 chunk(ENDLINE, ch.where, "\n")]
1438 pp[i-1:i] = chunks
1439 length = length + len(chunks) - 1
1440 i = i + len(chunks) - 1
1441
Fred Drake43c93501997-12-29 21:40:35 +00001442 elif envname in ('sloppypar', 'flushleft'):
1443 pass
1444
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001445 else:
1446 print 'WARNING: don\'t know what to do with env ' + `envname`
1447
Guido van Rossum36f219d1996-09-11 21:30:40 +00001448 elif ch.chtype == chunk_type[ENDENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001449 envname = ch.data
1450 if envname != hist.inenv[0]:
1451 raise error, '\'end\' does not match. Name ' + `envname` + ', expected ' + `hist.inenv[0]`
1452 del hist.inenv[0]
1453 del pp[i-1]
1454 i, length = i-1, length-1
1455
1456 if envname == 'verbatim':
Fred Drake43c93501997-12-29 21:40:35 +00001457 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1458 chunk(GROUP, ch.where, [
1459 chunk(PLAIN, ch.where, 'example')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001460 i, length = i+2, length+2
1461 elif envname == 'itemize':
1462 hist.itemizenesting = hist.itemizenesting - 1
Fred Drake43c93501997-12-29 21:40:35 +00001463 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1464 chunk(GROUP, ch.where, [
1465 chunk(PLAIN, ch.where, 'itemize')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001466 i, length = i+2, length+2
1467 elif envname == 'enumerate':
1468 hist.enumeratenesting = hist.enumeratenesting-1
Fred Drake43c93501997-12-29 21:40:35 +00001469 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1470 chunk(GROUP, ch.where, [
1471 chunk(PLAIN, ch.where, 'enumerate')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001472 i, length = i+2, length+2
1473 elif envname == 'description':
Fred Drake43c93501997-12-29 21:40:35 +00001474 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1475 chunk(GROUP, ch.where, [
1476 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001477 i, length = i+2, length+2
1478 elif (envname == 'tableiii') or (envname == 'tableii'):
Fred Drake43c93501997-12-29 21:40:35 +00001479 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1480 chunk(GROUP, ch.where, [
1481 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001482 i, length = i+2, length + 2
1483 pp.insert(i, chunk(DENDLINE, ch.where, '\n'))
1484 i, length = i+1, length+1
1485
1486 elif envname in ('funcdesc', 'excdesc', 'datadesc'):
Fred Drake43c93501997-12-29 21:40:35 +00001487 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1488 chunk(GROUP, ch.where, [
1489 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001490 i, length = i+2, length+2
Fred Drakea4541af1997-12-29 17:19:22 +00001491
Fred Drake43c93501997-12-29 21:40:35 +00001492 elif envname == 'opcodedesc':
1493 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1494 chunk(GROUP, ch.where, [
1495 chunk(PLAIN, ch.where, "deffn")])]
1496 i, length = i+2, length+2
1497
1498 elif envname in ('seealso', 'sloppypar', 'flushleft'):
Fred Drakea4541af1997-12-29 17:19:22 +00001499 pass
1500
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001501 else:
Fred Drakea4541af1997-12-29 17:19:22 +00001502 print 'WARNING: ending env %s has no actions' % `envname`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001503
Guido van Rossum36f219d1996-09-11 21:30:40 +00001504 elif ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001505 # control name transformations
Guido van Rossum36f219d1996-09-11 21:30:40 +00001506 s_buf_data = s(buf, ch.data)
1507 if s_buf_data == 'optional':
1508 pp[i-1].chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001509 pp[i-1].data = '['
1510 if (i < length) and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001511 (pp[i].chtype == chunk_type[GROUP]):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001512 cp=pp[i].data
1513 pp[i:i+1]=cp + [
1514 chunk(PLAIN, ch.where, ']')]
1515 length = length+len(cp)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001516 elif s_buf_data in ignoredcommands:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001517 del pp[i-1]
1518 i, length = i-1, length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001519 elif s_buf_data == '@' and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001520 i != length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001521 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001522 s(buf, pp[i].data)[0] == '.':
1523 # \@. --> \. --> @.
1524 ch.data = '.'
1525 del pp[i]
1526 length = length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001527 elif s_buf_data == '\\':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001528 # \\ --> \* --> @*
1529 ch.data = '*'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001530 elif len(s_buf_data) == 1 and \
1531 s_buf_data in onlylatexspecial:
1532 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001533 # check if such a command is followed by
1534 # an empty group: e.g., `\%{}'. If so, remove
1535 # this empty group too
1536 if i < length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001537 pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001538 and len(pp[i].data) == 0:
1539 del pp[i]
1540 length = length-1
1541
Guido van Rossum36f219d1996-09-11 21:30:40 +00001542 elif hist.inargs and s_buf_data in inargsselves:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001543 # This is the special processing of the
1544 # arguments of the \begin{funcdesc}... or
1545 # \funcline... arguments
1546 # \, --> , \[ --> [, \] --> ]
Guido van Rossum36f219d1996-09-11 21:30:40 +00001547 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001548
Guido van Rossum36f219d1996-09-11 21:30:40 +00001549 elif s_buf_data == 'renewcommand':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001550 # \renewcommand{\indexsubitem}....
1551 i, length = i-1, length-1
1552 del pp[i]
1553 length, newi = getnextarg(length, buf, pp, i)
1554 if newi-i == 1 \
1555 and i < length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001556 and pp[i].chtype == chunk_type[CSNAME] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001557 and s(buf, pp[i].data) == 'indexsubitem':
1558 del pp[i:newi]
1559 length = length - (newi-i)
1560 length, newi = getnextarg(length, buf, pp, i)
1561 text = flattext(buf, pp[i:newi])
1562 if text[:1] != '(' or text[-1:] != ')':
Guido van Rossum36f219d1996-09-11 21:30:40 +00001563 raise error, \
1564 'expected indexsubitem enclosed in parenteses'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001565 words = string.split(text[1:-1])
1566 hist.indexsubitem = words
Guido van Rossum36f219d1996-09-11 21:30:40 +00001567## print 'set hist.indexsubitem =', words
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001568 del text, words
1569 else:
1570 print 'WARNING: renewcommand with unsupported arg removed'
1571 del pp[i:newi]
1572 length = length - (newi-i)
1573
Fred Drake43c93501997-12-29 21:40:35 +00001574 elif s_buf_data == "fulllineitems":
1575 del pp[i-1]
1576 i, length = i-1, length-1
1577
Guido van Rossum36f219d1996-09-11 21:30:40 +00001578 elif s_buf_data == 'item':
1579 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001580 length, newi = getoptarg(length, buf, pp, i)
1581 ingroupch = pp[i:newi]
1582 del pp[i:newi]
1583 length = length - (newi-i)
Fred Drake893e5e01996-10-25 22:13:10 +00001584 changeit(buf, ingroupch) # catch stuff inside the optional arg
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001585 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1586 i, length = i+1, length+1
1587
Guido van Rossum36f219d1996-09-11 21:30:40 +00001588 elif s_buf_data == 'ttindex':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001589 idxsi = hist.indexsubitem
1590
1591 cat_class = ''
1592 if len(idxsi) >= 2 and idxsi[1] in \
1593 ('method', 'function', 'protocol'):
1594 command = 'findex'
1595 elif len(idxsi) >= 2 and idxsi[1] in \
1596 ('exception', 'object'):
1597 command = 'vindex'
Fred Drake7edd8d31996-10-09 16:11:26 +00001598 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1599 command = 'cindex'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001600 else:
Fred Drake7edd8d31996-10-09 16:11:26 +00001601 print 'WARNING: can\'t categorize ' + `idxsi` \
1602 + ' for \'ttindex\' command'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001603 command = 'cindex'
1604
1605 if not cat_class:
1606 cat_class = '('+string.join(idxsi)+')'
1607
Guido van Rossum36f219d1996-09-11 21:30:40 +00001608 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001609 ch.data = command
1610
1611 length, newi = getnextarg(length, buf, pp, i)
1612 arg = pp[i:newi]
1613 del pp[i:newi]
1614 length = length - (newi-i)
1615
1616 cat_arg = [chunk(PLAIN, ch.where, cat_class)]
1617
1618 # determine what should be set in roman, and
1619 # what in tt-font
1620 if command in regindices:
1621
1622 arg = [chunk(CSNAME, ch.where, 't'),
1623 chunk(GROUP, ch.where, arg)]
1624 else:
1625 cat_arg = [chunk(CSNAME, ch.where, 'r'),
1626 chunk(GROUP, ch.where, cat_arg)]
1627
1628 ingroupch = arg + \
1629 [chunk(PLAIN, ch.where, ' ')] + \
1630 cat_arg
1631
1632 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1633 length, i = length+1, i+1
1634
Guido van Rossum36f219d1996-09-11 21:30:40 +00001635 elif s_buf_data == 'ldots':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001636 # \ldots --> \dots{} --> @dots{}
1637 ch.data = 'dots'
1638 if i == length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001639 or pp[i].chtype != chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001640 or pp[i].data != []:
1641 pp.insert(i, chunk(GROUP, ch.where, []))
1642 i, length = i+1, length+1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001643 elif s_buf_data in themselves:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001644 # \UNIX --> UNIX
Guido van Rossum36f219d1996-09-11 21:30:40 +00001645 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001646 if i != length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001647 and pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001648 and pp[i].data == []:
1649 del pp[i]
1650 length = length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001651 elif s_buf_data in for_texi:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001652 pass
1653
Guido van Rossum36f219d1996-09-11 21:30:40 +00001654 elif s_buf_data == 'e':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001655 # "\e" --> "\"
1656 ch.data = '\\'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001657 ch.chtype = chunk_type[PLAIN]
1658 elif s_buf_data in ('lineiii', 'lineii'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001659 # This is the most tricky one
1660 # \lineiii{a1}{a2}[{a3}] -->
1661 # @item @<cts. of itemargmacro>{a1}
1662 # a2 [ -- a3]
1663 #
1664 ##print 'LINEIIIIII!!!!!!!'
Guido van Rossum49604d31996-09-10 22:19:51 +00001665## wobj = Wobj()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001666## dumpit(buf, wobj.write, pp[i-1:i+5])
1667## print '--->' + wobj.data + '<----'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001668 if not hist.inenv:
1669 raise error, 'no environment for lineiii'
1670 if (hist.inenv[0] != 'tableiii') and \
1671 (hist.inenv[0] != 'tableii'):
1672 raise error, \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001673 'wrong command (%s) in wrong environment (%s)' \
1674 % (s_buf_data, `hist.inenv[0]`)
1675 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001676 ch.data = 'item'
1677 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001678 ingroupch = [chunk(CSNAME, 0, hist.itemargmacro),
1679 chunk(GROUP, 0, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001680 del pp[i:newi]
1681 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001682## print 'ITEM ARG: --->',
Guido van Rossum49604d31996-09-10 22:19:51 +00001683## wobj = Wobj()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001684## dumpit(buf, wobj.write, ingroupch)
1685## print wobj.data, '<---'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001686 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1687 grouppos = i
1688 i, length = i+1, length+1
1689 length, i = getnextarg(length, buf, pp, i)
1690 length, newi = getnextarg(length, buf, pp, i)
1691 if newi > i:
1692 # we have a 3rd arg
1693 pp.insert(i, chunk(PLAIN, ch.where, ' --- '))
1694 i = newi + 1
1695 length = length + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001696## pp[grouppos].data = pp[grouppos].data \
1697## + [chunk(PLAIN, ch.where, ' ')] \
1698## + pp[i:newi]
1699## del pp[i:newi]
1700## length = length - (newi-i)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001701 if length != len(pp):
1702 raise 'IN LINEIII IS THE ERR', `i`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001703
Guido van Rossum36f219d1996-09-11 21:30:40 +00001704 elif s_buf_data in ('chapter', 'section', 'subsection', 'subsubsection'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001705 #\xxxsection{A} ---->
1706 # @node A, , ,
1707 # @xxxsection A
1708 ## also: remove commas and quotes
Guido van Rossum36f219d1996-09-11 21:30:40 +00001709 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001710 length, newi = getnextarg(length, buf, pp, i)
1711 afternodenamecmd = next_command_p(length, buf, pp, newi, 'nodename')
1712 if afternodenamecmd < 0:
1713 cp1 = crcopy(pp[i:newi])
Guido van Rossum36f219d1996-09-11 21:30:40 +00001714 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001715 length, newi = length - (newi-i) + 1, i+1
1716 text = flattext(buf, cp1)
1717 text = invent_node_names(text)
1718 else:
1719 length, endarg = getnextarg(length, buf, pp, afternodenamecmd)
1720 cp1 = crcopy(pp[afternodenamecmd:endarg])
1721 del pp[newi:endarg]
1722 length = length - (endarg-newi)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001723
Guido van Rossum36f219d1996-09-11 21:30:40 +00001724 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001725 length, newi = length - (newi-i) + 1, i + 1
1726 text = flattext(buf, cp1)
1727 if text[-1] == '.':
1728 text = text[:-1]
Guido van Rossum7a2dba21993-11-05 14:45:11 +00001729## print 'FLATTEXT:', `text`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001730 if text in hist.nodenames:
1731 print 'WARNING: node name ' + `text` + ' already used'
1732 out.doublenodes.append(text)
1733 else:
1734 hist.nodenames.append(text)
1735 text = rm_commas_etc(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001736 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'node'),
1737 chunk(GROUP, ch.where, [
1738 chunk(PLAIN, ch.where, text+', , ,')
1739 ])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001740 i, length = newi+2, length+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001741
Guido van Rossum36f219d1996-09-11 21:30:40 +00001742 elif s_buf_data == 'funcline':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001743 # fold it to a very short environment
Guido van Rossum36f219d1996-09-11 21:30:40 +00001744 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1745 chunk(GROUP, ch.where, [
1746 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001747 i, length = i+2, length+2
1748 length, i = do_funcdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001749
Guido van Rossum36f219d1996-09-11 21:30:40 +00001750 elif s_buf_data == 'dataline':
1751 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1752 chunk(GROUP, ch.where, [
1753 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001754 i, length = i+2, length+2
1755 length, i = do_datadesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001756
Guido van Rossum36f219d1996-09-11 21:30:40 +00001757 elif s_buf_data == 'excline':
1758 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1759 chunk(GROUP, ch.where, [
1760 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001761 i, length = i+2, length+2
1762 length, i = do_excdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001763
Guido van Rossum36f219d1996-09-11 21:30:40 +00001764 elif s_buf_data == 'index':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001765 #\index{A} --->
1766 # @cindex A
Guido van Rossum36f219d1996-09-11 21:30:40 +00001767 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001768 ch.data = 'cindex'
1769 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001770
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001771 ingroupch = pp[i:newi]
1772 del pp[i:newi]
1773 length = length - (newi-i)
1774 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1775 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001776
Guido van Rossum36f219d1996-09-11 21:30:40 +00001777 elif s_buf_data == 'bifuncindex':
1778 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001779 ch.data = 'findex'
1780 length, newi = getnextarg(length, buf, pp, i)
1781 ingroupch = pp[i:newi]
1782 del pp[i:newi]
1783 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001784
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001785 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1786 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1787 ingroupch.append(chunk(GROUP, ch.where, [
1788 chunk(PLAIN, ch.where,
1789 '(built-in function)')]))
1790
1791 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1792 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001793
Guido van Rossum36f219d1996-09-11 21:30:40 +00001794 elif s_buf_data == 'obindex':
1795 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001796 ch.data = 'findex'
1797 length, newi = getnextarg(length, buf, pp, i)
1798 ingroupch = pp[i:newi]
1799 del pp[i:newi]
1800 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001801
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001802 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1803 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1804 ingroupch.append(chunk(GROUP, ch.where, [
1805 chunk(PLAIN, ch.where,
1806 '(object)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001807
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001808 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1809 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001810
Guido van Rossum36f219d1996-09-11 21:30:40 +00001811 elif s_buf_data == 'opindex':
1812 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001813 ch.data = 'findex'
1814 length, newi = getnextarg(length, buf, pp, i)
1815 ingroupch = pp[i:newi]
1816 del pp[i:newi]
1817 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001818
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001819 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1820 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1821 ingroupch.append(chunk(GROUP, ch.where, [
1822 chunk(PLAIN, ch.where,
1823 '(operator)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001824
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001825 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1826 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001827
Fred Drakea4541af1997-12-29 17:19:22 +00001828 elif s_buf_data in ('bimodindex', 'refbimodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001829 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001830 ch.data = 'pindex'
1831 length, newi = getnextarg(length, buf, pp, i)
1832 ingroupch = pp[i:newi]
1833 del pp[i:newi]
1834 length = length - (newi-i)
1835
1836 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1837 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1838 ingroupch.append(chunk(GROUP, ch.where, [
1839 chunk(PLAIN, ch.where,
1840 '(built-in)')]))
1841
1842 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1843 length, i = length+1, i+1
1844
Fred Drakea4541af1997-12-29 17:19:22 +00001845 elif s_buf_data == 'refmodindex':
1846 ch.chtype = chunk_type[CSLINE]
1847 ch.data = 'pindex'
1848 length, newi = getnextarg(length, buf, pp, i)
1849 ingroupch = pp[i:newi]
1850 del pp[i:newi]
1851 length = length - (newi-i)
1852
Fred Drakea4541af1997-12-29 17:19:22 +00001853 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1854 length, i = length+1, i+1
1855
Guido van Rossum36f219d1996-09-11 21:30:40 +00001856 elif s_buf_data == 'sectcode':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001857 ch.data = 'code'
1858
Fred Drakea4541af1997-12-29 17:19:22 +00001859 elif s_buf_data in ('stmodindex', 'refstmodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001860 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001861 # use the program index as module index
1862 ch.data = 'pindex'
1863 length, newi = getnextarg(length, buf, pp, i)
1864 ingroupch = pp[i:newi]
1865 del pp[i:newi]
1866 length = length - (newi-i)
1867
1868 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1869 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1870 ingroupch.append(chunk(GROUP, ch.where, [
1871 chunk(PLAIN, ch.where,
1872 '(standard)')]))
1873
1874 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1875 length, i = length+1, i+1
1876
Fred Drakea4541af1997-12-29 17:19:22 +00001877 elif s_buf_data in ('stmodindex', 'refstmodindex'):
1878 ch.chtype = chunk_type[CSLINE]
1879 # use the program index as module index
1880 ch.data = 'pindex'
1881 length, newi = getnextarg(length, buf, pp, i)
1882 ingroupch = pp[i:newi]
1883 del pp[i:newi]
1884 length = length - (newi-i)
1885
1886 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1887 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1888 ingroupch.append(chunk(GROUP, ch.where, [
1889 chunk(PLAIN, ch.where,
1890 '(standard)')]))
1891
1892 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1893 length, i = length+1, i+1
1894
1895 elif s_buf_data in ('stindex', 'kwindex'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001896 # XXX must actually go to newindex st
Fred Drakea4541af1997-12-29 17:19:22 +00001897 what = (s_buf_data[:2] == "st") and "statement" or "keyword"
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001898 wh = ch.where
Guido van Rossum36f219d1996-09-11 21:30:40 +00001899 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001900 ch.data = 'cindex'
1901 length, newi = getnextarg(length, buf, pp, i)
1902 ingroupch = [chunk(CSNAME, wh, 'code'),
1903 chunk(GROUP, wh, pp[i:newi])]
1904
1905 del pp[i:newi]
1906 length = length - (newi-i)
1907
1908 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001909 t.append(chunk(PLAIN, wh, ' ' + what))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001910
1911 pp.insert(i, chunk(GROUP, wh, t))
1912 i, length = i+1, length+1
1913
1914 pp.insert(i, chunk(CSLINE, wh, 'cindex'))
1915 i, length = i+1, length+1
1916
1917 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001918 t.insert(0, chunk(PLAIN, wh, what + ', '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001919
1920 pp.insert(i, chunk(GROUP, wh, t))
1921 i, length = i+1, length+1
1922
Guido van Rossum36f219d1996-09-11 21:30:40 +00001923 elif s_buf_data == 'indexii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001924 #\indexii{A}{B} --->
1925 # @cindex A B
1926 # @cindex B, A
1927 length, newi = getnextarg(length, buf, pp, i)
1928 cp11 = pp[i:newi]
1929 cp21 = crcopy(pp[i:newi])
1930 del pp[i:newi]
1931 length = length - (newi-i)
1932 length, newi = getnextarg(length, buf, pp, i)
1933 cp12 = pp[i:newi]
1934 cp22 = crcopy(pp[i:newi])
1935 del pp[i:newi]
1936 length = length - (newi-i)
1937
Guido van Rossum36f219d1996-09-11 21:30:40 +00001938 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001939 ch.data = 'cindex'
1940 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
1941 chunk(PLAIN, ch.where, ' ')] + cp12))
1942 i, length = i+1, length+1
1943 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
1944 chunk(GROUP, ch.where, cp22 + [
1945 chunk(PLAIN, ch.where, ', ')]+ cp21)]
1946 i, length = i+2, length+2
1947
Guido van Rossum36f219d1996-09-11 21:30:40 +00001948 elif s_buf_data == 'indexiii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001949 length, newi = getnextarg(length, buf, pp, i)
1950 cp11 = pp[i:newi]
1951 cp21 = crcopy(pp[i:newi])
1952 cp31 = crcopy(pp[i:newi])
1953 del pp[i:newi]
1954 length = length - (newi-i)
1955 length, newi = getnextarg(length, buf, pp, i)
1956 cp12 = pp[i:newi]
1957 cp22 = crcopy(pp[i:newi])
1958 cp32 = crcopy(pp[i:newi])
1959 del pp[i:newi]
1960 length = length - (newi-i)
1961 length, newi = getnextarg(length, buf, pp, i)
1962 cp13 = pp[i:newi]
1963 cp23 = crcopy(pp[i:newi])
1964 cp33 = crcopy(pp[i:newi])
1965 del pp[i:newi]
1966 length = length - (newi-i)
1967
Guido van Rossum36f219d1996-09-11 21:30:40 +00001968 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001969 ch.data = 'cindex'
1970 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
1971 chunk(PLAIN, ch.where, ' ')] + cp12
1972 + [chunk(PLAIN, ch.where, ' ')]
1973 + cp13))
1974 i, length = i+1, length+1
1975 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
1976 chunk(GROUP, ch.where, cp22 + [
1977 chunk(PLAIN, ch.where, ' ')]+ cp23
1978 + [chunk(PLAIN, ch.where, ', ')] +
1979 cp21)]
1980 i, length = i+2, length+2
1981 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
1982 chunk(GROUP, ch.where, cp33 + [
1983 chunk(PLAIN, ch.where, ', ')]+ cp31
1984 + [chunk(PLAIN, ch.where, ' ')] +
1985 cp32)]
1986 i, length = i+2, length+2
1987
Guido van Rossum36f219d1996-09-11 21:30:40 +00001988 elif s_buf_data == 'indexiv':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001989 length, newi = getnextarg(length, buf, pp, i)
1990 cp11 = pp[i:newi]
1991 cp21 = crcopy(pp[i:newi])
1992 cp31 = crcopy(pp[i:newi])
1993 cp41 = crcopy(pp[i:newi])
1994 del pp[i:newi]
1995 length = length - (newi-i)
1996 length, newi = getnextarg(length, buf, pp, i)
1997 cp12 = pp[i:newi]
1998 cp22 = crcopy(pp[i:newi])
1999 cp32 = crcopy(pp[i:newi])
2000 cp42 = crcopy(pp[i:newi])
2001 del pp[i:newi]
2002 length = length - (newi-i)
2003 length, newi = getnextarg(length, buf, pp, i)
2004 cp13 = pp[i:newi]
2005 cp23 = crcopy(pp[i:newi])
2006 cp33 = crcopy(pp[i:newi])
2007 cp43 = crcopy(pp[i:newi])
2008 del pp[i:newi]
2009 length = length - (newi-i)
2010 length, newi = getnextarg(length, buf, pp, i)
2011 cp14 = pp[i:newi]
2012 cp24 = crcopy(pp[i:newi])
2013 cp34 = crcopy(pp[i:newi])
2014 cp44 = crcopy(pp[i:newi])
2015 del pp[i:newi]
2016 length = length - (newi-i)
2017
Guido van Rossum36f219d1996-09-11 21:30:40 +00002018 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002019 ch.data = 'cindex'
2020 ingroupch = cp11 + \
2021 spacech + cp12 + \
2022 spacech + cp13 + \
2023 spacech + cp14
2024 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
2025 i, length = i+1, length+1
2026 ingroupch = cp22 + \
2027 spacech + cp23 + \
2028 spacech + cp24 + \
2029 commach + cp21
2030 pp[i:i] = cindexch + [
2031 chunk(GROUP, ch.where, ingroupch)]
2032 i, length = i+2, length+2
2033 ingroupch = cp33 + \
2034 spacech + cp34 + \
2035 commach + cp31 + \
2036 spacech + cp32
2037 pp[i:i] = cindexch + [
2038 chunk(GROUP, ch.where, ingroupch)]
2039 i, length = i+2, length+2
2040 ingroupch = cp44 + \
2041 commach + cp41 + \
2042 spacech + cp42 + \
2043 spacech + cp43
2044 pp[i:i] = cindexch + [
2045 chunk(GROUP, ch.where, ingroupch)]
2046 i, length = i+2, length+2
2047
Guido van Rossum36f219d1996-09-11 21:30:40 +00002048## elif s_buf_data == 'indexsubitem':
2049## ch.data = flattext(buf, [ch])
2050## ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002051
Fred Drakea4541af1997-12-29 17:19:22 +00002052 elif s_buf_data == 'seemodule':
2053 ch.data = "code"
2054 data = pp[i+1].data
2055 data.insert(0, chunk(PLAIN, ch.where, " ("))
2056 data.append(chunk(PLAIN, ch.where, ")"))
2057 pp[i+1:i+2] = data
2058 length = length + len(data) - 1
2059
2060 elif s_buf_data == 'seetext':
2061 data = pp[i].data
2062 data.insert(0, chunk(ENDLINE, ch.where, "\n"))
2063 pp[i-1:i+1] = data
2064 i = i - 1
2065 length = length + len(data) - 2
2066
Fred Drake43c93501997-12-29 21:40:35 +00002067 elif s_buf_data == "quad":
2068 ch.chtype = PLAIN
2069 ch.data = " "
2070
Guido van Rossum36f219d1996-09-11 21:30:40 +00002071 elif s_buf_data in ('noindent', 'indexsubitem'):
2072 pass
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002073
Fred Drakea4541af1997-12-29 17:19:22 +00002074 elif s_buf_data == 'label':
Fred Drake43c93501997-12-29 21:40:35 +00002075 name = s(buf, pp[i].data[0].data)
Fred Drakea4541af1997-12-29 17:19:22 +00002076 del pp[i-1:i+1]
2077 length = length - 2
2078 i = i - 1
Fred Drake43c93501997-12-29 21:40:35 +00002079 label_nodes[name] = hist.nodenames[-1]
2080
2081 elif s_buf_data == 'ref':
2082 name = s(buf, pp[i].data[0].data)
2083 if label_nodes.has_key(name):
2084 pp[i].data[0].data = label_nodes[name]
2085 else:
2086 pp[i-1:i+1] = [
2087 chunk(PLAIN, ch.where,
2088 "(unknown node reference: %s)" % name)]
2089 length = length - 1
2090 print "WARNING: unknown node label", `name`
Fred Drakea4541af1997-12-29 17:19:22 +00002091
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002092 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002093 print "don't know what to do with keyword " + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002094
2095
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002096re_atsign = regex.compile('[@{}]')
2097re_newline = regex.compile('\n')
2098
2099def dumpit(buf, wm, pp):
2100
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002101 global out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002102
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002103 i, length = 0, len(pp)
2104
2105 addspace = 0
2106
2107 while 1:
2108 if len(pp) != length:
2109 raise 'FATAL', 'inconsistent length'
2110 if i == length:
2111 break
2112 ch = pp[i]
2113 i = i + 1
2114
Guido van Rossum36f219d1996-09-11 21:30:40 +00002115 dospace = addspace
2116 addspace = 0
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002117
Guido van Rossum36f219d1996-09-11 21:30:40 +00002118 if ch.chtype == chunk_type[CSNAME]:
2119 s_buf_data = s(buf, ch.data)
Fred Drake4b3f0311996-12-13 22:04:31 +00002120 if s_buf_data == 'e':
2121 wm('\\')
2122 continue
2123 if s_buf_data == '$':
2124 wm('$')
2125 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +00002126 wm('@' + s_buf_data)
2127 if s_buf_data == 'node' and \
2128 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002129 s(buf, pp[i].data) in out.doublenodes:
2130 ##XXX doesnt work yet??
2131 wm(' ZZZ-' + zfill(`i`, 4))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002132 if s_buf_data[0] in string.letters:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002133 addspace = 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002134 elif ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002135 if dospace and s(buf, ch.data) not in (' ', '\t'):
2136 wm(' ')
2137 text = s(buf, ch.data)
2138 while 1:
2139 pos = re_atsign.search(text)
2140 if pos < 0:
2141 break
2142 wm(text[:pos] + '@' + text[pos])
2143 text = text[pos+1:]
2144 wm(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00002145 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002146 wm('{')
2147 dumpit(buf, wm, ch.data)
2148 wm('}')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002149 elif ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002150 wm('\n\n')
2151 while i != length and pp[i].chtype in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002152 (chunk_type[DENDLINE], chunk_type[ENDLINE]):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002153 i = i + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002154 elif ch.chtype == chunk_type[OTHER]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002155 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002156 elif ch.chtype == chunk_type[ACTIVE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002157 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002158 elif ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002159 wm('\n')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002160 elif ch.chtype == chunk_type[CSLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002161 if i >= 2 and pp[i-2].chtype not in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002162 (chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2163 and (pp[i-2].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002164 or s(buf, pp[i-2].data)[-1] != '\n'):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002165
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002166 wm('\n')
2167 wm('@' + s(buf, ch.data))
2168 if i == length:
2169 raise error, 'CSLINE expected another chunk'
Guido van Rossum36f219d1996-09-11 21:30:40 +00002170 if pp[i].chtype != chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002171 raise error, 'CSLINE expected GROUP'
2172 if type(pp[i].data) != ListType:
2173 raise error, 'GROUP chould contain []-data'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002174
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002175 wobj = Wobj()
2176 dumpit(buf, wobj.write, pp[i].data)
2177 i = i + 1
2178 text = wobj.data
2179 del wobj
2180 if text:
2181 wm(' ')
2182 while 1:
2183 pos = re_newline.search(text)
2184 if pos < 0:
2185 break
2186 print 'WARNING: found newline in csline arg'
2187 wm(text[:pos] + ' ')
2188 text = text[pos+1:]
2189 wm(text)
2190 if i >= length or \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002191 pp[i].chtype not in (chunk_type[CSLINE],
2192 chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2193 and (pp[i].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002194 or s(buf, pp[i].data)[0] != '\n'):
2195 wm('\n')
Guido van Rossum49604d31996-09-10 22:19:51 +00002196
Guido van Rossum36f219d1996-09-11 21:30:40 +00002197 elif ch.chtype == chunk_type[COMMENT]:
2198## print 'COMMENT: previous chunk =', pp[i-2]
2199## if pp[i-2].chtype == chunk_type[PLAIN]:
2200## print 'PLAINTEXT =', `s(buf, pp[i-2].data)`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002201 if s(buf, ch.data) and \
2202 regex.match('^[ \t]*$', s(buf, ch.data)) < 0:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002203 if i >= 2 \
2204 and pp[i-2].chtype not in (chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2205 and not (pp[i-2].chtype == chunk_type[PLAIN]
2206 and regex.match('\\(.\\|\n\\)*[ \t]*\n$', s(buf, pp[i-2].data)) >= 0):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002207 wm('\n')
2208 wm('@c ' + s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002209 elif ch.chtype == chunk_type[IGNORE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002210 pass
2211 else:
2212 try:
2213 str = `s(buf, ch.data)`
2214 except TypeError:
2215 str = `ch.data`
2216 if len(str) > 400:
2217 str = str[:400] + '...'
2218 print 'warning:', ch.chtype, 'not handled, data ' + str
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002219
2220
2221
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002222def main():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002223 outfile = None
2224 headerfile = 'texipre.dat'
2225 trailerfile = 'texipost.dat'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002226
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002227 try:
2228 opts, args = getopt.getopt(sys.argv[1:], 'o:h:t:')
2229 except getopt.error:
2230 args = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002231
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002232 if not args:
2233 print 'usage: partparse [-o outfile] [-h headerfile]',
2234 print '[-t trailerfile] file ...'
2235 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002236
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002237 for opt, arg in opts:
2238 if opt == '-o': outfile = arg
2239 if opt == '-h': headerfile = arg
2240 if opt == '-t': trailerfile = arg
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002241
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002242 if not outfile:
2243 root, ext = os.path.splitext(args[0])
2244 outfile = root + '.texi'
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002245
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002246 if outfile in args:
2247 print 'will not overwrite input file', outfile
2248 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002249
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002250 outf = open(outfile, 'w')
2251 outf.write(open(headerfile, 'r').read())
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002252
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002253 for file in args:
2254 if len(args) > 1: print '='*20, file, '='*20
2255 buf = open(file, 'r').read()
2256 w, pp = parseit(buf)
2257 startchange()
2258 changeit(buf, pp)
2259 dumpit(buf, outf.write, pp)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002260
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002261 outf.write(open(trailerfile, 'r').read())
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002262
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002263 outf.close()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002264
Guido van Rossum49604d31996-09-10 22:19:51 +00002265if __name__ == "__main__":
2266 main()