blob: 36ffb6ca19c4ce1dca183bc8c40f85f4f99d6830 [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
Fred Drakee8b46131998-02-17 05:54:46 +000020#
21# (sometime later...)
22#
23# Ok, I've re-worked substantial chunks of this. It's only getting worse.
24# It just might be gone before the next source release. (Yeah!)
25#
26# -fld
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000027
Guido van Rossum7a2dba21993-11-05 14:45:11 +000028import sys, string, regex, getopt, os
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000029
Guido van Rossum49604d31996-09-10 22:19:51 +000030from types import IntType, ListType, StringType, TupleType
31
Fred Drakee8b46131998-02-17 05:54:46 +000032release_version = sys.version[:3]
33
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000034# Different parse modes for phase 1
35MODE_REGULAR = 0
36MODE_VERBATIM = 1
37MODE_CS_SCAN = 2
38MODE_COMMENT = 3
39MODE_MATH = 4
40MODE_DMATH = 5
41MODE_GOBBLEWHITE = 6
42
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000043the_modes = (MODE_REGULAR, MODE_VERBATIM, MODE_CS_SCAN, MODE_COMMENT,
Guido van Rossum36f219d1996-09-11 21:30:40 +000044 MODE_MATH, MODE_DMATH, MODE_GOBBLEWHITE)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000045
46# Show the neighbourhood of the scanned buffer
47def epsilon(buf, where):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000048 wmt, wpt = where - 10, where + 10
49 if wmt < 0:
50 wmt = 0
51 if wpt > len(buf):
52 wpt = len(buf)
53 return ' Context ' + `buf[wmt:where]` + '.' + `buf[where:wpt]` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000054
55# Should return the line number. never worked
56def lin():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000057 global lineno
58 return ' Line ' + `lineno` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000059
60# Displays the recursion level.
61def lv(lvl):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000062 return ' Level ' + `lvl` + '.'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000063
64# Combine the three previous functions. Used often.
65def lle(lvl, buf, where):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000066 return lv(lvl) + lin() + epsilon(buf, where)
67
68
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000069# This class is only needed for _symbolic_ representation of the parse mode.
70class Mode:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000071 def __init__(self, arg):
72 if arg not in the_modes:
73 raise ValueError, 'mode not in the_modes'
74 self.mode = arg
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000075
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000076 def __cmp__(self, other):
77 if type(self) != type(other):
Guido van Rossum36f219d1996-09-11 21:30:40 +000078 other = mode[other]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000079 return cmp(self.mode, other.mode)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000080
Guido van Rossum5f18d6c1996-09-10 22:34:20 +000081 def __repr__(self):
82 if self.mode == MODE_REGULAR:
83 return 'MODE_REGULAR'
84 elif self.mode == MODE_VERBATIM:
85 return 'MODE_VERBATIM'
86 elif self.mode == MODE_CS_SCAN:
87 return 'MODE_CS_SCAN'
88 elif self.mode == MODE_COMMENT:
89 return 'MODE_COMMENT'
90 elif self.mode == MODE_MATH:
91 return 'MODE_MATH'
92 elif self.mode == MODE_DMATH:
93 return 'MODE_DMATH'
94 elif self.mode == MODE_GOBBLEWHITE:
95 return 'MODE_GOBBLEWHITE'
96 else:
97 raise ValueError, 'mode not in the_modes'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +000098
99# just a wrapper around a class initialisation
Guido van Rossum36f219d1996-09-11 21:30:40 +0000100mode = {}
101for t in the_modes:
102 mode[t] = Mode(t)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000103
104
105# After phase 1, the text consists of chunks, with a certain type
106# this type will be assigned to the chtype member of the chunk
107# the where-field contains the file position where this is found
108# and the data field contains (1): a tuple describing start- end end
109# positions of the substring (can be used as slice for the buf-variable),
110# (2) just a string, mostly generated by the changeit routine,
111# or (3) a list, describing a (recursive) subgroup of chunks
112PLAIN = 0 # ASSUME PLAINTEXT, data = the text
113GROUP = 1 # GROUP ({}), data = [chunk, chunk,..]
114CSNAME = 2 # CONTROL SEQ TOKEN, data = the command
115COMMENT = 3 # data is the actual comment
116DMATH = 4 # DISPLAYMATH, data = [chunk, chunk,..]
117MATH = 5 # MATH, see DISPLAYMATH
118OTHER = 6 # CHAR WITH CATCODE OTHER, data = char
119ACTIVE = 7 # ACTIVE CHAR
120GOBBLEDWHITE = 8 # Gobbled LWSP, after CSNAME
121ENDLINE = 9 # END-OF-LINE, data = '\n'
122DENDLINE = 10 # DOUBLE EOL, data='\n', indicates \par
123ENV = 11 # LaTeX-environment
Guido van Rossum36f219d1996-09-11 21:30:40 +0000124 # data =(envname,[ch,ch,ch,.])
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000125CSLINE = 12 # for texi: next chunk will be one group
Guido van Rossum36f219d1996-09-11 21:30:40 +0000126 # of args. Will be set all on 1 line
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000127IGNORE = 13 # IGNORE this data
128ENDENV = 14 # TEMP END OF GROUP INDICATOR
129IF = 15 # IF-directive
Guido van Rossum36f219d1996-09-11 21:30:40 +0000130 # data = (flag,negate,[ch, ch, ch,...])
131
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000132the_types = (PLAIN, GROUP, CSNAME, COMMENT, DMATH, MATH, OTHER, ACTIVE,
Guido van Rossum36f219d1996-09-11 21:30:40 +0000133 GOBBLEDWHITE, ENDLINE, DENDLINE, ENV, CSLINE, IGNORE, ENDENV, IF)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000134
135# class, just to display symbolic name
136class ChunkType:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000137 def __init__(self, chunk_type):
138 if chunk_type not in the_types:
139 raise ValueError, 'chunk_type not in the_types'
140 self.chunk_type = chunk_type
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000141
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000142 def __cmp__(self, other):
143 if type(self) != type(other):
Guido van Rossum36f219d1996-09-11 21:30:40 +0000144 other = chunk_type[other]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000145 return cmp(self.chunk_type, other.chunk_type)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000146
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000147 def __repr__(self):
148 if self.chunk_type == PLAIN:
149 return 'PLAIN'
150 elif self.chunk_type == GROUP:
151 return 'GROUP'
152 elif self.chunk_type == CSNAME:
153 return 'CSNAME'
154 elif self.chunk_type == COMMENT:
155 return 'COMMENT'
156 elif self.chunk_type == DMATH:
157 return 'DMATH'
158 elif self.chunk_type == MATH:
159 return 'MATH'
160 elif self.chunk_type == OTHER:
161 return 'OTHER'
162 elif self.chunk_type == ACTIVE:
163 return 'ACTIVE'
164 elif self.chunk_type == GOBBLEDWHITE:
165 return 'GOBBLEDWHITE'
166 elif self.chunk_type == DENDLINE:
167 return 'DENDLINE'
168 elif self.chunk_type == ENDLINE:
169 return 'ENDLINE'
170 elif self.chunk_type == ENV:
171 return 'ENV'
172 elif self.chunk_type == CSLINE:
173 return 'CSLINE'
174 elif self.chunk_type == IGNORE:
175 return 'IGNORE'
176 elif self.chunk_type == ENDENV:
177 return 'ENDENV'
178 elif self.chunk_type == IF:
179 return 'IF'
180 else:
181 raise ValueError, 'chunk_type not in the_types'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000182
183# ...and the wrapper
Guido van Rossum36f219d1996-09-11 21:30:40 +0000184chunk_type = {}
Guido van Rossum49604d31996-09-10 22:19:51 +0000185for t in the_types:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000186 chunk_type[t] = ChunkType(t)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000187
188# store a type object of the ChunkType-class-instance...
Guido van Rossum36f219d1996-09-11 21:30:40 +0000189chunk_type_type = type(chunk_type[PLAIN])
Guido van Rossum49604d31996-09-10 22:19:51 +0000190
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000191# this class contains a part of the parsed buffer
192class Chunk:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000193 def __init__(self, chtype, where, data):
194 if type(chtype) != chunk_type_type:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000195 chtype = chunk_type[chtype]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000196 self.chtype = chtype
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000197 self.where = where
198 self.data = data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000199
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000200 def __repr__(self):
201 return 'chunk' + `self.chtype, self.where, self.data`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000202
203# and the wrapper
Guido van Rossum49604d31996-09-10 22:19:51 +0000204chunk = Chunk
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000205
206
207error = 'partparse.error'
208
209#
210# TeX's catcodes...
211#
212CC_ESCAPE = 0
213CC_LBRACE = 1
214CC_RBRACE = 2
215CC_MATHSHIFT = 3
216CC_ALIGNMENT = 4
217CC_ENDLINE = 5
218CC_PARAMETER = 6
219CC_SUPERSCRIPT = 7
220CC_SUBSCRIPT = 8
221CC_IGNORE = 9
222CC_WHITE = 10
223CC_LETTER = 11
224CC_OTHER = 12
225CC_ACTIVE = 13
226CC_COMMENT = 14
227CC_INVALID = 15
228
229# and the names
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000230cc_names = [
231 'CC_ESCAPE',
232 'CC_LBRACE',
233 'CC_RBRACE',
234 'CC_MATHSHIFT',
235 'CC_ALIGNMENT',
236 'CC_ENDLINE',
237 'CC_PARAMETER',
238 'CC_SUPERSCRIPT',
239 'CC_SUBSCRIPT',
240 'CC_IGNORE',
241 'CC_WHITE',
242 'CC_LETTER',
243 'CC_OTHER',
244 'CC_ACTIVE',
245 'CC_COMMENT',
246 'CC_INVALID',
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000247 ]
248
249# Show a list of catcode-name-symbols
250def pcl(codelist):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000251 result = ''
252 for i in codelist:
253 result = result + cc_names[i] + ', '
254 return '[' + result[:-2] + ']'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000255
256# the name of the catcode (ACTIVE, OTHER, etc.)
257def pc(code):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000258 return cc_names[code]
259
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000260
261# Which catcodes make the parser stop parsing regular plaintext
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000262regular_stopcodes = [CC_ESCAPE, CC_LBRACE, CC_RBRACE, CC_MATHSHIFT,
263 CC_ALIGNMENT, CC_PARAMETER, CC_SUPERSCRIPT, CC_SUBSCRIPT,
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000264 CC_IGNORE, CC_ACTIVE, CC_COMMENT, CC_INVALID, CC_ENDLINE]
265
266# same for scanning a control sequence name
267csname_scancodes = [CC_LETTER]
268
269# same for gobbling LWSP
270white_scancodes = [CC_WHITE]
271##white_scancodes = [CC_WHITE, CC_ENDLINE]
272
273# make a list of all catcode id's, except for catcode ``other''
274all_but_other_codes = range(16)
275del all_but_other_codes[CC_OTHER]
276##print all_but_other_codes
277
278# when does a comment end
279comment_stopcodes = [CC_ENDLINE]
280
281# gather all characters together, specified by a list of catcodes
282def code2string(cc, codelist):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000283 ##print 'code2string: codelist = ' + pcl(codelist),
284 result = ''
285 for category in codelist:
286 if cc[category]:
287 result = result + cc[category]
288 ##print 'result = ' + `result`
289 return result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000290
291# automatically generate all characters of catcode other, being the
292# complement set in the ASCII range (128 characters)
293def make_other_codes(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000294 otherchars = range(256) # could be made 256, no problem
295 for category in all_but_other_codes:
296 if cc[category]:
297 for c in cc[category]:
298 otherchars[ord(c)] = None
299 result = ''
300 for i in otherchars:
301 if i != None:
302 result = result + chr(i)
303 return result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000304
305# catcode dump (which characters have which catcodes).
306def dump_cc(name, cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000307 ##print '\t' + name
308 ##print '=' * (8+len(name))
309 if len(cc) != 16:
310 raise TypeError, 'cc not good cat class'
Guido van Rossum7a2dba21993-11-05 14:45:11 +0000311## for i in range(16):
312## print pc(i) + '\t' + `cc[i]`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000313
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000314
315# In the beginning,....
316epoch_cc = [None] * 16
317##dump_cc('epoch_cc', epoch_cc)
318
319
320# INITEX
321initex_cc = epoch_cc[:]
322initex_cc[CC_ESCAPE] = '\\'
323initex_cc[CC_ENDLINE], initex_cc[CC_IGNORE], initex_cc[CC_WHITE] = \
324 '\n', '\0', ' '
325initex_cc[CC_LETTER] = string.uppercase + string.lowercase
326initex_cc[CC_COMMENT], initex_cc[CC_INVALID] = '%', '\x7F'
327#initex_cc[CC_OTHER] = make_other_codes(initex_cc) I don't need them, anyway
328##dump_cc('initex_cc', initex_cc)
329
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000330
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000331# LPLAIN: LaTeX catcode setting (see lplain.tex)
332lplain_cc = initex_cc[:]
333lplain_cc[CC_LBRACE], lplain_cc[CC_RBRACE] = '{', '}'
334lplain_cc[CC_MATHSHIFT] = '$'
335lplain_cc[CC_ALIGNMENT] = '&'
336lplain_cc[CC_PARAMETER] = '#'
337lplain_cc[CC_SUPERSCRIPT] = '^\x0B' # '^' and C-k
338lplain_cc[CC_SUBSCRIPT] = '_\x01' # '_' and C-a
339lplain_cc[CC_WHITE] = lplain_cc[CC_WHITE] + '\t'
340lplain_cc[CC_ACTIVE] = '~\x0C' # '~' and C-l
341lplain_cc[CC_OTHER] = make_other_codes(lplain_cc)
342##dump_cc('lplain_cc', lplain_cc)
343
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000344
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000345# Guido's LaTeX environment catcoded '_' as ``other''
346# my own purpose catlist
347my_cc = lplain_cc[:]
348my_cc[CC_SUBSCRIPT] = my_cc[CC_SUBSCRIPT][1:] # remove '_' here
349my_cc[CC_OTHER] = my_cc[CC_OTHER] + '_' # add it to OTHER list
350dump_cc('my_cc', my_cc)
351
352
353
354# needed for un_re, my equivalent for regexp-quote in Emacs
355re_meaning = '\\[]^$'
356
357def un_re(str):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000358 result = ''
359 for i in str:
360 if i in re_meaning:
361 result = result + '\\'
362 result = result + i
363 return result
364
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000365# NOTE the negate ('^') operator in *some* of the regexps below
366def make_rc_regular(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000367 # problems here if '[]' are included!!
368 return regex.compile('[' + code2string(cc, regular_stopcodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000369
370def make_rc_cs_scan(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000371 return regex.compile('[^' + code2string(cc, csname_scancodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000372
373def make_rc_comment(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000374 return regex.compile('[' + code2string(cc, comment_stopcodes) + ']')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000375
376def make_rc_endwhite(cc):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000377 return regex.compile('[^' + code2string(cc, white_scancodes) + ']')
378
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000379
380
381# regular: normal mode:
382rc_regular = make_rc_regular(my_cc)
383
384# scan: scan a command sequence e.g. `newlength' or `mbox' or `;', `,' or `$'
385rc_cs_scan = make_rc_cs_scan(my_cc)
386rc_comment = make_rc_comment(my_cc)
387rc_endwhite = make_rc_endwhite(my_cc)
388
389
Guido van Rossum36f219d1996-09-11 21:30:40 +0000390# parseit (BUF, PARSEMODE=mode[MODE_REGULAR], START=0, RECURSION-LEVEL=0)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000391# RECURSION-LEVEL will is incremented on entry.
392# result contains the list of chunks returned
393# together with this list, the buffer position is returned
394
395# RECURSION-LEVEL will be set to zero *again*, when recursively a
396# {,D}MATH-mode scan has been enetered.
397# This has been done in order to better check for environment-mismatches
398
Guido van Rossum36f219d1996-09-11 21:30:40 +0000399def parseit(buf, parsemode=mode[MODE_REGULAR], start=0, lvl=0):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000400 global lineno
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000401
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000402 result = []
403 end = len(buf)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000404 if lvl == 0 and parsemode == mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000405 lineno = 1
406 lvl = lvl + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000407
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000408 ##print 'parseit(' + epsilon(buf, start) + ', ' + `parsemode` + ', ' + `start` + ', ' + `lvl` + ')'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000409
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000410 #
411 # some of the more regular modes...
412 #
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000413
Guido van Rossum36f219d1996-09-11 21:30:40 +0000414 if parsemode in (mode[MODE_REGULAR], mode[MODE_DMATH], mode[MODE_MATH]):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000415 cstate = []
416 newpos = start
417 curpmode = parsemode
418 while 1:
419 where = newpos
420 #print '\tnew round: ' + epsilon(buf, where)
421 if where == end:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000422 if lvl > 1 or curpmode != mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000423 # not the way we started...
424 raise EOFError, 'premature end of file.' + lle(lvl, buf, where)
425 # the real ending of lvl-1 parse
426 return end, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000427
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000428 pos = rc_regular.search(buf, where)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000429
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000430 if pos < 0:
431 pos = end
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000432
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000433 if pos != where:
434 newpos, c = pos, chunk(PLAIN, where, (where, pos))
435 result.append(c)
436 continue
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000437
438
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000439 #
440 # ok, pos == where and pos != end
441 #
442 foundchar = buf[where]
443 if foundchar in my_cc[CC_LBRACE]:
444 # recursive subgroup parse...
445 newpos, data = parseit(buf, curpmode, where+1, lvl)
446 result.append(chunk(GROUP, where, data))
447
448 elif foundchar in my_cc[CC_RBRACE]:
449 if lvl <= 1:
450 raise error, 'ENDGROUP while in base level.' + lle(lvl, buf, where)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000451 if lvl == 1 and mode != mode[MODE_REGULAR]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000452 raise error, 'endgroup while in math mode. +lin() + epsilon(buf, where)'
453 return where + 1, result
454
455 elif foundchar in my_cc[CC_ESCAPE]:
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000456 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000457 # call the routine that actually deals with
458 # this problem. If do_ret is None, than
459 # return the value of do_ret
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000460 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000461 # Note that handle_cs might call this routine
462 # recursively again...
463 #
464 do_ret, newpos = handlecs(buf, where,
465 curpmode, lvl, result, end)
466 if do_ret != None:
467 return do_ret
468
469 elif foundchar in my_cc[CC_COMMENT]:
470 newpos, data = parseit(buf,
Guido van Rossum36f219d1996-09-11 21:30:40 +0000471 mode[MODE_COMMENT], where+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000472 result.append(chunk(COMMENT, where, data))
473
474 elif foundchar in my_cc[CC_MATHSHIFT]:
475 # note that recursive calls to math-mode
476 # scanning are called with recursion-level 0
477 # again, in order to check for bad mathend
478 #
479 if where + 1 != end and buf[where + 1] in my_cc[CC_MATHSHIFT]:
480 #
481 # double mathshift, e.g. '$$'
482 #
Guido van Rossum36f219d1996-09-11 21:30:40 +0000483 if curpmode == mode[MODE_REGULAR]:
484 newpos, data = parseit(buf, mode[MODE_DMATH],
485 where + 2, 0)
486 result.append(chunk(DMATH, where, data))
487 elif curpmode == mode[MODE_MATH]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000488 raise error, 'wrong math delimiiter' + lin() + epsilon(buf, where)
489 elif lvl != 1:
490 raise error, 'bad mathend.' + lle(lvl, buf, where)
491 else:
492 return where + 2, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000493 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000494 #
495 # single math shift, e.g. '$'
496 #
Guido van Rossum36f219d1996-09-11 21:30:40 +0000497 if curpmode == mode[MODE_REGULAR]:
498 newpos, data = parseit(buf, mode[MODE_MATH],
499 where + 1, 0)
500 result.append(chunk(MATH, where, data))
501 elif curpmode == mode[MODE_DMATH]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000502 raise error, 'wrong math delimiiter' + lin() + epsilon(buf, where)
503 elif lvl != 1:
504 raise error, 'bad mathend.' + lv(lvl, buf, where)
505 else:
506 return where + 1, result
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000507
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000508 elif foundchar in my_cc[CC_IGNORE]:
509 print 'warning: ignored char', `foundchar`
510 newpos = where + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000511
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000512 elif foundchar in my_cc[CC_ACTIVE]:
513 result.append(chunk(ACTIVE, where, foundchar))
514 newpos = where + 1
515
516 elif foundchar in my_cc[CC_INVALID]:
517 raise error, 'invalid char ' + `foundchar`
518 newpos = where + 1
519
520 elif foundchar in my_cc[CC_ENDLINE]:
521 #
522 # after an end of line, eat the rest of
523 # whitespace on the beginning of the next line
524 # this is what LaTeX more or less does
525 #
526 # also, try to indicate double newlines (\par)
527 #
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000528 lineno = lineno + 1
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000529 savedwhere = where
Guido van Rossum36f219d1996-09-11 21:30:40 +0000530 newpos, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], where + 1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000531 if newpos != end and buf[newpos] in my_cc[CC_ENDLINE]:
532 result.append(chunk(DENDLINE, savedwhere, foundchar))
533 else:
534 result.append(chunk(ENDLINE, savedwhere, foundchar))
535 else:
536 result.append(chunk(OTHER, where, foundchar))
537 newpos = where + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000538
Guido van Rossum36f219d1996-09-11 21:30:40 +0000539 elif parsemode == mode[MODE_CS_SCAN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000540 #
541 # scan for a control sequence token. `\ape', `\nut' or `\%'
542 #
543 if start == end:
544 raise EOFError, 'can\'t find end of csname'
545 pos = rc_cs_scan.search(buf, start)
546 if pos < 0:
547 pos = end
548 if pos == start:
549 # first non-letter right where we started the search
550 # ---> the control sequence name consists of one single
551 # character. Also: don't eat white space...
552 if buf[pos] in my_cc[CC_ENDLINE]:
553 lineno = lineno + 1
554 pos = pos + 1
555 return pos, (start, pos)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000556 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000557 spos = pos
558 if buf[pos] == '\n':
559 lineno = lineno + 1
560 spos = pos + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000561 pos2, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], spos, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000562 return pos2, (start, pos)
563
Guido van Rossum36f219d1996-09-11 21:30:40 +0000564 elif parsemode == mode[MODE_GOBBLEWHITE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000565 if start == end:
566 return start, ''
567 pos = rc_endwhite.search(buf, start)
568 if pos < 0:
569 pos = start
570 return pos, (start, pos)
571
Guido van Rossum36f219d1996-09-11 21:30:40 +0000572 elif parsemode == mode[MODE_COMMENT]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000573 pos = rc_comment.search(buf, start)
574 lineno = lineno + 1
575 if pos < 0:
576 print 'no newline perhaps?'
577 raise EOFError, 'can\'t find end of comment'
578 pos = pos + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000579 pos2, dummy = parseit(buf, mode[MODE_GOBBLEWHITE], pos, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000580 return pos2, (start, pos)
581
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000582 else:
583 raise error, 'Unknown mode (' + `parsemode` + ')'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000584
585
586#moreresult = cswitch(buf[x1:x2], buf, newpos, parsemode, lvl)
587
588#boxcommands = 'mbox', 'fbox'
589#defcommands = 'def', 'newcommand'
590
591endverbstr = '\\end{verbatim}'
592
593re_endverb = regex.compile(un_re(endverbstr))
594
595#
596# handlecs: helper function for parseit, for the special thing we might
597# wanna do after certain command control sequences
598# returns: None or return_data, newpos
599#
600# in the latter case, the calling function is instructed to immediately
601# return with the data in return_data
602#
603def handlecs(buf, where, curpmode, lvl, result, end):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000604 global lineno
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000605
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000606 # get the control sequence name...
Guido van Rossum36f219d1996-09-11 21:30:40 +0000607 newpos, data = parseit(buf, mode[MODE_CS_SCAN], where+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000608 saveddata = data
Guido van Rossum36f219d1996-09-11 21:30:40 +0000609 s_buf_data = s(buf, data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000610
Guido van Rossum36f219d1996-09-11 21:30:40 +0000611 if s_buf_data in ('begin', 'end'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000612 # skip the expected '{' and get the LaTeX-envname '}'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000613 newpos, data = parseit(buf, mode[MODE_REGULAR], newpos+1, lvl)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000614 if len(data) != 1:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000615 raise error, 'expected 1 chunk of data.' + lle(lvl, buf, where)
Guido van Rossum49604d31996-09-10 22:19:51 +0000616
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000617 # yucky, we've got an environment
618 envname = s(buf, data[0].data)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000619 s_buf_saveddata = s(buf, saveddata)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000620 ##print 'FOUND ' + s(buf, saveddata) + '. Name ' + `envname` + '.' + lv(lvl)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000621 if s_buf_saveddata == 'begin' and envname == 'verbatim':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000622 # verbatim deserves special treatment
623 pos = re_endverb.search(buf, newpos)
624 if pos < 0:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000625 raise error, "%s not found.%s" \
626 % (`endverbstr`, lle(lvl, buf, where))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000627 result.append(chunk(ENV, where, (envname, [chunk(PLAIN, newpos, (newpos, pos))])))
628 newpos = pos + len(endverbstr)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000629
Guido van Rossum36f219d1996-09-11 21:30:40 +0000630 elif s_buf_saveddata == 'begin':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000631 # start parsing recursively... If that parse returns
632 # from an '\end{...}', then should the last item of
633 # the returned data be a string containing the ended
634 # environment
635 newpos, data = parseit(buf, curpmode, newpos, lvl)
636 if not data or type(data[-1]) is not StringType:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000637 raise error, "missing 'end'" + lle(lvl, buf, where) \
638 + epsilon(buf, newpos)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000639 retenv = data[-1]
640 del data[-1]
641 if retenv != envname:
642 #[`retenv`, `envname`]
Guido van Rossum36f219d1996-09-11 21:30:40 +0000643 raise error, 'environments do not match.%s%s' \
644 % (lle(lvl, buf, where), epsilon(buf, newpos))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000645 result.append(chunk(ENV, where, (retenv, data)))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000646 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000647 # 'end'... append the environment name, as just
648 # pointed out, and order parsit to return...
649 result.append(envname)
650 ##print 'POINT of return: ' + epsilon(buf, newpos)
651 # the tuple will be returned by parseit
652 return (newpos, result), newpos
653
654 # end of \begin ... \end handling
655
Guido van Rossum36f219d1996-09-11 21:30:40 +0000656 elif s_buf_data[0:2] == 'if':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000657 # another scary monster: the 'if' directive
Guido van Rossum36f219d1996-09-11 21:30:40 +0000658 flag = s_buf_data[2:]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000659
660 # recursively call parseit, just like environment above..
661 # the last item of data should contain the if-termination
662 # e.g., 'else' of 'fi'
663 newpos, data = parseit(buf, curpmode, newpos, lvl)
664 if not data or data[-1] not in ('else', 'fi'):
665 raise error, 'wrong if... termination' + \
666 lle(lvl, buf, where) + epsilon(buf, newpos)
667
668 ifterm = data[-1]
669 del data[-1]
670 # 0 means dont_negate flag
671 result.append(chunk(IF, where, (flag, 0, data)))
672 if ifterm == 'else':
673 # do the whole thing again, there is only one way
674 # to end this one, by 'fi'
675 newpos, data = parseit(buf, curpmode, newpos, lvl)
676 if not data or data[-1] not in ('fi', ):
677 raise error, 'wrong if...else... termination' \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000678 + lle(lvl, buf, where) \
679 + epsilon(buf, newpos)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000680
681 ifterm = data[-1]
682 del data[-1]
683 result.append(chunk(IF, where, (flag, 1, data)))
684 #done implicitely: return None, newpos
685
Guido van Rossum36f219d1996-09-11 21:30:40 +0000686 elif s_buf_data in ('else', 'fi'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000687 result.append(s(buf, data))
688 # order calling party to return tuple
689 return (newpos, result), newpos
690
691 # end of \if, \else, ... \fi handling
692
693 elif s(buf, saveddata) == 'verb':
694 x2 = saveddata[1]
695 result.append(chunk(CSNAME, where, data))
696 if x2 == end:
697 raise error, 'premature end of command.' + lle(lvl, buf, where)
698 delimchar = buf[x2]
699 ##print 'VERB: delimchar ' + `delimchar`
700 pos = regex.compile(un_re(delimchar)).search(buf, x2 + 1)
701 if pos < 0:
702 raise error, 'end of \'verb\' argument (' + \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000703 `delimchar` + ') not found.' + \
704 lle(lvl, buf, where)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000705 result.append(chunk(GROUP, x2, [chunk(PLAIN, x2+1, (x2+1, pos))]))
706 newpos = pos + 1
707 else:
708 result.append(chunk(CSNAME, where, data))
709 return None, newpos
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000710
711# this is just a function to get the string value if the possible data-tuple
712def s(buf, data):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000713 if type(data) is StringType:
714 return data
715 if len(data) != 2 or not (type(data[0]) is type(data[1]) is IntType):
716 raise TypeError, 'expected tuple of 2 integers'
717 x1, x2 = data
718 return buf[x1:x2]
Guido van Rossum49604d31996-09-10 22:19:51 +0000719
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000720
721##length, data1, i = getnextarg(length, buf, pp, i + 1)
722
723# make a deep-copy of some chunks
724def crcopy(r):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000725 return map(chunkcopy, r)
Guido van Rossum49604d31996-09-10 22:19:51 +0000726
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000727
728# copy a chunk, would better be a method of class Chunk...
729def chunkcopy(ch):
Guido van Rossum36f219d1996-09-11 21:30:40 +0000730 if ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000731 return chunk(GROUP, ch.where, map(chunkcopy, ch.data))
732 else:
733 return chunk(ch.chtype, ch.where, ch.data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000734
735
736# get next argument for TeX-macro, flatten a group (insert between)
737# or return Command Sequence token, or give back one character
738def getnextarg(length, buf, pp, item):
739
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000740 ##wobj = Wobj()
741 ##dumpit(buf, wobj.write, pp[item:min(length, item + 5)])
742 ##print 'GETNEXTARG, (len, item) =', `length, item` + ' ---> ' + wobj.data + ' <---'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000743
Guido van Rossum36f219d1996-09-11 21:30:40 +0000744 while item < length and pp[item].chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000745 del pp[item]
746 length = length - 1
747 if item >= length:
748 raise error, 'no next arg.' + epsilon(buf, pp[-1].where)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000749 if pp[item].chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000750 newpp = pp[item].data
751 del pp[item]
752 length = length - 1
753 changeit(buf, newpp)
754 length = length + len(newpp)
755 pp[item:item] = newpp
756 item = item + len(newpp)
757 if len(newpp) < 10:
758 wobj = Wobj()
759 dumpit(buf, wobj.write, newpp)
760 ##print 'GETNEXTARG: inserted ' + `wobj.data`
761 return length, item
Guido van Rossum36f219d1996-09-11 21:30:40 +0000762 elif pp[item].chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000763 #grab one char
764 print 'WARNING: grabbing one char'
765 if len(s(buf, pp[item].data)) > 1:
766 pp.insert(item, chunk(PLAIN, pp[item].where, s(buf, pp[item].data)[:1]))
767 item, length = item+1, length+1
768 pp[item].data = s(buf, pp[item].data)[1:]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000769 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000770 item = item+1
771 return length, item
772 else:
773 ch = pp[item]
774 try:
775 str = `s(buf, ch.data)`
776 except TypeError:
777 str = `ch.data`
778 if len(str) > 400:
779 str = str[:400] + '...'
780 print 'GETNEXTARG:', ch.chtype, 'not handled, data ' + str
781 return length, item
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000782
783
784# this one is needed to find the end of LaTeX's optional argument, like
785# item[...]
786re_endopt = regex.compile(']')
787
788# get a LaTeX-optional argument, you know, the square braces '[' and ']'
789def getoptarg(length, buf, pp, item):
790
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000791 wobj = Wobj()
792 dumpit(buf, wobj.write, pp[item:min(length, item + 5)])
793 ##print 'GETOPTARG, (len, item) =', `length, item` + ' ---> ' + wobj.data + ' <---'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000794
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000795 if item >= length or \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000796 pp[item].chtype != chunk_type[PLAIN] or \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000797 s(buf, pp[item].data)[0] != '[':
798 return length, item
799
800 pp[item].data = s(buf, pp[item].data)[1:]
801 if len(pp[item].data) == 0:
802 del pp[item]
803 length = length-1
804
805 while 1:
806 if item == length:
807 raise error, 'No end of optional arg found'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000808 if pp[item].chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000809 text = s(buf, pp[item].data)
810 pos = re_endopt.search(text)
811 if pos >= 0:
812 pp[item].data = text[:pos]
813 if pos == 0:
814 del pp[item]
815 length = length-1
816 else:
817 item=item+1
818 text = text[pos+1:]
819
820 while text and text[0] in ' \t':
821 text = text[1:]
822
823 if text:
824 pp.insert(item, chunk(PLAIN, 0, text))
825 length = length + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000826 return length, item
827
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000828 item = item+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000829
830
831# Wobj just add write-requests to the ``data'' attribute
832class Wobj:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000833 data = ''
Guido van Rossum49604d31996-09-10 22:19:51 +0000834
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000835 def write(self, data):
836 self.data = self.data + data
Guido van Rossumb819bdf1995-03-15 11:26:26 +0000837
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000838# ignore these commands
Fred Drake43c93501997-12-29 21:40:35 +0000839ignoredcommands = ('bcode', 'ecode', 'hline', 'small', '/')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000840# map commands like these to themselves as plaintext
Fred Drakee8b46131998-02-17 05:54:46 +0000841wordsselves = ('UNIX', 'ABC', 'C', 'ASCII', 'EOF', 'LaTeX', 'POSIX')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000842# \{ --> {, \} --> }, etc
Guido van Rossum36f219d1996-09-11 21:30:40 +0000843themselves = ('{', '}', ',', '.', '@', ' ', '\n') + wordsselves
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000844# these ones also themselves (see argargs macro in myformat.sty)
845inargsselves = (',', '[', ']', '(', ')')
846# this is how *I* would show the difference between emph and strong
847# code 1 means: fold to uppercase
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000848markcmds = {'code': ('', ''), 'var': 1, 'emph': ('_', '_'),
Fred Drakee8b46131998-02-17 05:54:46 +0000849 'strong': ('*', '*')}
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000850
851# recognise patter {\FONTCHANGE-CMD TEXT} to \MAPPED-FC-CMD{TEXT}
852fontchanges = {'rm': 'r', 'it': 'i', 'em': 'emph', 'bf': 'b', 'tt': 't'}
853
854# transparent for these commands
Guido van Rossum7760cde1995-03-17 16:03:11 +0000855for_texi = ('emph', 'var', 'strong', 'code', 'kbd', 'key', 'dfn', 'samp',
856 'file', 'r', 'i', 't')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000857
858
859# try to remove macros and return flat text
860def flattext(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000861 pp = crcopy(pp)
862 ##print '---> FLATTEXT ' + `pp`
863 wobj = Wobj()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000864
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000865 i, length = 0, len(pp)
866 while 1:
867 if len(pp) != length:
868 raise 'FATAL', 'inconsistent length'
869 if i >= length:
870 break
871 ch = pp[i]
872 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000873 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000874 pass
Guido van Rossum36f219d1996-09-11 21:30:40 +0000875 elif ch.chtype == chunk_type[CSNAME]:
876 s_buf_data = s(buf, ch.data)
877 if s_buf_data in themselves or hist.inargs and s_buf_data in inargsselves:
878 ch.chtype = chunk_type[PLAIN]
879 elif s_buf_data == 'e':
880 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000881 ch.data = '\\'
Guido van Rossum36f219d1996-09-11 21:30:40 +0000882 elif len(s_buf_data) == 1 \
883 and s_buf_data in onlylatexspecial:
884 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000885 # if it is followed by an empty group,
886 # remove that group, it was needed for
887 # a true space
888 if i < length \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000889 and pp[i].chtype==chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000890 and len(pp[i].data) == 0:
891 del pp[i]
892 length = length-1
893
Guido van Rossum36f219d1996-09-11 21:30:40 +0000894 elif s_buf_data in markcmds.keys():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000895 length, newi = getnextarg(length, buf, pp, i)
896 str = flattext(buf, pp[i:newi])
897 del pp[i:newi]
898 length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000899 ch.chtype = chunk_type[PLAIN]
900 markcmd = s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000901 x = markcmds[markcmd]
902 if type(x) == TupleType:
903 pre, after = x
904 str = pre+str+after
905 elif x == 1:
906 str = string.upper(str)
907 else:
908 raise 'FATAL', 'corrupt markcmds'
909 ch.data = str
910 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000911 if s_buf_data not in ignoredcommands:
912 print 'WARNING: deleting command ' + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000913 print 'PP' + `pp[i-1]`
914 del pp[i-1]
915 i, length = i-1, length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000916 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000917 length, newi = getnextarg(length, buf, pp, i-1)
918 i = i-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000919## str = flattext(buf, crcopy(pp[i-1:newi]))
920## del pp[i:newi]
921## length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000922## ch.chtype = chunk_type[PLAIN]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000923## ch.data = str
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000924 else:
925 pass
926
927 dumpit(buf, wobj.write, pp)
928 ##print 'FLATTEXT: RETURNING ' + `wobj.data`
929 return wobj.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000930
931# try to generate node names (a bit shorter than the chapter title)
932# note that the \nodename command (see elsewhere) overules these efforts
933def invent_node_names(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000934 words = string.split(text)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000935
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000936 ##print 'WORDS ' + `words`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000937
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000938 if len(words) == 2 \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000939 and string.lower(words[0]) == 'built-in' \
940 and string.lower(words[1]) not in ('modules', 'functions'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000941 return words[1]
942 if len(words) == 3 and string.lower(words[1]) == 'module':
943 return words[2]
944 if len(words) == 3 and string.lower(words[1]) == 'object':
945 return string.join(words[0:2])
Guido van Rossum36f219d1996-09-11 21:30:40 +0000946 if len(words) > 4 \
947 and (string.lower(string.join(words[-4:])) \
948 == 'methods and data attributes'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000949 return string.join(words[:2])
950 return text
951
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000952re_commas_etc = regex.compile('[,`\'@{}]')
953
954re_whitespace = regex.compile('[ \t]*')
955
956
957##nodenamecmd = next_command_p(length, buf, pp, newi, 'nodename')
958
959# look if the next non-white stuff is also a command, resulting in skipping
960# double endlines (DENDLINE) too, and thus omitting \par's
961# Sometimes this is too much, maybe consider DENDLINE's as stop
962def next_command_p(length, buf, pp, i, cmdname):
963
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000964 while 1:
965 if i >= len(pp):
966 break
967 ch = pp[i]
968 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000969 if ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000970 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000971 if ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000972 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000973 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000974 if re_whitespace.search(s(buf, ch.data)) == 0 and \
975 re_whitespace.match(s(buf, ch.data)) == len(s(buf, ch.data)):
976 continue
977 return -1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000978 if ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000979 if s(buf, ch.data) == cmdname:
980 return i # _after_ the command
981 return -1
982 return -1
983
984
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000985# things that are special to LaTeX, but not to texi..
986onlylatexspecial = '_~^$#&%'
987
Guido van Rossum23301a91993-05-24 14:19:37 +0000988class Struct: pass
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000989
990hist = Struct()
991out = Struct()
992
993def startchange():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000994 global hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000995
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000996 hist.inenv = []
997 hist.nodenames = []
998 hist.cindex = []
999 hist.inargs = 0
1000 hist.enumeratenesting, hist.itemizenesting = 0, 0
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001001
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001002 out.doublenodes = []
1003 out.doublecindeces = []
1004
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001005
1006spacech = [chunk(PLAIN, 0, ' ')]
1007commach = [chunk(PLAIN, 0, ', ')]
1008cindexch = [chunk(CSLINE, 0, 'cindex')]
1009
1010# the standard variation in symbols for itemize
1011itemizesymbols = ['bullet', 'minus', 'dots']
1012
1013# same for enumerate
1014enumeratesymbols = ['1', 'A', 'a']
1015
Fred Drake9c7c6be1998-02-19 21:40:22 +00001016d = {}
1017for name in ('url', 'module', 'function', 'cfunction',
1018 'keyword', 'method', 'exception', 'constant',
1019 'email', 'class', 'member', 'cdata', 'ctype',
1020 'member'):
1021 d[name] = 'code'
1022d['program'] = 'strong'
1023d['sectcode'] = 'code'
1024convertible_csname = d.has_key
1025conversion = d.get
1026del d, name
1027
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001028##
1029## \begin{ {func,data,exc}desc }{name}...
1030## the resulting texi-code is dependent on the contents of indexsubitem
1031##
1032
1033# indexsubitem: `['XXX', 'function']
1034# funcdesc:
1035# deffn {`idxsi`} NAME (FUNCARGS)
1036
1037# indexsubitem: `['XXX', 'method']`
1038# funcdesc:
1039# defmethod {`idxsi[0]`} NAME (FUNCARGS)
1040
1041# indexsubitem: `['in', 'module', 'MODNAME']'
1042# datadesc:
1043# defcv data {`idxsi[1:]`} NAME
1044# excdesc:
1045# defcv exception {`idxsi[1:]`} NAME
1046# funcdesc:
1047# deffn {function of `idxsi[1:]`} NAME (FUNCARGS)
1048
1049# indexsubitem: `['OBJECT', 'attribute']'
1050# datadesc
1051# defcv attribute {`OBJECT`} NAME
1052
1053
1054## this routine will be called on \begin{funcdesc}{NAME}{ARGS}
1055## or \funcline{NAME}{ARGS}
1056##
Fred Drakee8b46131998-02-17 05:54:46 +00001057def do_funcdesc(length, buf, pp, i, index=1):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001058 startpoint = i-1
1059 ch = pp[startpoint]
1060 wh = ch.where
1061 length, newi = getnextarg(length, buf, pp, i)
1062 funcname = chunk(GROUP, wh, pp[i:newi])
1063 del pp[i:newi]
1064 length = length - (newi-i)
1065 save = hist.inargs
1066 hist.inargs = 1
1067 length, newi = getnextarg(length, buf, pp, i)
1068 hist.inargs = save
1069 del save
1070 the_args = [chunk(PLAIN, wh, '()'[0])] + pp[i:newi] + \
Fred Drake7edd8d31996-10-09 16:11:26 +00001071 [chunk(PLAIN, wh, '()'[1])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001072 del pp[i:newi]
1073 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001074
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001075 idxsi = hist.indexsubitem # words
1076 command = ''
1077 cat_class = ''
Fred Drakeacc87541996-10-14 16:20:42 +00001078 if idxsi and idxsi[-1] in ('method', 'protocol', 'attribute'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001079 command = 'defmethod'
1080 cat_class = string.join(idxsi[:-1])
1081 elif len(idxsi) == 2 and idxsi[1] == 'function':
1082 command = 'deffn'
1083 cat_class = string.join(idxsi)
1084 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1085 command = 'deffn'
1086 cat_class = 'function of ' + string.join(idxsi[1:])
Fred Drakea4541af1997-12-29 17:19:22 +00001087 elif len(idxsi) > 3 and idxsi[:2] == ['in', 'modules']:
1088 command = 'deffn'
1089 cat_class = 'function of ' + string.join(idxsi[1:])
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001090
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001091 if not command:
1092 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001093
Guido van Rossum36f219d1996-09-11 21:30:40 +00001094 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001095 ch.data = command
1096
1097 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1098 cslinearg.append(chunk(PLAIN, wh, ' '))
1099 cslinearg.append(funcname)
1100 cslinearg.append(chunk(PLAIN, wh, ' '))
1101 l = len(cslinearg)
1102 cslinearg[l:l] = the_args
1103
1104 pp.insert(i, chunk(GROUP, wh, cslinearg))
1105 i, length = i+1, length+1
1106 hist.command = command
1107 return length, i
1108
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001109
1110## this routine will be called on \begin{excdesc}{NAME}
1111## or \excline{NAME}
1112##
1113def do_excdesc(length, buf, pp, i):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001114 startpoint = i-1
1115 ch = pp[startpoint]
1116 wh = ch.where
1117 length, newi = getnextarg(length, buf, pp, i)
1118 excname = chunk(GROUP, wh, pp[i:newi])
1119 del pp[i:newi]
1120 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001121
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001122 idxsi = hist.indexsubitem # words
1123 command = ''
1124 cat_class = ''
1125 class_class = ''
1126 if len(idxsi) == 2 and idxsi[1] == 'exception':
1127 command = 'defvr'
1128 cat_class = string.join(idxsi)
1129 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1130 command = 'defcv'
1131 cat_class = 'exception'
1132 class_class = string.join(idxsi[1:])
1133 elif len(idxsi) == 4 and idxsi[:3] == ['exception', 'in', 'module']:
1134 command = 'defcv'
1135 cat_class = 'exception'
1136 class_class = string.join(idxsi[2:])
Fred Drakea4541af1997-12-29 17:19:22 +00001137 elif idxsi == ['built-in', 'exception', 'base', 'class']:
Fred Drakee8b46131998-02-17 05:54:46 +00001138 command = 'defvr'
1139 cat_class = 'exception base class'
Fred Drakea4541af1997-12-29 17:19:22 +00001140 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001141 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
1142
Guido van Rossum36f219d1996-09-11 21:30:40 +00001143 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001144 ch.data = command
1145
1146 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1147 cslinearg.append(chunk(PLAIN, wh, ' '))
1148 if class_class:
1149 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001150 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001151 cslinearg.append(excname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001152
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001153 pp.insert(i, chunk(GROUP, wh, cslinearg))
1154 i, length = i+1, length+1
1155 hist.command = command
1156 return length, i
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001157
1158## same for datadesc or dataline...
Fred Drakee8b46131998-02-17 05:54:46 +00001159def do_datadesc(length, buf, pp, i, index=1):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001160 startpoint = i-1
1161 ch = pp[startpoint]
1162 wh = ch.where
1163 length, newi = getnextarg(length, buf, pp, i)
1164 dataname = chunk(GROUP, wh, pp[i:newi])
1165 del pp[i:newi]
1166 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001167
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001168 idxsi = hist.indexsubitem # words
Fred Drakee8b46131998-02-17 05:54:46 +00001169 command = 'defcv'
1170 cat_class = 'data'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001171 class_class = ''
1172 if idxsi[-1] in ('attribute', 'option'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001173 cat_class = idxsi[-1]
1174 class_class = string.join(idxsi[:-1])
1175 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001176 class_class = string.join(idxsi[1:])
1177 elif len(idxsi) == 4 and idxsi[:3] == ['data', 'in', 'module']:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001178 class_class = string.join(idxsi[2:])
Fred Drake11b6d241996-10-10 20:09:56 +00001179 else:
Fred Drake11b6d241996-10-10 20:09:56 +00001180 class_class = string.join(idxsi)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001181
Guido van Rossum36f219d1996-09-11 21:30:40 +00001182 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001183 ch.data = command
1184
1185 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1186 cslinearg.append(chunk(PLAIN, wh, ' '))
1187 if class_class:
1188 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001189 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001190 cslinearg.append(dataname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001191
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001192 pp.insert(i, chunk(GROUP, wh, cslinearg))
1193 i, length = i+1, length+1
1194 hist.command = command
1195 return length, i
1196
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001197
Fred Drakea4541af1997-12-29 17:19:22 +00001198def do_opcodedesc(length, buf, pp, i):
1199 startpoint = i-1
1200 ch = pp[startpoint]
1201 wh = ch.where
1202 length, newi = getnextarg(length, buf, pp, i)
1203 dataname = chunk(GROUP, wh, pp[i:newi])
1204 del pp[i:newi]
1205 length = length - (newi-i)
1206
Fred Drake43c93501997-12-29 21:40:35 +00001207 ch.chtype = CSLINE
1208 ch.data = "deffn"
Fred Drakea4541af1997-12-29 17:19:22 +00001209
Fred Drakee8b46131998-02-17 05:54:46 +00001210 cslinearg = [chunk(PLAIN, wh, 'byte\ code\ instruction'),
Fred Drakea4541af1997-12-29 17:19:22 +00001211 chunk(GROUP, wh, [chunk(PLAIN, wh, "byte code instruction")]),
1212 chunk(PLAIN, wh, ' '),
1213 dataname,
Fred Drake43c93501997-12-29 21:40:35 +00001214 chunk(PLAIN, wh, ' '),
1215 pp[i],
Fred Drakea4541af1997-12-29 17:19:22 +00001216 ]
1217
Fred Drake43c93501997-12-29 21:40:35 +00001218 pp[i] = chunk(GROUP, wh, cslinearg)
Fred Drakea4541af1997-12-29 17:19:22 +00001219 hist.command = ch.data
1220 return length, i
1221
1222
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001223# regular indices: those that are not set in tt font by default....
1224regindices = ('cindex', )
1225
1226# remove illegal characters from node names
1227def rm_commas_etc(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001228 result = ''
1229 changed = 0
1230 while 1:
1231 pos = re_commas_etc.search(text)
1232 if pos >= 0:
1233 changed = 1
1234 result = result + text[:pos]
1235 text = text[pos+1:]
1236 else:
1237 result = result + text
1238 break
1239 if changed:
Fred Drake43c93501997-12-29 21:40:35 +00001240 print 'Warning: nodename changed to ' + `result`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001241
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001242 return result
1243
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001244# boolean flags
1245flags = {'texi': 1}
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001246
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001247
Fred Drake43c93501997-12-29 21:40:35 +00001248# map of \label{} to node names
1249label_nodes = {}
1250
1251
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001252##
1253## changeit: the actual routine, that changes the contents of the parsed
1254## chunks
1255##
1256
1257def changeit(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001258 global onlylatexspecial, hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001259
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001260 i, length = 0, len(pp)
1261 while 1:
1262 # sanity check: length should always equal len(pp)
1263 if len(pp) != length:
1264 raise 'FATAL', 'inconsistent length. thought ' + `length` + ', but should really be ' + `len(pp)`
1265 if i >= length:
1266 break
1267 ch = pp[i]
1268 i = i + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001269
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001270 if type(ch) is StringType:
1271 #normally, only chunks are present in pp,
1272 # but in some cases, some extra info
1273 # has been inserted, e.g., the \end{...} clauses
1274 raise 'FATAL', 'got string, probably too many ' + `end`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001275
Guido van Rossum36f219d1996-09-11 21:30:40 +00001276 if ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001277 # check for {\em ...} constructs
Fred Drakee8b46131998-02-17 05:54:46 +00001278 data = ch.data
1279 if data and \
1280 data[0].chtype == chunk_type[CSNAME] and \
1281 fontchanges.has_key(s(buf, data[0].data)):
1282 k = s(buf, data[0].data)
1283 del data[0]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001284 pp.insert(i-1, chunk(CSNAME, ch.where, fontchanges[k]))
1285 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001286
Fred Drakee8b46131998-02-17 05:54:46 +00001287 elif data:
1288 if len(data) \
1289 and data[0].chtype == chunk_type[GROUP] \
1290 and len(data[0].data) \
1291 and data[0].data[0].chtype == chunk_type[CSNAME] \
1292 and s(buf, data[0].data[0].data) == 'e':
1293 data[0] = data[0].data[0]
1294 print "invoking \\e magic group transform..."
1295 else:
1296## print "GROUP -- ch.data[0].data =", ch.data[0].data
1297 k = s(buf, data[0].data)
1298 if k == "fulllineitems":
1299 del data[0]
1300 pp[i-1:i] = data
1301 i = i - 1
1302 length = length + len(data) - 1
1303 continue
Fred Drake43c93501997-12-29 21:40:35 +00001304
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001305 # recursively parse the contents of the group
Fred Drakee8b46131998-02-17 05:54:46 +00001306 changeit(buf, data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001307
Guido van Rossum36f219d1996-09-11 21:30:40 +00001308 elif ch.chtype == chunk_type[IF]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001309 # \if...
1310 flag, negate, data = ch.data
1311 ##print 'IF: flag, negate = ' + `flag, negate`
1312 if flag not in flags.keys():
1313 raise error, 'unknown flag ' + `flag`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001314
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001315 value = flags[flag]
1316 if negate:
1317 value = (not value)
1318 del pp[i-1]
1319 length, i = length-1, i-1
1320 if value:
1321 pp[i:i] = data
1322 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001323
1324
Guido van Rossum36f219d1996-09-11 21:30:40 +00001325 elif ch.chtype == chunk_type[ENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001326 # \begin{...} ....
1327 envname, data = ch.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001328
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001329 #push this environment name on stack
1330 hist.inenv.insert(0, envname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001331
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001332 #append an endenv chunk after grouped data
1333 data.append(chunk(ENDENV, ch.where, envname))
1334 ##[`data`]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001335
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001336 #delete this object
1337 del pp[i-1]
1338 i, length = i-1, length-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001339
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001340 #insert found data
1341 pp[i:i] = data
1342 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001343
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001344 if envname == 'verbatim':
1345 pp[i:i] = [chunk(CSLINE, ch.where, 'example'),
1346 chunk(GROUP, ch.where, [])]
1347 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001348
Fred Drakeef058031998-02-19 15:20:30 +00001349 elif envname in ('itemize', 'list', 'fulllineitems'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001350 if hist.itemizenesting > len(itemizesymbols):
1351 raise error, 'too deep itemize nesting'
Fred Drakee8b46131998-02-17 05:54:46 +00001352 if envname == 'list':
1353 del pp[i:i+2]
1354 length = length - 2
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001355 ingroupch = [chunk(CSNAME, ch.where,
Fred Drakee8b46131998-02-17 05:54:46 +00001356 itemizesymbols[hist.itemizenesting])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001357 hist.itemizenesting = hist.itemizenesting + 1
1358 pp[i:i] = [chunk(CSLINE, ch.where, 'itemize'),
Fred Drakee8b46131998-02-17 05:54:46 +00001359 chunk(GROUP, ch.where, ingroupch)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001360 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001361
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001362 elif envname == 'enumerate':
1363 if hist.enumeratenesting > len(enumeratesymbols):
1364 raise error, 'too deep enumerate nesting'
1365 ingroupch = [chunk(PLAIN, ch.where,
Fred Drakee8b46131998-02-17 05:54:46 +00001366 enumeratesymbols[hist.enumeratenesting])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001367 hist.enumeratenesting = hist.enumeratenesting + 1
1368 pp[i:i] = [chunk(CSLINE, ch.where, 'enumerate'),
Fred Drakee8b46131998-02-17 05:54:46 +00001369 chunk(GROUP, ch.where, ingroupch)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001370 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001371
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001372 elif envname == 'description':
1373 ingroupch = [chunk(CSNAME, ch.where, 'b')]
1374 pp[i:i] = [chunk(CSLINE, ch.where, 'table'),
1375 chunk(GROUP, ch.where, ingroupch)]
1376 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001377
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001378 elif (envname == 'tableiii') or (envname == 'tableii'):
1379 if (envname == 'tableii'):
1380 ltable = 2
1381 else:
1382 ltable = 3
1383 wh = ch.where
1384 newcode = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001385
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001386 #delete tabular format description
1387 # e.g., {|l|c|l|}
1388 length, newi = getnextarg(length, buf, pp, i)
1389 del pp[i:newi]
1390 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001391
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001392 newcode.append(chunk(CSLINE, wh, 'table'))
1393 ingroupch = [chunk(CSNAME, wh, 'asis')]
1394 newcode.append(chunk(GROUP, wh, ingroupch))
1395 newcode.append(chunk(CSLINE, wh, 'item'))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001396
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001397 #get the name of macro for @item
1398 # e.g., {code}
1399 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001400
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001401 if newi-i != 1:
1402 raise error, 'Sorry, expected 1 chunk argument'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001403 if pp[i].chtype != chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001404 raise error, 'Sorry, expected plain text argument'
1405 hist.itemargmacro = s(buf, pp[i].data)
Fred Drake9c7c6be1998-02-19 21:40:22 +00001406 if convertible_csname(hist.itemargmacro):
1407 hist.itemargmacro = conversion(hist.itemargmacro)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001408 del pp[i:newi]
1409 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001410
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001411 itembody = []
1412 for count in range(ltable):
1413 length, newi = getnextarg(length, buf, pp, i)
1414 emphgroup = [
1415 chunk(CSNAME, wh, 'emph'),
1416 chunk(GROUP, 0, pp[i:newi])]
1417 del pp[i:newi]
1418 length = length - (newi-i)
1419 if count == 0:
1420 itemarg = emphgroup
1421 elif count == ltable-1:
1422 itembody = itembody + \
1423 [chunk(PLAIN, wh, ' --- ')] + emphgroup
1424 else:
1425 itembody = emphgroup
1426 newcode.append(chunk(GROUP, wh, itemarg))
1427 newcode = newcode + itembody + [chunk(DENDLINE, wh, '\n')]
1428 pp[i:i] = newcode
1429 l = len(newcode)
1430 length, i = length+l, i+l
1431 del newcode, l
1432
1433 if length != len(pp):
1434 raise 'STILL, SOMETHING wrong', `i`
1435
Fred Drakeef058031998-02-19 15:20:30 +00001436 elif envname in ('funcdesc', 'funcdescni', 'classdesc'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001437 pp.insert(i, chunk(PLAIN, ch.where, ''))
1438 i, length = i+1, length+1
Fred Drakee8b46131998-02-17 05:54:46 +00001439 length, i = do_funcdesc(length, buf, pp, i,
Fred Drakeef058031998-02-19 15:20:30 +00001440 envname[-2:] != "ni")
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001441
1442 elif envname == 'excdesc':
1443 pp.insert(i, chunk(PLAIN, ch.where, ''))
1444 i, length = i+1, length+1
1445 length, i = do_excdesc(length, buf, pp, i)
1446
Fred Drakee8b46131998-02-17 05:54:46 +00001447 elif envname in ('datadesc', 'datadescni'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001448 pp.insert(i, chunk(PLAIN, ch.where, ''))
1449 i, length = i+1, length+1
Fred Drakee8b46131998-02-17 05:54:46 +00001450 length, i = do_datadesc(length, buf, pp, i,
Fred Drakeef058031998-02-19 15:20:30 +00001451 envname[-2:] != "ni")
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001452
Fred Drakea4541af1997-12-29 17:19:22 +00001453 elif envname == 'opcodedesc':
1454 pp.insert(i, chunk(PLAIN, ch.where, ''))
1455 i, length = i+1, length+1
1456 length, i = do_opcodedesc(length, buf, pp, i)
1457
1458 elif envname == 'seealso':
1459 chunks = [chunk(ENDLINE, ch.where, "\n"),
1460 chunk(CSNAME, ch.where, "b"),
1461 chunk(GROUP, ch.where, [
1462 chunk(PLAIN, ch.where, "See also: ")]),
1463 chunk(ENDLINE, ch.where, "\n"),
1464 chunk(ENDLINE, ch.where, "\n")]
1465 pp[i-1:i] = chunks
1466 length = length + len(chunks) - 1
1467 i = i + len(chunks) - 1
1468
Fred Drake43c93501997-12-29 21:40:35 +00001469 elif envname in ('sloppypar', 'flushleft'):
1470 pass
1471
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001472 else:
1473 print 'WARNING: don\'t know what to do with env ' + `envname`
1474
Guido van Rossum36f219d1996-09-11 21:30:40 +00001475 elif ch.chtype == chunk_type[ENDENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001476 envname = ch.data
1477 if envname != hist.inenv[0]:
1478 raise error, '\'end\' does not match. Name ' + `envname` + ', expected ' + `hist.inenv[0]`
1479 del hist.inenv[0]
1480 del pp[i-1]
1481 i, length = i-1, length-1
1482
1483 if envname == 'verbatim':
Fred Drake43c93501997-12-29 21:40:35 +00001484 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1485 chunk(GROUP, ch.where, [
1486 chunk(PLAIN, ch.where, 'example')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001487 i, length = i+2, length+2
Fred Drakeef058031998-02-19 15:20:30 +00001488 elif envname in ('itemize', 'list', 'fulllineitems'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001489 hist.itemizenesting = hist.itemizenesting - 1
Fred Drake43c93501997-12-29 21:40:35 +00001490 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1491 chunk(GROUP, ch.where, [
1492 chunk(PLAIN, ch.where, 'itemize')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001493 i, length = i+2, length+2
1494 elif envname == 'enumerate':
1495 hist.enumeratenesting = hist.enumeratenesting-1
Fred Drake43c93501997-12-29 21:40:35 +00001496 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1497 chunk(GROUP, ch.where, [
1498 chunk(PLAIN, ch.where, 'enumerate')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001499 i, length = i+2, length+2
1500 elif envname == 'description':
Fred Drake43c93501997-12-29 21:40:35 +00001501 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1502 chunk(GROUP, ch.where, [
1503 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001504 i, length = i+2, length+2
1505 elif (envname == 'tableiii') or (envname == 'tableii'):
Fred Drake43c93501997-12-29 21:40:35 +00001506 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1507 chunk(GROUP, ch.where, [
1508 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001509 i, length = i+2, length + 2
1510 pp.insert(i, chunk(DENDLINE, ch.where, '\n'))
1511 i, length = i+1, length+1
1512
Fred Drakeef058031998-02-19 15:20:30 +00001513 elif envname in ('funcdesc', 'excdesc', 'datadesc', 'classdesc',
Fred Drakee8b46131998-02-17 05:54:46 +00001514 'funcdescni', 'datadescni'):
Fred Drake43c93501997-12-29 21:40:35 +00001515 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1516 chunk(GROUP, ch.where, [
1517 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001518 i, length = i+2, length+2
Fred Drakea4541af1997-12-29 17:19:22 +00001519
Fred Drake43c93501997-12-29 21:40:35 +00001520 elif envname == 'opcodedesc':
1521 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1522 chunk(GROUP, ch.where, [
1523 chunk(PLAIN, ch.where, "deffn")])]
1524 i, length = i+2, length+2
1525
1526 elif envname in ('seealso', 'sloppypar', 'flushleft'):
Fred Drakea4541af1997-12-29 17:19:22 +00001527 pass
1528
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001529 else:
Fred Drakea4541af1997-12-29 17:19:22 +00001530 print 'WARNING: ending env %s has no actions' % `envname`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001531
Guido van Rossum36f219d1996-09-11 21:30:40 +00001532 elif ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001533 # control name transformations
Guido van Rossum36f219d1996-09-11 21:30:40 +00001534 s_buf_data = s(buf, ch.data)
1535 if s_buf_data == 'optional':
1536 pp[i-1].chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001537 pp[i-1].data = '['
1538 if (i < length) and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001539 (pp[i].chtype == chunk_type[GROUP]):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001540 cp=pp[i].data
1541 pp[i:i+1]=cp + [
1542 chunk(PLAIN, ch.where, ']')]
1543 length = length+len(cp)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001544 elif s_buf_data in ignoredcommands:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001545 del pp[i-1]
1546 i, length = i-1, length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001547 elif s_buf_data == '@' and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001548 i != length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001549 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001550 s(buf, pp[i].data)[0] == '.':
1551 # \@. --> \. --> @.
1552 ch.data = '.'
1553 del pp[i]
1554 length = length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001555 elif s_buf_data == '\\':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001556 # \\ --> \* --> @*
1557 ch.data = '*'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001558 elif len(s_buf_data) == 1 and \
1559 s_buf_data in onlylatexspecial:
1560 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001561 # check if such a command is followed by
1562 # an empty group: e.g., `\%{}'. If so, remove
1563 # this empty group too
1564 if i < length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001565 pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001566 and len(pp[i].data) == 0:
1567 del pp[i]
1568 length = length-1
1569
Guido van Rossum36f219d1996-09-11 21:30:40 +00001570 elif hist.inargs and s_buf_data in inargsselves:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001571 # This is the special processing of the
1572 # arguments of the \begin{funcdesc}... or
1573 # \funcline... arguments
1574 # \, --> , \[ --> [, \] --> ]
Guido van Rossum36f219d1996-09-11 21:30:40 +00001575 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001576
Fred Drakee8b46131998-02-17 05:54:46 +00001577 elif s_buf_data == 'setindexsubitem':
1578 stuff = pp[i].data
1579 if len(stuff) != 1:
1580 raise error, "parameter to \\setindexsubitem{} too long"
1581 if pp[i].chtype != chunk_type[GROUP]:
1582 raise error, "bad chunk type following \\setindexsubitem" \
1583 "\nexpected GROUP, got " + str(ch.chtype)
1584 text = s(buf, stuff[0].data)
1585 if text[:1] != '(' or text[-1:] != ')':
1586 raise error, \
1587 'expected indexsubitem enclosed in parenteses'
1588 hist.indexsubitem = string.split(text[1:-1])
1589 del stuff, text
1590 del pp[i-1:i+1]
1591 i = i - 1
1592 length = length - 2
1593
1594 elif s_buf_data == 'newcommand':
1595 print "ignoring definition of \\" + s(buf, pp[i].data[0].data)
1596 del pp[i-1:i+2]
1597 i = i - 1
1598 length = length - 3
1599
1600 elif s_buf_data == 'mbox':
1601 stuff = pp[i].data
1602 pp[i-1:i+1] = stuff
1603 i = i - 1
1604 length = length + len(stuff) - 2
1605
1606 elif s_buf_data == 'version':
1607 ch.chtype = chunk_type[PLAIN]
1608 ch.data = release_version
1609
Guido van Rossum36f219d1996-09-11 21:30:40 +00001610 elif s_buf_data == 'item':
1611 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001612 length, newi = getoptarg(length, buf, pp, i)
1613 ingroupch = pp[i:newi]
1614 del pp[i:newi]
1615 length = length - (newi-i)
Fred Drake893e5e01996-10-25 22:13:10 +00001616 changeit(buf, ingroupch) # catch stuff inside the optional arg
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001617 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1618 i, length = i+1, length+1
1619
Guido van Rossum36f219d1996-09-11 21:30:40 +00001620 elif s_buf_data == 'ttindex':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001621 idxsi = hist.indexsubitem
1622
1623 cat_class = ''
1624 if len(idxsi) >= 2 and idxsi[1] in \
1625 ('method', 'function', 'protocol'):
1626 command = 'findex'
1627 elif len(idxsi) >= 2 and idxsi[1] in \
1628 ('exception', 'object'):
1629 command = 'vindex'
Fred Drake7edd8d31996-10-09 16:11:26 +00001630 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1631 command = 'cindex'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001632 else:
Fred Drake7edd8d31996-10-09 16:11:26 +00001633 print 'WARNING: can\'t categorize ' + `idxsi` \
1634 + ' for \'ttindex\' command'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001635 command = 'cindex'
1636
1637 if not cat_class:
1638 cat_class = '('+string.join(idxsi)+')'
1639
Guido van Rossum36f219d1996-09-11 21:30:40 +00001640 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001641 ch.data = command
1642
1643 length, newi = getnextarg(length, buf, pp, i)
1644 arg = pp[i:newi]
1645 del pp[i:newi]
1646 length = length - (newi-i)
1647
1648 cat_arg = [chunk(PLAIN, ch.where, cat_class)]
1649
1650 # determine what should be set in roman, and
1651 # what in tt-font
1652 if command in regindices:
1653
1654 arg = [chunk(CSNAME, ch.where, 't'),
Fred Drake9c7c6be1998-02-19 21:40:22 +00001655 chunk(GROUP, ch.where, arg)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001656 else:
1657 cat_arg = [chunk(CSNAME, ch.where, 'r'),
Fred Drake9c7c6be1998-02-19 21:40:22 +00001658 chunk(GROUP, ch.where, cat_arg)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001659
1660 ingroupch = arg + \
1661 [chunk(PLAIN, ch.where, ' ')] + \
1662 cat_arg
1663
1664 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1665 length, i = length+1, i+1
1666
Guido van Rossum36f219d1996-09-11 21:30:40 +00001667 elif s_buf_data == 'ldots':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001668 # \ldots --> \dots{} --> @dots{}
1669 ch.data = 'dots'
1670 if i == length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001671 or pp[i].chtype != chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001672 or pp[i].data != []:
1673 pp.insert(i, chunk(GROUP, ch.where, []))
1674 i, length = i+1, length+1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001675 elif s_buf_data in themselves:
Fred Drakee8b46131998-02-17 05:54:46 +00001676 # \UNIX --> &UNIX;
Guido van Rossum36f219d1996-09-11 21:30:40 +00001677 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001678 if i != length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001679 and pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001680 and pp[i].data == []:
1681 del pp[i]
1682 length = length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +00001683 elif s_buf_data in for_texi:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001684 pass
1685
Fred Drakee8b46131998-02-17 05:54:46 +00001686 elif s_buf_data == 'manpage':
1687 ch.data = 'emph'
1688 sect = s(buf, pp[i+1].data[0].data)
1689 pp[i+1].data = "(%s)" % sect
1690 pp[i+1].chtype = chunk_type[PLAIN]
1691
Guido van Rossum36f219d1996-09-11 21:30:40 +00001692 elif s_buf_data == 'e':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001693 # "\e" --> "\"
1694 ch.data = '\\'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001695 ch.chtype = chunk_type[PLAIN]
1696 elif s_buf_data in ('lineiii', 'lineii'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001697 # This is the most tricky one
1698 # \lineiii{a1}{a2}[{a3}] -->
1699 # @item @<cts. of itemargmacro>{a1}
1700 # a2 [ -- a3]
1701 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001702 if not hist.inenv:
1703 raise error, 'no environment for lineiii'
1704 if (hist.inenv[0] != 'tableiii') and \
1705 (hist.inenv[0] != 'tableii'):
1706 raise error, \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001707 'wrong command (%s) in wrong environment (%s)' \
1708 % (s_buf_data, `hist.inenv[0]`)
1709 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001710 ch.data = 'item'
1711 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001712 ingroupch = [chunk(CSNAME, 0, hist.itemargmacro),
1713 chunk(GROUP, 0, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001714 del pp[i:newi]
1715 length = length - (newi-i)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001716 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1717 grouppos = i
1718 i, length = i+1, length+1
1719 length, i = getnextarg(length, buf, pp, i)
1720 length, newi = getnextarg(length, buf, pp, i)
1721 if newi > i:
1722 # we have a 3rd arg
1723 pp.insert(i, chunk(PLAIN, ch.where, ' --- '))
1724 i = newi + 1
1725 length = length + 1
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001726 if length != len(pp):
1727 raise 'IN LINEIII IS THE ERR', `i`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001728
Guido van Rossum36f219d1996-09-11 21:30:40 +00001729 elif s_buf_data in ('chapter', 'section', 'subsection', 'subsubsection'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001730 #\xxxsection{A} ---->
1731 # @node A, , ,
1732 # @xxxsection A
1733 ## also: remove commas and quotes
Guido van Rossum36f219d1996-09-11 21:30:40 +00001734 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001735 length, newi = getnextarg(length, buf, pp, i)
Fred Drakee8b46131998-02-17 05:54:46 +00001736 afternodenamecmd = next_command_p(length, buf,
1737 pp, newi, 'nodename')
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001738 if afternodenamecmd < 0:
1739 cp1 = crcopy(pp[i:newi])
Guido van Rossum36f219d1996-09-11 21:30:40 +00001740 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001741 length, newi = length - (newi-i) + 1, i+1
1742 text = flattext(buf, cp1)
1743 text = invent_node_names(text)
1744 else:
Fred Drakee8b46131998-02-17 05:54:46 +00001745 length, endarg = getnextarg(length, buf,
1746 pp, afternodenamecmd)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001747 cp1 = crcopy(pp[afternodenamecmd:endarg])
1748 del pp[newi:endarg]
1749 length = length - (endarg-newi)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001750
Guido van Rossum36f219d1996-09-11 21:30:40 +00001751 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001752 length, newi = length - (newi-i) + 1, i + 1
1753 text = flattext(buf, cp1)
1754 if text[-1] == '.':
1755 text = text[:-1]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001756 if text in hist.nodenames:
1757 print 'WARNING: node name ' + `text` + ' already used'
1758 out.doublenodes.append(text)
1759 else:
1760 hist.nodenames.append(text)
1761 text = rm_commas_etc(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001762 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'node'),
1763 chunk(GROUP, ch.where, [
1764 chunk(PLAIN, ch.where, text+', , ,')
1765 ])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001766 i, length = newi+2, length+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001767
Guido van Rossum36f219d1996-09-11 21:30:40 +00001768 elif s_buf_data == 'funcline':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001769 # fold it to a very short environment
Guido van Rossum36f219d1996-09-11 21:30:40 +00001770 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1771 chunk(GROUP, ch.where, [
1772 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001773 i, length = i+2, length+2
1774 length, i = do_funcdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001775
Guido van Rossum36f219d1996-09-11 21:30:40 +00001776 elif s_buf_data == 'dataline':
1777 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1778 chunk(GROUP, ch.where, [
1779 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001780 i, length = i+2, length+2
1781 length, i = do_datadesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001782
Guido van Rossum36f219d1996-09-11 21:30:40 +00001783 elif s_buf_data == 'excline':
1784 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1785 chunk(GROUP, ch.where, [
1786 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001787 i, length = i+2, length+2
1788 length, i = do_excdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001789
Guido van Rossum36f219d1996-09-11 21:30:40 +00001790 elif s_buf_data == 'index':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001791 #\index{A} --->
1792 # @cindex A
Guido van Rossum36f219d1996-09-11 21:30:40 +00001793 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001794 ch.data = 'cindex'
1795 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001796
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001797 ingroupch = pp[i:newi]
1798 del pp[i:newi]
1799 length = length - (newi-i)
1800 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1801 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001802
Guido van Rossum36f219d1996-09-11 21:30:40 +00001803 elif s_buf_data == 'bifuncindex':
1804 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001805 ch.data = 'findex'
1806 length, newi = getnextarg(length, buf, pp, i)
1807 ingroupch = pp[i:newi]
1808 del pp[i:newi]
1809 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001810
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001811 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1812 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1813 ingroupch.append(chunk(GROUP, ch.where, [
1814 chunk(PLAIN, ch.where,
1815 '(built-in function)')]))
1816
1817 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1818 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001819
Guido van Rossum36f219d1996-09-11 21:30:40 +00001820 elif s_buf_data == 'obindex':
1821 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001822 ch.data = 'findex'
1823 length, newi = getnextarg(length, buf, pp, i)
1824 ingroupch = pp[i:newi]
1825 del pp[i:newi]
1826 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001827
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001828 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1829 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1830 ingroupch.append(chunk(GROUP, ch.where, [
1831 chunk(PLAIN, ch.where,
1832 '(object)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001833
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001834 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1835 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001836
Guido van Rossum36f219d1996-09-11 21:30:40 +00001837 elif s_buf_data == 'opindex':
1838 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001839 ch.data = 'findex'
1840 length, newi = getnextarg(length, buf, pp, i)
1841 ingroupch = pp[i:newi]
1842 del pp[i:newi]
1843 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001844
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001845 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1846 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1847 ingroupch.append(chunk(GROUP, ch.where, [
1848 chunk(PLAIN, ch.where,
1849 '(operator)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001850
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001851 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1852 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001853
Fred Drakea4541af1997-12-29 17:19:22 +00001854 elif s_buf_data in ('bimodindex', 'refbimodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001855 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001856 ch.data = 'pindex'
1857 length, newi = getnextarg(length, buf, pp, i)
1858 ingroupch = pp[i:newi]
1859 del pp[i:newi]
1860 length = length - (newi-i)
1861
1862 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1863 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1864 ingroupch.append(chunk(GROUP, ch.where, [
1865 chunk(PLAIN, ch.where,
1866 '(built-in)')]))
1867
1868 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1869 length, i = length+1, i+1
1870
Fred Drakea4541af1997-12-29 17:19:22 +00001871 elif s_buf_data == 'refmodindex':
1872 ch.chtype = chunk_type[CSLINE]
1873 ch.data = 'pindex'
1874 length, newi = getnextarg(length, buf, pp, i)
1875 ingroupch = pp[i:newi]
1876 del pp[i:newi]
1877 length = length - (newi-i)
1878
Fred Drakea4541af1997-12-29 17:19:22 +00001879 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1880 length, i = length+1, i+1
1881
Fred Drakea4541af1997-12-29 17:19:22 +00001882 elif s_buf_data in ('stmodindex', 'refstmodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001883 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001884 # use the program index as module index
1885 ch.data = 'pindex'
1886 length, newi = getnextarg(length, buf, pp, i)
1887 ingroupch = pp[i:newi]
1888 del pp[i:newi]
1889 length = length - (newi-i)
1890
1891 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1892 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1893 ingroupch.append(chunk(GROUP, ch.where, [
1894 chunk(PLAIN, ch.where,
1895 '(standard)')]))
1896
1897 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1898 length, i = length+1, i+1
1899
Fred Drakea4541af1997-12-29 17:19:22 +00001900 elif s_buf_data in ('stmodindex', 'refstmodindex'):
1901 ch.chtype = chunk_type[CSLINE]
1902 # use the program index as module index
1903 ch.data = 'pindex'
1904 length, newi = getnextarg(length, buf, pp, i)
1905 ingroupch = pp[i:newi]
1906 del pp[i:newi]
1907 length = length - (newi-i)
1908
1909 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1910 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1911 ingroupch.append(chunk(GROUP, ch.where, [
1912 chunk(PLAIN, ch.where,
1913 '(standard)')]))
1914
1915 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1916 length, i = length+1, i+1
1917
1918 elif s_buf_data in ('stindex', 'kwindex'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001919 # XXX must actually go to newindex st
Fred Drakea4541af1997-12-29 17:19:22 +00001920 what = (s_buf_data[:2] == "st") and "statement" or "keyword"
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001921 wh = ch.where
Guido van Rossum36f219d1996-09-11 21:30:40 +00001922 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001923 ch.data = 'cindex'
1924 length, newi = getnextarg(length, buf, pp, i)
1925 ingroupch = [chunk(CSNAME, wh, 'code'),
Fred Drakee8b46131998-02-17 05:54:46 +00001926 chunk(GROUP, wh, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001927
1928 del pp[i:newi]
1929 length = length - (newi-i)
1930
1931 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001932 t.append(chunk(PLAIN, wh, ' ' + what))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001933
1934 pp.insert(i, chunk(GROUP, wh, t))
1935 i, length = i+1, length+1
1936
1937 pp.insert(i, chunk(CSLINE, wh, 'cindex'))
1938 i, length = i+1, length+1
1939
1940 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001941 t.insert(0, chunk(PLAIN, wh, what + ', '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001942
1943 pp.insert(i, chunk(GROUP, wh, t))
1944 i, length = i+1, length+1
1945
Guido van Rossum36f219d1996-09-11 21:30:40 +00001946 elif s_buf_data == 'indexii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001947 #\indexii{A}{B} --->
1948 # @cindex A B
1949 # @cindex B, A
1950 length, newi = getnextarg(length, buf, pp, i)
1951 cp11 = pp[i:newi]
1952 cp21 = 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 del pp[i:newi]
1959 length = length - (newi-i)
1960
Guido van Rossum36f219d1996-09-11 21:30:40 +00001961 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001962 ch.data = 'cindex'
1963 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
1964 chunk(PLAIN, ch.where, ' ')] + cp12))
1965 i, length = i+1, length+1
1966 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
1967 chunk(GROUP, ch.where, cp22 + [
1968 chunk(PLAIN, ch.where, ', ')]+ cp21)]
1969 i, length = i+2, length+2
1970
Guido van Rossum36f219d1996-09-11 21:30:40 +00001971 elif s_buf_data == 'indexiii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001972 length, newi = getnextarg(length, buf, pp, i)
1973 cp11 = pp[i:newi]
1974 cp21 = crcopy(pp[i:newi])
1975 cp31 = crcopy(pp[i:newi])
1976 del pp[i:newi]
1977 length = length - (newi-i)
1978 length, newi = getnextarg(length, buf, pp, i)
1979 cp12 = pp[i:newi]
1980 cp22 = crcopy(pp[i:newi])
1981 cp32 = crcopy(pp[i:newi])
1982 del pp[i:newi]
1983 length = length - (newi-i)
1984 length, newi = getnextarg(length, buf, pp, i)
1985 cp13 = pp[i:newi]
1986 cp23 = crcopy(pp[i:newi])
1987 cp33 = crcopy(pp[i:newi])
1988 del pp[i:newi]
1989 length = length - (newi-i)
1990
Guido van Rossum36f219d1996-09-11 21:30:40 +00001991 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001992 ch.data = 'cindex'
1993 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
1994 chunk(PLAIN, ch.where, ' ')] + cp12
1995 + [chunk(PLAIN, ch.where, ' ')]
1996 + cp13))
1997 i, length = i+1, length+1
1998 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
1999 chunk(GROUP, ch.where, cp22 + [
2000 chunk(PLAIN, ch.where, ' ')]+ cp23
2001 + [chunk(PLAIN, ch.where, ', ')] +
2002 cp21)]
2003 i, length = i+2, length+2
2004 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
2005 chunk(GROUP, ch.where, cp33 + [
2006 chunk(PLAIN, ch.where, ', ')]+ cp31
2007 + [chunk(PLAIN, ch.where, ' ')] +
2008 cp32)]
2009 i, length = i+2, length+2
2010
Guido van Rossum36f219d1996-09-11 21:30:40 +00002011 elif s_buf_data == 'indexiv':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002012 length, newi = getnextarg(length, buf, pp, i)
2013 cp11 = pp[i:newi]
2014 cp21 = crcopy(pp[i:newi])
2015 cp31 = crcopy(pp[i:newi])
2016 cp41 = crcopy(pp[i:newi])
2017 del pp[i:newi]
2018 length = length - (newi-i)
2019 length, newi = getnextarg(length, buf, pp, i)
2020 cp12 = pp[i:newi]
2021 cp22 = crcopy(pp[i:newi])
2022 cp32 = crcopy(pp[i:newi])
2023 cp42 = crcopy(pp[i:newi])
2024 del pp[i:newi]
2025 length = length - (newi-i)
2026 length, newi = getnextarg(length, buf, pp, i)
2027 cp13 = pp[i:newi]
2028 cp23 = crcopy(pp[i:newi])
2029 cp33 = crcopy(pp[i:newi])
2030 cp43 = crcopy(pp[i:newi])
2031 del pp[i:newi]
2032 length = length - (newi-i)
2033 length, newi = getnextarg(length, buf, pp, i)
2034 cp14 = pp[i:newi]
2035 cp24 = crcopy(pp[i:newi])
2036 cp34 = crcopy(pp[i:newi])
2037 cp44 = crcopy(pp[i:newi])
2038 del pp[i:newi]
2039 length = length - (newi-i)
2040
Guido van Rossum36f219d1996-09-11 21:30:40 +00002041 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002042 ch.data = 'cindex'
2043 ingroupch = cp11 + \
2044 spacech + cp12 + \
2045 spacech + cp13 + \
2046 spacech + cp14
2047 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
2048 i, length = i+1, length+1
2049 ingroupch = cp22 + \
2050 spacech + cp23 + \
2051 spacech + cp24 + \
2052 commach + cp21
2053 pp[i:i] = cindexch + [
2054 chunk(GROUP, ch.where, ingroupch)]
2055 i, length = i+2, length+2
2056 ingroupch = cp33 + \
2057 spacech + cp34 + \
2058 commach + cp31 + \
2059 spacech + cp32
2060 pp[i:i] = cindexch + [
2061 chunk(GROUP, ch.where, ingroupch)]
2062 i, length = i+2, length+2
2063 ingroupch = cp44 + \
2064 commach + cp41 + \
2065 spacech + cp42 + \
2066 spacech + cp43
2067 pp[i:i] = cindexch + [
2068 chunk(GROUP, ch.where, ingroupch)]
2069 i, length = i+2, length+2
2070
Fred Drakea4541af1997-12-29 17:19:22 +00002071 elif s_buf_data == 'seemodule':
2072 ch.data = "code"
Fred Drakee8b46131998-02-17 05:54:46 +00002073 # this is needed for just one of the input files... -sigh-
2074 while pp[i+1].chtype == chunk_type[COMMENT]:
2075 i = i + 1
Fred Drakea4541af1997-12-29 17:19:22 +00002076 data = pp[i+1].data
Fred Drakee8b46131998-02-17 05:54:46 +00002077 oparen = chunk(PLAIN, ch.where, " (")
2078 data.insert(0, oparen)
Fred Drakea4541af1997-12-29 17:19:22 +00002079 data.append(chunk(PLAIN, ch.where, ")"))
2080 pp[i+1:i+2] = data
2081 length = length + len(data) - 1
2082
2083 elif s_buf_data == 'seetext':
2084 data = pp[i].data
2085 data.insert(0, chunk(ENDLINE, ch.where, "\n"))
2086 pp[i-1:i+1] = data
2087 i = i - 1
2088 length = length + len(data) - 2
2089
Fred Drake43c93501997-12-29 21:40:35 +00002090 elif s_buf_data == "quad":
2091 ch.chtype = PLAIN
2092 ch.data = " "
2093
Fred Drakee8b46131998-02-17 05:54:46 +00002094 elif s_buf_data in ('noindent', 'indexsubitem', 'footnote'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00002095 pass
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002096
Fred Drake9c7c6be1998-02-19 21:40:22 +00002097 elif convertible_csname(s_buf_data):
2098 ch.data = conversion(s_buf_data)
Fred Drakee8b46131998-02-17 05:54:46 +00002099
Fred Drakea4541af1997-12-29 17:19:22 +00002100 elif s_buf_data == 'label':
Fred Drake43c93501997-12-29 21:40:35 +00002101 name = s(buf, pp[i].data[0].data)
Fred Drakea4541af1997-12-29 17:19:22 +00002102 del pp[i-1:i+1]
2103 length = length - 2
2104 i = i - 1
Fred Drake43c93501997-12-29 21:40:35 +00002105 label_nodes[name] = hist.nodenames[-1]
2106
Fred Drakee8b46131998-02-17 05:54:46 +00002107 elif s_buf_data == 'rfc':
2108 ch.chtype = chunk_type[PLAIN]
2109 ch.data = "RFC " + s(buf, pp[i].data[0].data)
2110 del pp[i]
2111 length = length - 1
2112
2113 elif s_buf_data == 'Large':
2114 del pp[i-1]
2115 i = i - 1
2116 length = length - 1
2117
Fred Drake43c93501997-12-29 21:40:35 +00002118 elif s_buf_data == 'ref':
2119 name = s(buf, pp[i].data[0].data)
2120 if label_nodes.has_key(name):
2121 pp[i].data[0].data = label_nodes[name]
2122 else:
2123 pp[i-1:i+1] = [
2124 chunk(PLAIN, ch.where,
2125 "(unknown node reference: %s)" % name)]
2126 length = length - 1
2127 print "WARNING: unknown node label", `name`
Fred Drakea4541af1997-12-29 17:19:22 +00002128
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002129 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002130 print "don't know what to do with keyword " + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002131
2132
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002133re_atsign = regex.compile('[@{}]')
2134re_newline = regex.compile('\n')
2135
2136def dumpit(buf, wm, pp):
2137
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002138 global out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002139
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002140 i, length = 0, len(pp)
2141
2142 addspace = 0
2143
2144 while 1:
2145 if len(pp) != length:
2146 raise 'FATAL', 'inconsistent length'
2147 if i == length:
2148 break
2149 ch = pp[i]
2150 i = i + 1
2151
Guido van Rossum36f219d1996-09-11 21:30:40 +00002152 dospace = addspace
2153 addspace = 0
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002154
Guido van Rossum36f219d1996-09-11 21:30:40 +00002155 if ch.chtype == chunk_type[CSNAME]:
2156 s_buf_data = s(buf, ch.data)
Fred Drake4b3f0311996-12-13 22:04:31 +00002157 if s_buf_data == 'e':
2158 wm('\\')
2159 continue
2160 if s_buf_data == '$':
2161 wm('$')
2162 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +00002163 wm('@' + s_buf_data)
2164 if s_buf_data == 'node' and \
2165 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002166 s(buf, pp[i].data) in out.doublenodes:
2167 ##XXX doesnt work yet??
2168 wm(' ZZZ-' + zfill(`i`, 4))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002169 if s_buf_data[0] in string.letters:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002170 addspace = 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002171 elif ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002172 if dospace and s(buf, ch.data) not in (' ', '\t'):
2173 wm(' ')
2174 text = s(buf, ch.data)
2175 while 1:
2176 pos = re_atsign.search(text)
2177 if pos < 0:
2178 break
2179 wm(text[:pos] + '@' + text[pos])
2180 text = text[pos+1:]
2181 wm(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00002182 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002183 wm('{')
2184 dumpit(buf, wm, ch.data)
2185 wm('}')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002186 elif ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002187 wm('\n\n')
2188 while i != length and pp[i].chtype in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002189 (chunk_type[DENDLINE], chunk_type[ENDLINE]):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002190 i = i + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002191 elif ch.chtype == chunk_type[OTHER]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002192 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002193 elif ch.chtype == chunk_type[ACTIVE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002194 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002195 elif ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002196 wm('\n')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002197 elif ch.chtype == chunk_type[CSLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002198 if i >= 2 and pp[i-2].chtype not in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002199 (chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2200 and (pp[i-2].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002201 or s(buf, pp[i-2].data)[-1] != '\n'):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002202
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002203 wm('\n')
2204 wm('@' + s(buf, ch.data))
2205 if i == length:
2206 raise error, 'CSLINE expected another chunk'
Guido van Rossum36f219d1996-09-11 21:30:40 +00002207 if pp[i].chtype != chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002208 raise error, 'CSLINE expected GROUP'
2209 if type(pp[i].data) != ListType:
2210 raise error, 'GROUP chould contain []-data'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002211
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002212 wobj = Wobj()
2213 dumpit(buf, wobj.write, pp[i].data)
2214 i = i + 1
2215 text = wobj.data
2216 del wobj
2217 if text:
2218 wm(' ')
2219 while 1:
2220 pos = re_newline.search(text)
2221 if pos < 0:
2222 break
2223 print 'WARNING: found newline in csline arg'
2224 wm(text[:pos] + ' ')
2225 text = text[pos+1:]
2226 wm(text)
2227 if i >= length or \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002228 pp[i].chtype not in (chunk_type[CSLINE],
2229 chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2230 and (pp[i].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002231 or s(buf, pp[i].data)[0] != '\n'):
2232 wm('\n')
Guido van Rossum49604d31996-09-10 22:19:51 +00002233
Guido van Rossum36f219d1996-09-11 21:30:40 +00002234 elif ch.chtype == chunk_type[COMMENT]:
2235## print 'COMMENT: previous chunk =', pp[i-2]
2236## if pp[i-2].chtype == chunk_type[PLAIN]:
2237## print 'PLAINTEXT =', `s(buf, pp[i-2].data)`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002238 if s(buf, ch.data) and \
2239 regex.match('^[ \t]*$', s(buf, ch.data)) < 0:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002240 if i >= 2 \
2241 and pp[i-2].chtype not in (chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2242 and not (pp[i-2].chtype == chunk_type[PLAIN]
2243 and regex.match('\\(.\\|\n\\)*[ \t]*\n$', s(buf, pp[i-2].data)) >= 0):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002244 wm('\n')
2245 wm('@c ' + s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002246 elif ch.chtype == chunk_type[IGNORE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002247 pass
2248 else:
2249 try:
2250 str = `s(buf, ch.data)`
2251 except TypeError:
2252 str = `ch.data`
2253 if len(str) > 400:
2254 str = str[:400] + '...'
2255 print 'warning:', ch.chtype, 'not handled, data ' + str
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002256
2257
2258
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002259def main():
Fred Drakee8b46131998-02-17 05:54:46 +00002260 global release_version
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002261 outfile = None
2262 headerfile = 'texipre.dat'
2263 trailerfile = 'texipost.dat'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002264
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002265 try:
Fred Drakee8b46131998-02-17 05:54:46 +00002266 opts, args = getopt.getopt(sys.argv[1:], 'o:h:t:v:')
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002267 except getopt.error:
2268 args = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002269
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002270 if not args:
2271 print 'usage: partparse [-o outfile] [-h headerfile]',
2272 print '[-t trailerfile] file ...'
2273 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002274
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002275 for opt, arg in opts:
2276 if opt == '-o': outfile = arg
2277 if opt == '-h': headerfile = arg
2278 if opt == '-t': trailerfile = arg
Fred Drakee8b46131998-02-17 05:54:46 +00002279 if opt == '-v': release_version = arg
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002280
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002281 if not outfile:
2282 root, ext = os.path.splitext(args[0])
2283 outfile = root + '.texi'
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002284
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002285 if outfile in args:
2286 print 'will not overwrite input file', outfile
2287 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002288
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002289 outf = open(outfile, 'w')
2290 outf.write(open(headerfile, 'r').read())
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002291
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002292 for file in args:
2293 if len(args) > 1: print '='*20, file, '='*20
2294 buf = open(file, 'r').read()
2295 w, pp = parseit(buf)
2296 startchange()
2297 changeit(buf, pp)
2298 dumpit(buf, outf.write, pp)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002299
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002300 outf.write(open(trailerfile, 'r').read())
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002301
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002302 outf.close()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002303
Guido van Rossum49604d31996-09-10 22:19:51 +00002304if __name__ == "__main__":
2305 main()