blob: d3b850f4f09065338ab7b5779599f5c0d84bd3bb [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 Drake74a11e51998-02-26 05:52:37 +0000839ignoredcommands = ('hline', 'small', '/', 'tableofcontents', 'Large')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000840# map commands like these to themselves as plaintext
Fred Drake74a11e51998-02-26 05:52:37 +0000841wordsselves = ('UNIX', 'ABC', 'C', 'ASCII', 'EOF', 'LaTeX', 'POSIX', 'TeX',
842 'SliTeX')
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000843# \{ --> {, \} --> }, etc
Guido van Rossum36f219d1996-09-11 21:30:40 +0000844themselves = ('{', '}', ',', '.', '@', ' ', '\n') + wordsselves
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000845# these ones also themselves (see argargs macro in myformat.sty)
846inargsselves = (',', '[', ']', '(', ')')
847# this is how *I* would show the difference between emph and strong
848# code 1 means: fold to uppercase
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000849markcmds = {'code': ('', ''), 'var': 1, 'emph': ('_', '_'),
Fred Drakee8b46131998-02-17 05:54:46 +0000850 'strong': ('*', '*')}
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000851
852# recognise patter {\FONTCHANGE-CMD TEXT} to \MAPPED-FC-CMD{TEXT}
853fontchanges = {'rm': 'r', 'it': 'i', 'em': 'emph', 'bf': 'b', 'tt': 't'}
854
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000855
856# try to remove macros and return flat text
857def flattext(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000858 pp = crcopy(pp)
859 ##print '---> FLATTEXT ' + `pp`
860 wobj = Wobj()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000861
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000862 i, length = 0, len(pp)
863 while 1:
864 if len(pp) != length:
865 raise 'FATAL', 'inconsistent length'
866 if i >= length:
867 break
868 ch = pp[i]
869 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000870 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000871 pass
Guido van Rossum36f219d1996-09-11 21:30:40 +0000872 elif ch.chtype == chunk_type[CSNAME]:
873 s_buf_data = s(buf, ch.data)
Fred Drake74a11e51998-02-26 05:52:37 +0000874 if convertible_csname(s_buf_data):
875 ch.chtype, ch.data, nix = conversion(s_buf_data)
876 if hist.inargs and s_buf_data in inargsselves:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000877 ch.chtype = chunk_type[PLAIN]
Guido van Rossum36f219d1996-09-11 21:30:40 +0000878 elif len(s_buf_data) == 1 \
879 and s_buf_data in onlylatexspecial:
880 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000881 # if it is followed by an empty group,
882 # remove that group, it was needed for
883 # a true space
884 if i < length \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000885 and pp[i].chtype==chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000886 and len(pp[i].data) == 0:
887 del pp[i]
888 length = length-1
889
Guido van Rossum36f219d1996-09-11 21:30:40 +0000890 elif s_buf_data in markcmds.keys():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000891 length, newi = getnextarg(length, buf, pp, i)
892 str = flattext(buf, pp[i:newi])
893 del pp[i:newi]
894 length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000895 ch.chtype = chunk_type[PLAIN]
896 markcmd = s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000897 x = markcmds[markcmd]
898 if type(x) == TupleType:
899 pre, after = x
900 str = pre+str+after
901 elif x == 1:
902 str = string.upper(str)
903 else:
904 raise 'FATAL', 'corrupt markcmds'
905 ch.data = str
906 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +0000907 if s_buf_data not in ignoredcommands:
908 print 'WARNING: deleting command ' + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000909 print 'PP' + `pp[i-1]`
910 del pp[i-1]
911 i, length = i-1, length-1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000912 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000913 length, newi = getnextarg(length, buf, pp, i-1)
914 i = i-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000915## str = flattext(buf, crcopy(pp[i-1:newi]))
916## del pp[i:newi]
917## length = length - (newi - i)
Guido van Rossum36f219d1996-09-11 21:30:40 +0000918## ch.chtype = chunk_type[PLAIN]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000919## ch.data = str
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000920 else:
921 pass
922
923 dumpit(buf, wobj.write, pp)
924 ##print 'FLATTEXT: RETURNING ' + `wobj.data`
925 return wobj.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000926
927# try to generate node names (a bit shorter than the chapter title)
928# note that the \nodename command (see elsewhere) overules these efforts
929def invent_node_names(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000930 words = string.split(text)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000931
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000932 ##print 'WORDS ' + `words`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000933
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000934 if len(words) == 2 \
Guido van Rossum36f219d1996-09-11 21:30:40 +0000935 and string.lower(words[0]) == 'built-in' \
936 and string.lower(words[1]) not in ('modules', 'functions'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000937 return words[1]
938 if len(words) == 3 and string.lower(words[1]) == 'module':
939 return words[2]
940 if len(words) == 3 and string.lower(words[1]) == 'object':
941 return string.join(words[0:2])
Guido van Rossum36f219d1996-09-11 21:30:40 +0000942 if len(words) > 4 \
943 and (string.lower(string.join(words[-4:])) \
944 == 'methods and data attributes'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000945 return string.join(words[:2])
946 return text
947
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000948re_commas_etc = regex.compile('[,`\'@{}]')
949
950re_whitespace = regex.compile('[ \t]*')
951
952
953##nodenamecmd = next_command_p(length, buf, pp, newi, 'nodename')
954
955# look if the next non-white stuff is also a command, resulting in skipping
956# double endlines (DENDLINE) too, and thus omitting \par's
957# Sometimes this is too much, maybe consider DENDLINE's as stop
958def next_command_p(length, buf, pp, i, cmdname):
959
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000960 while 1:
961 if i >= len(pp):
962 break
963 ch = pp[i]
964 i = i+1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000965 if ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000966 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000967 if ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000968 continue
Guido van Rossum36f219d1996-09-11 21:30:40 +0000969 if ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000970 if re_whitespace.search(s(buf, ch.data)) == 0 and \
971 re_whitespace.match(s(buf, ch.data)) == len(s(buf, ch.data)):
972 continue
973 return -1
Guido van Rossum36f219d1996-09-11 21:30:40 +0000974 if ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000975 if s(buf, ch.data) == cmdname:
976 return i # _after_ the command
977 return -1
978 return -1
979
980
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000981# things that are special to LaTeX, but not to texi..
982onlylatexspecial = '_~^$#&%'
983
Guido van Rossum23301a91993-05-24 14:19:37 +0000984class Struct: pass
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000985
986hist = Struct()
987out = Struct()
988
989def startchange():
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000990 global hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000991
Fred Drake74a11e51998-02-26 05:52:37 +0000992 hist.chaptertype = "chapter"
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000993 hist.inenv = []
994 hist.nodenames = []
995 hist.cindex = []
996 hist.inargs = 0
997 hist.enumeratenesting, hist.itemizenesting = 0, 0
Guido van Rossum95cd2ef1992-12-08 14:37:55 +0000998
Guido van Rossum5f18d6c1996-09-10 22:34:20 +0000999 out.doublenodes = []
1000 out.doublecindeces = []
1001
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001002
1003spacech = [chunk(PLAIN, 0, ' ')]
1004commach = [chunk(PLAIN, 0, ', ')]
1005cindexch = [chunk(CSLINE, 0, 'cindex')]
1006
1007# the standard variation in symbols for itemize
1008itemizesymbols = ['bullet', 'minus', 'dots']
1009
1010# same for enumerate
1011enumeratesymbols = ['1', 'A', 'a']
1012
Fred Drake74a11e51998-02-26 05:52:37 +00001013# Map of things that convert one-to-one. Each entry is a 3-tuple:
1014#
1015# new_chtype, new_data, nix_trailing_empty_group
1016#
Fred Drake9c7c6be1998-02-19 21:40:22 +00001017d = {}
Fred Drake74a11e51998-02-26 05:52:37 +00001018# add stuff that converts from one name to another:
Fred Drake9c7c6be1998-02-19 21:40:22 +00001019for name in ('url', 'module', 'function', 'cfunction',
1020 'keyword', 'method', 'exception', 'constant',
1021 'email', 'class', 'member', 'cdata', 'ctype',
Fred Drake74a11e51998-02-26 05:52:37 +00001022 'member', 'sectcode', 'verb'):
1023 d[name] = chunk_type[CSNAME], 'code', 0
1024for name in ('emph', 'var', 'strong', 'code', 'kbd', 'key',
1025 'dfn', 'samp', 'file', 'r', 'i', 't'):
1026 d[name] = chunk_type[CSNAME], name, 0
1027d['program'] = chunk_type[CSNAME], 'strong', 0
1028d['\\'] = chunk_type[CSNAME], '*', 0
1029# add stuff that converts to text:
1030for name in themselves:
1031 d[name] = chunk_type[PLAIN], name, 0
1032for name in wordsselves:
1033 d[name] = chunk_type[PLAIN], name, 1
1034for name in ',[]()':
1035 d[name] = chunk_type[PLAIN], name, 0
1036# a lot of these are LaTeX2e additions
1037for name, value in [('quotedblbase', ',,'), ('quotesinglbase', ','),
1038 ('textquotedbl', '"'), ('LaTeXe', 'LaTeX2e'),
1039 ('e', '\\'), ('textquotedblleft', "``"),
1040 ('textquotedblright', "''"), ('textquoteleft', "`"),
1041 ('textquoteright', "'"), ('textbackslash', '\\'),
1042 ('textbar', '|'), ('textless', '<'),
1043 ('textgreater', '>'), ('textasciicircum', '^'),
1044 ('Cpp', 'C++'), ('copyright', '')]:
1045 d[name] = chunk_type[PLAIN], value, 1
Fred Drake9c7c6be1998-02-19 21:40:22 +00001046convertible_csname = d.has_key
1047conversion = d.get
Fred Drake74a11e51998-02-26 05:52:37 +00001048del d, name, value
Fred Drake9c7c6be1998-02-19 21:40:22 +00001049
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001050##
1051## \begin{ {func,data,exc}desc }{name}...
1052## the resulting texi-code is dependent on the contents of indexsubitem
1053##
1054
1055# indexsubitem: `['XXX', 'function']
1056# funcdesc:
1057# deffn {`idxsi`} NAME (FUNCARGS)
1058
1059# indexsubitem: `['XXX', 'method']`
1060# funcdesc:
1061# defmethod {`idxsi[0]`} NAME (FUNCARGS)
1062
1063# indexsubitem: `['in', 'module', 'MODNAME']'
1064# datadesc:
1065# defcv data {`idxsi[1:]`} NAME
1066# excdesc:
1067# defcv exception {`idxsi[1:]`} NAME
1068# funcdesc:
1069# deffn {function of `idxsi[1:]`} NAME (FUNCARGS)
1070
1071# indexsubitem: `['OBJECT', 'attribute']'
1072# datadesc
1073# defcv attribute {`OBJECT`} NAME
1074
1075
1076## this routine will be called on \begin{funcdesc}{NAME}{ARGS}
1077## or \funcline{NAME}{ARGS}
1078##
Fred Drakee8b46131998-02-17 05:54:46 +00001079def do_funcdesc(length, buf, pp, i, index=1):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001080 startpoint = i-1
1081 ch = pp[startpoint]
1082 wh = ch.where
1083 length, newi = getnextarg(length, buf, pp, i)
1084 funcname = chunk(GROUP, wh, pp[i:newi])
1085 del pp[i:newi]
1086 length = length - (newi-i)
1087 save = hist.inargs
1088 hist.inargs = 1
1089 length, newi = getnextarg(length, buf, pp, i)
1090 hist.inargs = save
1091 del save
1092 the_args = [chunk(PLAIN, wh, '()'[0])] + pp[i:newi] + \
Fred Drake7edd8d31996-10-09 16:11:26 +00001093 [chunk(PLAIN, wh, '()'[1])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001094 del pp[i:newi]
1095 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001096
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001097 idxsi = hist.indexsubitem # words
1098 command = ''
1099 cat_class = ''
Fred Drakeacc87541996-10-14 16:20:42 +00001100 if idxsi and idxsi[-1] in ('method', 'protocol', 'attribute'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001101 command = 'defmethod'
1102 cat_class = string.join(idxsi[:-1])
1103 elif len(idxsi) == 2 and idxsi[1] == 'function':
1104 command = 'deffn'
1105 cat_class = string.join(idxsi)
1106 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1107 command = 'deffn'
1108 cat_class = 'function of ' + string.join(idxsi[1:])
Fred Drakea4541af1997-12-29 17:19:22 +00001109 elif len(idxsi) > 3 and idxsi[:2] == ['in', 'modules']:
1110 command = 'deffn'
1111 cat_class = 'function of ' + string.join(idxsi[1:])
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001112
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001113 if not command:
1114 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001115
Guido van Rossum36f219d1996-09-11 21:30:40 +00001116 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001117 ch.data = command
1118
1119 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1120 cslinearg.append(chunk(PLAIN, wh, ' '))
1121 cslinearg.append(funcname)
1122 cslinearg.append(chunk(PLAIN, wh, ' '))
1123 l = len(cslinearg)
1124 cslinearg[l:l] = the_args
1125
1126 pp.insert(i, chunk(GROUP, wh, cslinearg))
1127 i, length = i+1, length+1
1128 hist.command = command
1129 return length, i
1130
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001131
1132## this routine will be called on \begin{excdesc}{NAME}
1133## or \excline{NAME}
1134##
1135def do_excdesc(length, buf, pp, i):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001136 startpoint = i-1
1137 ch = pp[startpoint]
1138 wh = ch.where
1139 length, newi = getnextarg(length, buf, pp, i)
1140 excname = chunk(GROUP, wh, pp[i:newi])
1141 del pp[i:newi]
1142 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001143
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001144 idxsi = hist.indexsubitem # words
1145 command = ''
1146 cat_class = ''
1147 class_class = ''
1148 if len(idxsi) == 2 and idxsi[1] == 'exception':
1149 command = 'defvr'
1150 cat_class = string.join(idxsi)
1151 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1152 command = 'defcv'
1153 cat_class = 'exception'
1154 class_class = string.join(idxsi[1:])
1155 elif len(idxsi) == 4 and idxsi[:3] == ['exception', 'in', 'module']:
1156 command = 'defcv'
1157 cat_class = 'exception'
1158 class_class = string.join(idxsi[2:])
Fred Drakea4541af1997-12-29 17:19:22 +00001159 elif idxsi == ['built-in', 'exception', 'base', 'class']:
Fred Drakee8b46131998-02-17 05:54:46 +00001160 command = 'defvr'
1161 cat_class = 'exception base class'
Fred Drakea4541af1997-12-29 17:19:22 +00001162 else:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001163 raise error, 'don\'t know what to do with indexsubitem ' + `idxsi`
1164
Guido van Rossum36f219d1996-09-11 21:30:40 +00001165 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001166 ch.data = command
1167
1168 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1169 cslinearg.append(chunk(PLAIN, wh, ' '))
1170 if class_class:
1171 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001172 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001173 cslinearg.append(excname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001174
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001175 pp.insert(i, chunk(GROUP, wh, cslinearg))
1176 i, length = i+1, length+1
1177 hist.command = command
1178 return length, i
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001179
1180## same for datadesc or dataline...
Fred Drakee8b46131998-02-17 05:54:46 +00001181def do_datadesc(length, buf, pp, i, index=1):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001182 startpoint = i-1
1183 ch = pp[startpoint]
1184 wh = ch.where
1185 length, newi = getnextarg(length, buf, pp, i)
1186 dataname = chunk(GROUP, wh, pp[i:newi])
1187 del pp[i:newi]
1188 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001189
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001190 idxsi = hist.indexsubitem # words
Fred Drakee8b46131998-02-17 05:54:46 +00001191 command = 'defcv'
1192 cat_class = 'data'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001193 class_class = ''
1194 if idxsi[-1] in ('attribute', 'option'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001195 cat_class = idxsi[-1]
1196 class_class = string.join(idxsi[:-1])
1197 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001198 class_class = string.join(idxsi[1:])
1199 elif len(idxsi) == 4 and idxsi[:3] == ['data', 'in', 'module']:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001200 class_class = string.join(idxsi[2:])
Fred Drake11b6d241996-10-10 20:09:56 +00001201 else:
Fred Drake11b6d241996-10-10 20:09:56 +00001202 class_class = string.join(idxsi)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001203
Guido van Rossum36f219d1996-09-11 21:30:40 +00001204 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001205 ch.data = command
1206
1207 cslinearg = [chunk(GROUP, wh, [chunk(PLAIN, wh, cat_class)])]
1208 cslinearg.append(chunk(PLAIN, wh, ' '))
1209 if class_class:
1210 cslinearg.append(chunk(GROUP, wh, [chunk(PLAIN, wh, class_class)]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001211 cslinearg.append(chunk(PLAIN, wh, ' '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001212 cslinearg.append(dataname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001213
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001214 pp.insert(i, chunk(GROUP, wh, cslinearg))
1215 i, length = i+1, length+1
1216 hist.command = command
1217 return length, i
1218
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001219
Fred Drakea4541af1997-12-29 17:19:22 +00001220def do_opcodedesc(length, buf, pp, i):
1221 startpoint = i-1
1222 ch = pp[startpoint]
1223 wh = ch.where
1224 length, newi = getnextarg(length, buf, pp, i)
1225 dataname = chunk(GROUP, wh, pp[i:newi])
1226 del pp[i:newi]
1227 length = length - (newi-i)
1228
Fred Drake43c93501997-12-29 21:40:35 +00001229 ch.chtype = CSLINE
1230 ch.data = "deffn"
Fred Drakea4541af1997-12-29 17:19:22 +00001231
Fred Drakee8b46131998-02-17 05:54:46 +00001232 cslinearg = [chunk(PLAIN, wh, 'byte\ code\ instruction'),
Fred Drakea4541af1997-12-29 17:19:22 +00001233 chunk(GROUP, wh, [chunk(PLAIN, wh, "byte code instruction")]),
1234 chunk(PLAIN, wh, ' '),
1235 dataname,
Fred Drake43c93501997-12-29 21:40:35 +00001236 chunk(PLAIN, wh, ' '),
1237 pp[i],
Fred Drakea4541af1997-12-29 17:19:22 +00001238 ]
1239
Fred Drake43c93501997-12-29 21:40:35 +00001240 pp[i] = chunk(GROUP, wh, cslinearg)
Fred Drakea4541af1997-12-29 17:19:22 +00001241 hist.command = ch.data
1242 return length, i
1243
1244
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001245# regular indices: those that are not set in tt font by default....
1246regindices = ('cindex', )
1247
1248# remove illegal characters from node names
1249def rm_commas_etc(text):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001250 result = ''
1251 changed = 0
1252 while 1:
1253 pos = re_commas_etc.search(text)
1254 if pos >= 0:
1255 changed = 1
1256 result = result + text[:pos]
1257 text = text[pos+1:]
1258 else:
1259 result = result + text
1260 break
1261 if changed:
Fred Drake43c93501997-12-29 21:40:35 +00001262 print 'Warning: nodename changed to ' + `result`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001263
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001264 return result
1265
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001266# boolean flags
1267flags = {'texi': 1}
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001268
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001269
Fred Drake43c93501997-12-29 21:40:35 +00001270# map of \label{} to node names
1271label_nodes = {}
1272
1273
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001274##
1275## changeit: the actual routine, that changes the contents of the parsed
1276## chunks
1277##
1278
1279def changeit(buf, pp):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001280 global onlylatexspecial, hist, out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001281
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001282 i, length = 0, len(pp)
1283 while 1:
1284 # sanity check: length should always equal len(pp)
1285 if len(pp) != length:
Fred Drake74a11e51998-02-26 05:52:37 +00001286 print i, pp[i]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001287 raise 'FATAL', 'inconsistent length. thought ' + `length` + ', but should really be ' + `len(pp)`
1288 if i >= length:
1289 break
1290 ch = pp[i]
1291 i = i + 1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001292
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001293 if type(ch) is StringType:
1294 #normally, only chunks are present in pp,
1295 # but in some cases, some extra info
1296 # has been inserted, e.g., the \end{...} clauses
1297 raise 'FATAL', 'got string, probably too many ' + `end`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001298
Guido van Rossum36f219d1996-09-11 21:30:40 +00001299 if ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001300 # check for {\em ...} constructs
Fred Drakee8b46131998-02-17 05:54:46 +00001301 data = ch.data
1302 if data and \
1303 data[0].chtype == chunk_type[CSNAME] and \
1304 fontchanges.has_key(s(buf, data[0].data)):
1305 k = s(buf, data[0].data)
1306 del data[0]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001307 pp.insert(i-1, chunk(CSNAME, ch.where, fontchanges[k]))
1308 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001309
Fred Drakee8b46131998-02-17 05:54:46 +00001310 elif data:
1311 if len(data) \
1312 and data[0].chtype == chunk_type[GROUP] \
1313 and len(data[0].data) \
1314 and data[0].data[0].chtype == chunk_type[CSNAME] \
1315 and s(buf, data[0].data[0].data) == 'e':
1316 data[0] = data[0].data[0]
1317 print "invoking \\e magic group transform..."
1318 else:
1319## print "GROUP -- ch.data[0].data =", ch.data[0].data
1320 k = s(buf, data[0].data)
1321 if k == "fulllineitems":
1322 del data[0]
1323 pp[i-1:i] = data
1324 i = i - 1
1325 length = length + len(data) - 1
1326 continue
Fred Drake43c93501997-12-29 21:40:35 +00001327
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001328 # recursively parse the contents of the group
Fred Drakee8b46131998-02-17 05:54:46 +00001329 changeit(buf, data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001330
Guido van Rossum36f219d1996-09-11 21:30:40 +00001331 elif ch.chtype == chunk_type[IF]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001332 # \if...
1333 flag, negate, data = ch.data
1334 ##print 'IF: flag, negate = ' + `flag, negate`
1335 if flag not in flags.keys():
1336 raise error, 'unknown flag ' + `flag`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001337
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001338 value = flags[flag]
1339 if negate:
1340 value = (not value)
1341 del pp[i-1]
1342 length, i = length-1, i-1
1343 if value:
1344 pp[i:i] = data
1345 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001346
1347
Guido van Rossum36f219d1996-09-11 21:30:40 +00001348 elif ch.chtype == chunk_type[ENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001349 # \begin{...} ....
1350 envname, data = ch.data
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001351
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001352 #push this environment name on stack
1353 hist.inenv.insert(0, envname)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001354
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001355 #append an endenv chunk after grouped data
1356 data.append(chunk(ENDENV, ch.where, envname))
1357 ##[`data`]
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001358
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001359 #delete this object
1360 del pp[i-1]
1361 i, length = i-1, length-1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001362
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001363 #insert found data
1364 pp[i:i] = data
1365 length = length + len(data)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001366
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001367 if envname == 'verbatim':
1368 pp[i:i] = [chunk(CSLINE, ch.where, 'example'),
1369 chunk(GROUP, ch.where, [])]
1370 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001371
Fred Drakeef058031998-02-19 15:20:30 +00001372 elif envname in ('itemize', 'list', 'fulllineitems'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001373 if hist.itemizenesting > len(itemizesymbols):
1374 raise error, 'too deep itemize nesting'
Fred Drakee8b46131998-02-17 05:54:46 +00001375 if envname == 'list':
1376 del pp[i:i+2]
1377 length = length - 2
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001378 ingroupch = [chunk(CSNAME, ch.where,
Fred Drakee8b46131998-02-17 05:54:46 +00001379 itemizesymbols[hist.itemizenesting])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001380 hist.itemizenesting = hist.itemizenesting + 1
1381 pp[i:i] = [chunk(CSLINE, ch.where, 'itemize'),
Fred Drakee8b46131998-02-17 05:54:46 +00001382 chunk(GROUP, ch.where, ingroupch)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001383 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001384
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001385 elif envname == 'enumerate':
1386 if hist.enumeratenesting > len(enumeratesymbols):
1387 raise error, 'too deep enumerate nesting'
1388 ingroupch = [chunk(PLAIN, ch.where,
Fred Drakee8b46131998-02-17 05:54:46 +00001389 enumeratesymbols[hist.enumeratenesting])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001390 hist.enumeratenesting = hist.enumeratenesting + 1
1391 pp[i:i] = [chunk(CSLINE, ch.where, 'enumerate'),
Fred Drakee8b46131998-02-17 05:54:46 +00001392 chunk(GROUP, ch.where, ingroupch)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001393 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001394
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001395 elif envname == 'description':
1396 ingroupch = [chunk(CSNAME, ch.where, 'b')]
1397 pp[i:i] = [chunk(CSLINE, ch.where, 'table'),
1398 chunk(GROUP, ch.where, ingroupch)]
1399 length, i = length+2, i+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001400
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001401 elif (envname == 'tableiii') or (envname == 'tableii'):
1402 if (envname == 'tableii'):
1403 ltable = 2
1404 else:
1405 ltable = 3
1406 wh = ch.where
1407 newcode = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001408
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001409 #delete tabular format description
1410 # e.g., {|l|c|l|}
1411 length, newi = getnextarg(length, buf, pp, i)
1412 del pp[i:newi]
1413 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001414
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001415 newcode.append(chunk(CSLINE, wh, 'table'))
1416 ingroupch = [chunk(CSNAME, wh, 'asis')]
1417 newcode.append(chunk(GROUP, wh, ingroupch))
1418 newcode.append(chunk(CSLINE, wh, 'item'))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001419
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001420 #get the name of macro for @item
1421 # e.g., {code}
1422 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001423
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001424 if newi-i != 1:
1425 raise error, 'Sorry, expected 1 chunk argument'
Guido van Rossum36f219d1996-09-11 21:30:40 +00001426 if pp[i].chtype != chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001427 raise error, 'Sorry, expected plain text argument'
1428 hist.itemargmacro = s(buf, pp[i].data)
Fred Drake9c7c6be1998-02-19 21:40:22 +00001429 if convertible_csname(hist.itemargmacro):
Fred Drake74a11e51998-02-26 05:52:37 +00001430 hist.itemargmacro = conversion(hist.itemargmacro)[1]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001431 del pp[i:newi]
1432 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001433
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001434 itembody = []
1435 for count in range(ltable):
1436 length, newi = getnextarg(length, buf, pp, i)
1437 emphgroup = [
1438 chunk(CSNAME, wh, 'emph'),
1439 chunk(GROUP, 0, pp[i:newi])]
1440 del pp[i:newi]
1441 length = length - (newi-i)
1442 if count == 0:
1443 itemarg = emphgroup
1444 elif count == ltable-1:
1445 itembody = itembody + \
1446 [chunk(PLAIN, wh, ' --- ')] + emphgroup
1447 else:
1448 itembody = emphgroup
1449 newcode.append(chunk(GROUP, wh, itemarg))
1450 newcode = newcode + itembody + [chunk(DENDLINE, wh, '\n')]
1451 pp[i:i] = newcode
1452 l = len(newcode)
1453 length, i = length+l, i+l
1454 del newcode, l
1455
1456 if length != len(pp):
1457 raise 'STILL, SOMETHING wrong', `i`
1458
Fred Drakeef058031998-02-19 15:20:30 +00001459 elif envname in ('funcdesc', 'funcdescni', 'classdesc'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001460 pp.insert(i, chunk(PLAIN, ch.where, ''))
1461 i, length = i+1, length+1
Fred Drakee8b46131998-02-17 05:54:46 +00001462 length, i = do_funcdesc(length, buf, pp, i,
Fred Drakeef058031998-02-19 15:20:30 +00001463 envname[-2:] != "ni")
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001464
1465 elif envname == 'excdesc':
1466 pp.insert(i, chunk(PLAIN, ch.where, ''))
1467 i, length = i+1, length+1
1468 length, i = do_excdesc(length, buf, pp, i)
1469
Fred Drakee8b46131998-02-17 05:54:46 +00001470 elif envname in ('datadesc', 'datadescni'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001471 pp.insert(i, chunk(PLAIN, ch.where, ''))
1472 i, length = i+1, length+1
Fred Drakee8b46131998-02-17 05:54:46 +00001473 length, i = do_datadesc(length, buf, pp, i,
Fred Drakeef058031998-02-19 15:20:30 +00001474 envname[-2:] != "ni")
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001475
Fred Drakea4541af1997-12-29 17:19:22 +00001476 elif envname == 'opcodedesc':
1477 pp.insert(i, chunk(PLAIN, ch.where, ''))
1478 i, length = i+1, length+1
1479 length, i = do_opcodedesc(length, buf, pp, i)
1480
1481 elif envname == 'seealso':
1482 chunks = [chunk(ENDLINE, ch.where, "\n"),
1483 chunk(CSNAME, ch.where, "b"),
1484 chunk(GROUP, ch.where, [
1485 chunk(PLAIN, ch.where, "See also: ")]),
1486 chunk(ENDLINE, ch.where, "\n"),
1487 chunk(ENDLINE, ch.where, "\n")]
1488 pp[i-1:i] = chunks
1489 length = length + len(chunks) - 1
1490 i = i + len(chunks) - 1
1491
Fred Drake74a11e51998-02-26 05:52:37 +00001492 elif envname in ('sloppypar', 'flushleft', 'document'):
Fred Drake43c93501997-12-29 21:40:35 +00001493 pass
1494
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001495 else:
1496 print 'WARNING: don\'t know what to do with env ' + `envname`
1497
Guido van Rossum36f219d1996-09-11 21:30:40 +00001498 elif ch.chtype == chunk_type[ENDENV]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001499 envname = ch.data
1500 if envname != hist.inenv[0]:
1501 raise error, '\'end\' does not match. Name ' + `envname` + ', expected ' + `hist.inenv[0]`
1502 del hist.inenv[0]
1503 del pp[i-1]
1504 i, length = i-1, length-1
1505
1506 if envname == 'verbatim':
Fred Drake43c93501997-12-29 21:40:35 +00001507 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1508 chunk(GROUP, ch.where, [
1509 chunk(PLAIN, ch.where, 'example')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001510 i, length = i+2, length+2
Fred Drakeef058031998-02-19 15:20:30 +00001511 elif envname in ('itemize', 'list', 'fulllineitems'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001512 hist.itemizenesting = hist.itemizenesting - 1
Fred Drake43c93501997-12-29 21:40:35 +00001513 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1514 chunk(GROUP, ch.where, [
1515 chunk(PLAIN, ch.where, 'itemize')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001516 i, length = i+2, length+2
1517 elif envname == 'enumerate':
1518 hist.enumeratenesting = hist.enumeratenesting-1
Fred Drake43c93501997-12-29 21:40:35 +00001519 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1520 chunk(GROUP, ch.where, [
1521 chunk(PLAIN, ch.where, 'enumerate')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001522 i, length = i+2, length+2
1523 elif envname == 'description':
Fred Drake43c93501997-12-29 21:40:35 +00001524 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1525 chunk(GROUP, ch.where, [
1526 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001527 i, length = i+2, length+2
1528 elif (envname == 'tableiii') or (envname == 'tableii'):
Fred Drake43c93501997-12-29 21:40:35 +00001529 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1530 chunk(GROUP, ch.where, [
1531 chunk(PLAIN, ch.where, 'table')])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001532 i, length = i+2, length + 2
1533 pp.insert(i, chunk(DENDLINE, ch.where, '\n'))
1534 i, length = i+1, length+1
1535
Fred Drakeef058031998-02-19 15:20:30 +00001536 elif envname in ('funcdesc', 'excdesc', 'datadesc', 'classdesc',
Fred Drakee8b46131998-02-17 05:54:46 +00001537 'funcdescni', 'datadescni'):
Fred Drake43c93501997-12-29 21:40:35 +00001538 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1539 chunk(GROUP, ch.where, [
1540 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001541 i, length = i+2, length+2
Fred Drakea4541af1997-12-29 17:19:22 +00001542
Fred Drake43c93501997-12-29 21:40:35 +00001543 elif envname == 'opcodedesc':
1544 pp[i:i] = [chunk(CSLINE, ch.where, 'end'),
1545 chunk(GROUP, ch.where, [
1546 chunk(PLAIN, ch.where, "deffn")])]
1547 i, length = i+2, length+2
1548
Fred Drake74a11e51998-02-26 05:52:37 +00001549 elif envname in ('seealso', 'sloppypar', 'flushleft', 'document'):
Fred Drakea4541af1997-12-29 17:19:22 +00001550 pass
1551
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001552 else:
Fred Drakea4541af1997-12-29 17:19:22 +00001553 print 'WARNING: ending env %s has no actions' % `envname`
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001554
Guido van Rossum36f219d1996-09-11 21:30:40 +00001555 elif ch.chtype == chunk_type[CSNAME]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001556 # control name transformations
Guido van Rossum36f219d1996-09-11 21:30:40 +00001557 s_buf_data = s(buf, ch.data)
1558 if s_buf_data == 'optional':
1559 pp[i-1].chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001560 pp[i-1].data = '['
1561 if (i < length) and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001562 (pp[i].chtype == chunk_type[GROUP]):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001563 cp=pp[i].data
1564 pp[i:i+1]=cp + [
1565 chunk(PLAIN, ch.where, ']')]
1566 length = length+len(cp)
Fred Drake74a11e51998-02-26 05:52:37 +00001567
Guido van Rossum36f219d1996-09-11 21:30:40 +00001568 elif s_buf_data in ignoredcommands:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001569 del pp[i-1]
1570 i, length = i-1, length-1
Fred Drake74a11e51998-02-26 05:52:37 +00001571
Guido van Rossum36f219d1996-09-11 21:30:40 +00001572 elif s_buf_data == '@' and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001573 i != length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001574 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001575 s(buf, pp[i].data)[0] == '.':
1576 # \@. --> \. --> @.
1577 ch.data = '.'
1578 del pp[i]
Fred Drake74a11e51998-02-26 05:52:37 +00001579 length = length - 1
1580
1581 elif convertible_csname(s_buf_data):
1582 ch.chtype, ch.data, nix = conversion(s_buf_data)
1583 try:
1584 if nix and pp[i].chtype == chunk_type[GROUP] \
1585 and len(pp[i].data) == 0:
1586 del pp[i]
1587 length = length - 1
1588 except IndexError:
1589 pass
1590
Guido van Rossum36f219d1996-09-11 21:30:40 +00001591 elif s_buf_data == '\\':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001592 # \\ --> \* --> @*
1593 ch.data = '*'
Fred Drake74a11e51998-02-26 05:52:37 +00001594
Guido van Rossum36f219d1996-09-11 21:30:40 +00001595 elif len(s_buf_data) == 1 and \
1596 s_buf_data in onlylatexspecial:
1597 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001598 # check if such a command is followed by
1599 # an empty group: e.g., `\%{}'. If so, remove
1600 # this empty group too
1601 if i < length and \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001602 pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001603 and len(pp[i].data) == 0:
1604 del pp[i]
1605 length = length-1
1606
Fred Drake74a11e51998-02-26 05:52:37 +00001607 elif s_buf_data == "appendix":
1608 hist.chaptertype = "appendix"
1609 del pp[i-1]
1610 i, length = i-1, length-1
1611
Guido van Rossum36f219d1996-09-11 21:30:40 +00001612 elif hist.inargs and s_buf_data in inargsselves:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001613 # This is the special processing of the
1614 # arguments of the \begin{funcdesc}... or
1615 # \funcline... arguments
1616 # \, --> , \[ --> [, \] --> ]
Guido van Rossum36f219d1996-09-11 21:30:40 +00001617 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001618
Fred Drakee8b46131998-02-17 05:54:46 +00001619 elif s_buf_data == 'setindexsubitem':
1620 stuff = pp[i].data
1621 if len(stuff) != 1:
1622 raise error, "parameter to \\setindexsubitem{} too long"
1623 if pp[i].chtype != chunk_type[GROUP]:
1624 raise error, "bad chunk type following \\setindexsubitem" \
1625 "\nexpected GROUP, got " + str(ch.chtype)
1626 text = s(buf, stuff[0].data)
1627 if text[:1] != '(' or text[-1:] != ')':
1628 raise error, \
1629 'expected indexsubitem enclosed in parenteses'
1630 hist.indexsubitem = string.split(text[1:-1])
1631 del stuff, text
1632 del pp[i-1:i+1]
1633 i = i - 1
1634 length = length - 2
1635
1636 elif s_buf_data == 'newcommand':
1637 print "ignoring definition of \\" + s(buf, pp[i].data[0].data)
1638 del pp[i-1:i+2]
1639 i = i - 1
1640 length = length - 3
1641
Fred Drake74a11e51998-02-26 05:52:37 +00001642 elif s_buf_data == 'renewcommand':
1643 print "ignoring redefinition of \\" \
1644 + s(buf, pp[i].data[0].data)
1645 del pp[i-1:i+2]
1646 i = i - 1
1647 length = length - 3
1648
Fred Drakee8b46131998-02-17 05:54:46 +00001649 elif s_buf_data == 'mbox':
1650 stuff = pp[i].data
1651 pp[i-1:i+1] = stuff
1652 i = i - 1
1653 length = length + len(stuff) - 2
1654
1655 elif s_buf_data == 'version':
1656 ch.chtype = chunk_type[PLAIN]
1657 ch.data = release_version
1658
Guido van Rossum36f219d1996-09-11 21:30:40 +00001659 elif s_buf_data == 'item':
1660 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001661 length, newi = getoptarg(length, buf, pp, i)
1662 ingroupch = pp[i:newi]
1663 del pp[i:newi]
1664 length = length - (newi-i)
Fred Drake893e5e01996-10-25 22:13:10 +00001665 changeit(buf, ingroupch) # catch stuff inside the optional arg
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001666 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1667 i, length = i+1, length+1
1668
Guido van Rossum36f219d1996-09-11 21:30:40 +00001669 elif s_buf_data == 'ttindex':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001670 idxsi = hist.indexsubitem
1671
1672 cat_class = ''
1673 if len(idxsi) >= 2 and idxsi[1] in \
1674 ('method', 'function', 'protocol'):
1675 command = 'findex'
1676 elif len(idxsi) >= 2 and idxsi[1] in \
1677 ('exception', 'object'):
1678 command = 'vindex'
Fred Drake7edd8d31996-10-09 16:11:26 +00001679 elif len(idxsi) == 3 and idxsi[:2] == ['in', 'module']:
1680 command = 'cindex'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001681 else:
Fred Drake7edd8d31996-10-09 16:11:26 +00001682 print 'WARNING: can\'t categorize ' + `idxsi` \
1683 + ' for \'ttindex\' command'
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001684 command = 'cindex'
1685
1686 if not cat_class:
1687 cat_class = '('+string.join(idxsi)+')'
1688
Guido van Rossum36f219d1996-09-11 21:30:40 +00001689 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001690 ch.data = command
1691
1692 length, newi = getnextarg(length, buf, pp, i)
1693 arg = pp[i:newi]
1694 del pp[i:newi]
1695 length = length - (newi-i)
1696
1697 cat_arg = [chunk(PLAIN, ch.where, cat_class)]
1698
1699 # determine what should be set in roman, and
1700 # what in tt-font
1701 if command in regindices:
1702
1703 arg = [chunk(CSNAME, ch.where, 't'),
Fred Drake9c7c6be1998-02-19 21:40:22 +00001704 chunk(GROUP, ch.where, arg)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001705 else:
1706 cat_arg = [chunk(CSNAME, ch.where, 'r'),
Fred Drake9c7c6be1998-02-19 21:40:22 +00001707 chunk(GROUP, ch.where, cat_arg)]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001708
1709 ingroupch = arg + \
1710 [chunk(PLAIN, ch.where, ' ')] + \
1711 cat_arg
1712
1713 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1714 length, i = length+1, i+1
1715
Guido van Rossum36f219d1996-09-11 21:30:40 +00001716 elif s_buf_data == 'ldots':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001717 # \ldots --> \dots{} --> @dots{}
1718 ch.data = 'dots'
1719 if i == length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001720 or pp[i].chtype != chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001721 or pp[i].data != []:
1722 pp.insert(i, chunk(GROUP, ch.where, []))
1723 i, length = i+1, length+1
Fred Drake74a11e51998-02-26 05:52:37 +00001724
Guido van Rossum36f219d1996-09-11 21:30:40 +00001725 elif s_buf_data in themselves:
Fred Drakee8b46131998-02-17 05:54:46 +00001726 # \UNIX --> &UNIX;
Guido van Rossum36f219d1996-09-11 21:30:40 +00001727 ch.chtype = chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001728 if i != length \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001729 and pp[i].chtype == chunk_type[GROUP] \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001730 and pp[i].data == []:
1731 del pp[i]
1732 length = length-1
Fred Drake74a11e51998-02-26 05:52:37 +00001733
1734## elif s_buf_data == 'copyright':
1735## if (pp[i].chtype == chunk_type[GROUP]
1736## and not pp[i].data):
1737## del pp[i]
1738## length = length - 1
1739## del pp[i-1]
1740## i, length = i-1, length-1
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001741
Fred Drakee8b46131998-02-17 05:54:46 +00001742 elif s_buf_data == 'manpage':
1743 ch.data = 'emph'
1744 sect = s(buf, pp[i+1].data[0].data)
1745 pp[i+1].data = "(%s)" % sect
1746 pp[i+1].chtype = chunk_type[PLAIN]
1747
Guido van Rossum36f219d1996-09-11 21:30:40 +00001748 elif s_buf_data in ('lineiii', 'lineii'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001749 # This is the most tricky one
1750 # \lineiii{a1}{a2}[{a3}] -->
1751 # @item @<cts. of itemargmacro>{a1}
1752 # a2 [ -- a3]
1753 #
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001754 if not hist.inenv:
1755 raise error, 'no environment for lineiii'
1756 if (hist.inenv[0] != 'tableiii') and \
1757 (hist.inenv[0] != 'tableii'):
1758 raise error, \
Guido van Rossum36f219d1996-09-11 21:30:40 +00001759 'wrong command (%s) in wrong environment (%s)' \
1760 % (s_buf_data, `hist.inenv[0]`)
1761 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001762 ch.data = 'item'
1763 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001764 ingroupch = [chunk(CSNAME, 0, hist.itemargmacro),
1765 chunk(GROUP, 0, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001766 del pp[i:newi]
1767 length = length - (newi-i)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001768 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1769 grouppos = i
1770 i, length = i+1, length+1
1771 length, i = getnextarg(length, buf, pp, i)
1772 length, newi = getnextarg(length, buf, pp, i)
1773 if newi > i:
1774 # we have a 3rd arg
1775 pp.insert(i, chunk(PLAIN, ch.where, ' --- '))
1776 i = newi + 1
1777 length = length + 1
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001778 if length != len(pp):
1779 raise 'IN LINEIII IS THE ERR', `i`
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001780
Fred Drake74a11e51998-02-26 05:52:37 +00001781 elif s_buf_data in ('chapter', 'section',
1782 'subsection', 'subsubsection'):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001783 #\xxxsection{A} ---->
1784 # @node A, , ,
1785 # @xxxsection A
1786 ## also: remove commas and quotes
Fred Drake74a11e51998-02-26 05:52:37 +00001787 if s_buf_data == "chapter":
1788 ch.data = hist.chaptertype
Guido van Rossum36f219d1996-09-11 21:30:40 +00001789 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001790 length, newi = getnextarg(length, buf, pp, i)
Fred Drakee8b46131998-02-17 05:54:46 +00001791 afternodenamecmd = next_command_p(length, buf,
1792 pp, newi, 'nodename')
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001793 if afternodenamecmd < 0:
1794 cp1 = crcopy(pp[i:newi])
Guido van Rossum36f219d1996-09-11 21:30:40 +00001795 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001796 length, newi = length - (newi-i) + 1, i+1
1797 text = flattext(buf, cp1)
1798 text = invent_node_names(text)
1799 else:
Fred Drakee8b46131998-02-17 05:54:46 +00001800 length, endarg = getnextarg(length, buf,
1801 pp, afternodenamecmd)
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001802 cp1 = crcopy(pp[afternodenamecmd:endarg])
1803 del pp[newi:endarg]
1804 length = length - (endarg-newi)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001805
Guido van Rossum36f219d1996-09-11 21:30:40 +00001806 pp[i:newi] = [chunk(GROUP, ch.where, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001807 length, newi = length - (newi-i) + 1, i + 1
1808 text = flattext(buf, cp1)
1809 if text[-1] == '.':
1810 text = text[:-1]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001811 if text in hist.nodenames:
1812 print 'WARNING: node name ' + `text` + ' already used'
1813 out.doublenodes.append(text)
1814 else:
1815 hist.nodenames.append(text)
1816 text = rm_commas_etc(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00001817 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'node'),
1818 chunk(GROUP, ch.where, [
1819 chunk(PLAIN, ch.where, text+', , ,')
1820 ])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001821 i, length = newi+2, length+2
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001822
Guido van Rossum36f219d1996-09-11 21:30:40 +00001823 elif s_buf_data == 'funcline':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001824 # fold it to a very short environment
Guido van Rossum36f219d1996-09-11 21:30:40 +00001825 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1826 chunk(GROUP, ch.where, [
1827 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001828 i, length = i+2, length+2
1829 length, i = do_funcdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001830
Guido van Rossum36f219d1996-09-11 21:30:40 +00001831 elif s_buf_data == 'dataline':
1832 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1833 chunk(GROUP, ch.where, [
1834 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001835 i, length = i+2, length+2
1836 length, i = do_datadesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001837
Guido van Rossum36f219d1996-09-11 21:30:40 +00001838 elif s_buf_data == 'excline':
1839 pp[i-1:i-1] = [chunk(CSLINE, ch.where, 'end'),
1840 chunk(GROUP, ch.where, [
1841 chunk(PLAIN, ch.where, hist.command)])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001842 i, length = i+2, length+2
1843 length, i = do_excdesc(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001844
Guido van Rossum36f219d1996-09-11 21:30:40 +00001845 elif s_buf_data == 'index':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001846 #\index{A} --->
1847 # @cindex A
Guido van Rossum36f219d1996-09-11 21:30:40 +00001848 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001849 ch.data = 'cindex'
1850 length, newi = getnextarg(length, buf, pp, i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001851
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001852 ingroupch = pp[i:newi]
1853 del pp[i:newi]
1854 length = length - (newi-i)
1855 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1856 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001857
Guido van Rossum36f219d1996-09-11 21:30:40 +00001858 elif s_buf_data == 'bifuncindex':
1859 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001860 ch.data = 'findex'
1861 length, newi = getnextarg(length, buf, pp, i)
1862 ingroupch = pp[i:newi]
1863 del pp[i:newi]
1864 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001865
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001866 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1867 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1868 ingroupch.append(chunk(GROUP, ch.where, [
1869 chunk(PLAIN, ch.where,
1870 '(built-in function)')]))
1871
1872 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1873 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001874
Guido van Rossum36f219d1996-09-11 21:30:40 +00001875 elif s_buf_data == 'obindex':
1876 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001877 ch.data = 'findex'
1878 length, newi = getnextarg(length, buf, pp, i)
1879 ingroupch = pp[i:newi]
1880 del pp[i:newi]
1881 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001882
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001883 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1884 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1885 ingroupch.append(chunk(GROUP, ch.where, [
1886 chunk(PLAIN, ch.where,
1887 '(object)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001888
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001889 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1890 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001891
Guido van Rossum36f219d1996-09-11 21:30:40 +00001892 elif s_buf_data == 'opindex':
1893 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001894 ch.data = 'findex'
1895 length, newi = getnextarg(length, buf, pp, i)
1896 ingroupch = pp[i:newi]
1897 del pp[i:newi]
1898 length = length - (newi-i)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001899
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001900 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1901 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1902 ingroupch.append(chunk(GROUP, ch.where, [
1903 chunk(PLAIN, ch.where,
1904 '(operator)')]))
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001905
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001906 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1907 length, i = length+1, i+1
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00001908
Fred Drakea4541af1997-12-29 17:19:22 +00001909 elif s_buf_data in ('bimodindex', 'refbimodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001910 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001911 ch.data = 'pindex'
1912 length, newi = getnextarg(length, buf, pp, i)
1913 ingroupch = pp[i:newi]
1914 del pp[i:newi]
1915 length = length - (newi-i)
1916
1917 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1918 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1919 ingroupch.append(chunk(GROUP, ch.where, [
1920 chunk(PLAIN, ch.where,
1921 '(built-in)')]))
1922
1923 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1924 length, i = length+1, i+1
1925
Fred Drakea4541af1997-12-29 17:19:22 +00001926 elif s_buf_data == 'refmodindex':
1927 ch.chtype = chunk_type[CSLINE]
1928 ch.data = 'pindex'
1929 length, newi = getnextarg(length, buf, pp, i)
1930 ingroupch = pp[i:newi]
1931 del pp[i:newi]
1932 length = length - (newi-i)
1933
Fred Drakea4541af1997-12-29 17:19:22 +00001934 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1935 length, i = length+1, i+1
1936
Fred Drakea4541af1997-12-29 17:19:22 +00001937 elif s_buf_data in ('stmodindex', 'refstmodindex'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00001938 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001939 # use the program index as module index
1940 ch.data = 'pindex'
1941 length, newi = getnextarg(length, buf, pp, i)
1942 ingroupch = pp[i:newi]
1943 del pp[i:newi]
1944 length = length - (newi-i)
1945
1946 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1947 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1948 ingroupch.append(chunk(GROUP, ch.where, [
1949 chunk(PLAIN, ch.where,
1950 '(standard)')]))
1951
1952 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1953 length, i = length+1, i+1
1954
Fred Drakea4541af1997-12-29 17:19:22 +00001955 elif s_buf_data in ('stmodindex', 'refstmodindex'):
1956 ch.chtype = chunk_type[CSLINE]
1957 # use the program index as module index
1958 ch.data = 'pindex'
1959 length, newi = getnextarg(length, buf, pp, i)
1960 ingroupch = pp[i:newi]
1961 del pp[i:newi]
1962 length = length - (newi-i)
1963
1964 ingroupch.append(chunk(PLAIN, ch.where, ' '))
1965 ingroupch.append(chunk(CSNAME, ch.where, 'r'))
1966 ingroupch.append(chunk(GROUP, ch.where, [
1967 chunk(PLAIN, ch.where,
1968 '(standard)')]))
1969
1970 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
1971 length, i = length+1, i+1
1972
Fred Drake74a11e51998-02-26 05:52:37 +00001973 elif s_buf_data == 'stindex':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001974 # XXX must actually go to newindex st
Fred Drakea4541af1997-12-29 17:19:22 +00001975 what = (s_buf_data[:2] == "st") and "statement" or "keyword"
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001976 wh = ch.where
Guido van Rossum36f219d1996-09-11 21:30:40 +00001977 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001978 ch.data = 'cindex'
1979 length, newi = getnextarg(length, buf, pp, i)
1980 ingroupch = [chunk(CSNAME, wh, 'code'),
Fred Drakee8b46131998-02-17 05:54:46 +00001981 chunk(GROUP, wh, pp[i:newi])]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001982
1983 del pp[i:newi]
1984 length = length - (newi-i)
1985
1986 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001987 t.append(chunk(PLAIN, wh, ' ' + what))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001988
1989 pp.insert(i, chunk(GROUP, wh, t))
1990 i, length = i+1, length+1
1991
1992 pp.insert(i, chunk(CSLINE, wh, 'cindex'))
1993 i, length = i+1, length+1
1994
1995 t = ingroupch[:]
Fred Drakea4541af1997-12-29 17:19:22 +00001996 t.insert(0, chunk(PLAIN, wh, what + ', '))
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00001997
1998 pp.insert(i, chunk(GROUP, wh, t))
1999 i, length = i+1, length+1
2000
Guido van Rossum36f219d1996-09-11 21:30:40 +00002001 elif s_buf_data == 'indexii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002002 #\indexii{A}{B} --->
2003 # @cindex A B
2004 # @cindex B, A
2005 length, newi = getnextarg(length, buf, pp, i)
2006 cp11 = pp[i:newi]
2007 cp21 = crcopy(pp[i:newi])
2008 del pp[i:newi]
2009 length = length - (newi-i)
2010 length, newi = getnextarg(length, buf, pp, i)
2011 cp12 = pp[i:newi]
2012 cp22 = crcopy(pp[i:newi])
2013 del pp[i:newi]
2014 length = length - (newi-i)
2015
Guido van Rossum36f219d1996-09-11 21:30:40 +00002016 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002017 ch.data = 'cindex'
2018 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
2019 chunk(PLAIN, ch.where, ' ')] + cp12))
2020 i, length = i+1, length+1
2021 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
2022 chunk(GROUP, ch.where, cp22 + [
2023 chunk(PLAIN, ch.where, ', ')]+ cp21)]
2024 i, length = i+2, length+2
2025
Guido van Rossum36f219d1996-09-11 21:30:40 +00002026 elif s_buf_data == 'indexiii':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002027 length, newi = getnextarg(length, buf, pp, i)
2028 cp11 = pp[i:newi]
2029 cp21 = crcopy(pp[i:newi])
2030 cp31 = crcopy(pp[i:newi])
2031 del pp[i:newi]
2032 length = length - (newi-i)
2033 length, newi = getnextarg(length, buf, pp, i)
2034 cp12 = pp[i:newi]
2035 cp22 = crcopy(pp[i:newi])
2036 cp32 = crcopy(pp[i:newi])
2037 del pp[i:newi]
2038 length = length - (newi-i)
2039 length, newi = getnextarg(length, buf, pp, i)
2040 cp13 = pp[i:newi]
2041 cp23 = crcopy(pp[i:newi])
2042 cp33 = crcopy(pp[i:newi])
2043 del pp[i:newi]
2044 length = length - (newi-i)
2045
Guido van Rossum36f219d1996-09-11 21:30:40 +00002046 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002047 ch.data = 'cindex'
2048 pp.insert(i, chunk(GROUP, ch.where, cp11 + [
2049 chunk(PLAIN, ch.where, ' ')] + cp12
2050 + [chunk(PLAIN, ch.where, ' ')]
2051 + cp13))
2052 i, length = i+1, length+1
2053 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
2054 chunk(GROUP, ch.where, cp22 + [
2055 chunk(PLAIN, ch.where, ' ')]+ cp23
2056 + [chunk(PLAIN, ch.where, ', ')] +
2057 cp21)]
2058 i, length = i+2, length+2
2059 pp[i:i] = [chunk(CSLINE, ch.where, 'cindex'),
2060 chunk(GROUP, ch.where, cp33 + [
2061 chunk(PLAIN, ch.where, ', ')]+ cp31
2062 + [chunk(PLAIN, ch.where, ' ')] +
2063 cp32)]
2064 i, length = i+2, length+2
2065
Guido van Rossum36f219d1996-09-11 21:30:40 +00002066 elif s_buf_data == 'indexiv':
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002067 length, newi = getnextarg(length, buf, pp, i)
2068 cp11 = pp[i:newi]
2069 cp21 = crcopy(pp[i:newi])
2070 cp31 = crcopy(pp[i:newi])
2071 cp41 = crcopy(pp[i:newi])
2072 del pp[i:newi]
2073 length = length - (newi-i)
2074 length, newi = getnextarg(length, buf, pp, i)
2075 cp12 = pp[i:newi]
2076 cp22 = crcopy(pp[i:newi])
2077 cp32 = crcopy(pp[i:newi])
2078 cp42 = crcopy(pp[i:newi])
2079 del pp[i:newi]
2080 length = length - (newi-i)
2081 length, newi = getnextarg(length, buf, pp, i)
2082 cp13 = pp[i:newi]
2083 cp23 = crcopy(pp[i:newi])
2084 cp33 = crcopy(pp[i:newi])
2085 cp43 = crcopy(pp[i:newi])
2086 del pp[i:newi]
2087 length = length - (newi-i)
2088 length, newi = getnextarg(length, buf, pp, i)
2089 cp14 = pp[i:newi]
2090 cp24 = crcopy(pp[i:newi])
2091 cp34 = crcopy(pp[i:newi])
2092 cp44 = crcopy(pp[i:newi])
2093 del pp[i:newi]
2094 length = length - (newi-i)
2095
Guido van Rossum36f219d1996-09-11 21:30:40 +00002096 ch.chtype = chunk_type[CSLINE]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002097 ch.data = 'cindex'
2098 ingroupch = cp11 + \
2099 spacech + cp12 + \
2100 spacech + cp13 + \
2101 spacech + cp14
2102 pp.insert(i, chunk(GROUP, ch.where, ingroupch))
2103 i, length = i+1, length+1
2104 ingroupch = cp22 + \
2105 spacech + cp23 + \
2106 spacech + cp24 + \
2107 commach + cp21
2108 pp[i:i] = cindexch + [
2109 chunk(GROUP, ch.where, ingroupch)]
2110 i, length = i+2, length+2
2111 ingroupch = cp33 + \
2112 spacech + cp34 + \
2113 commach + cp31 + \
2114 spacech + cp32
2115 pp[i:i] = cindexch + [
2116 chunk(GROUP, ch.where, ingroupch)]
2117 i, length = i+2, length+2
2118 ingroupch = cp44 + \
2119 commach + cp41 + \
2120 spacech + cp42 + \
2121 spacech + cp43
2122 pp[i:i] = cindexch + [
2123 chunk(GROUP, ch.where, ingroupch)]
2124 i, length = i+2, length+2
2125
Fred Drakea4541af1997-12-29 17:19:22 +00002126 elif s_buf_data == 'seemodule':
2127 ch.data = "code"
Fred Drakee8b46131998-02-17 05:54:46 +00002128 # this is needed for just one of the input files... -sigh-
2129 while pp[i+1].chtype == chunk_type[COMMENT]:
2130 i = i + 1
Fred Drakea4541af1997-12-29 17:19:22 +00002131 data = pp[i+1].data
Fred Drakee8b46131998-02-17 05:54:46 +00002132 oparen = chunk(PLAIN, ch.where, " (")
2133 data.insert(0, oparen)
Fred Drakea4541af1997-12-29 17:19:22 +00002134 data.append(chunk(PLAIN, ch.where, ")"))
2135 pp[i+1:i+2] = data
2136 length = length + len(data) - 1
2137
2138 elif s_buf_data == 'seetext':
2139 data = pp[i].data
2140 data.insert(0, chunk(ENDLINE, ch.where, "\n"))
2141 pp[i-1:i+1] = data
2142 i = i - 1
2143 length = length + len(data) - 2
2144
Fred Drake43c93501997-12-29 21:40:35 +00002145 elif s_buf_data == "quad":
2146 ch.chtype = PLAIN
2147 ch.data = " "
2148
Fred Drake74a11e51998-02-26 05:52:37 +00002149 elif s_buf_data in ('usepackage', 'input'):
2150 del pp[i-1:i+1]
2151 i, length = i-1, length-2
2152
Fred Drakee8b46131998-02-17 05:54:46 +00002153 elif s_buf_data in ('noindent', 'indexsubitem', 'footnote'):
Guido van Rossum36f219d1996-09-11 21:30:40 +00002154 pass
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002155
Fred Drakea4541af1997-12-29 17:19:22 +00002156 elif s_buf_data == 'label':
Fred Drake43c93501997-12-29 21:40:35 +00002157 name = s(buf, pp[i].data[0].data)
Fred Drakea4541af1997-12-29 17:19:22 +00002158 del pp[i-1:i+1]
2159 length = length - 2
2160 i = i - 1
Fred Drake43c93501997-12-29 21:40:35 +00002161 label_nodes[name] = hist.nodenames[-1]
2162
Fred Drakee8b46131998-02-17 05:54:46 +00002163 elif s_buf_data == 'rfc':
2164 ch.chtype = chunk_type[PLAIN]
2165 ch.data = "RFC " + s(buf, pp[i].data[0].data)
2166 del pp[i]
2167 length = length - 1
2168
Fred Drake43c93501997-12-29 21:40:35 +00002169 elif s_buf_data == 'ref':
2170 name = s(buf, pp[i].data[0].data)
2171 if label_nodes.has_key(name):
2172 pp[i].data[0].data = label_nodes[name]
2173 else:
2174 pp[i-1:i+1] = [
2175 chunk(PLAIN, ch.where,
2176 "(unknown node reference: %s)" % name)]
2177 length = length - 1
2178 print "WARNING: unknown node label", `name`
Fred Drakea4541af1997-12-29 17:19:22 +00002179
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002180 else:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002181 print "don't know what to do with keyword " + s_buf_data
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002182
2183
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002184re_atsign = regex.compile('[@{}]')
2185re_newline = regex.compile('\n')
2186
2187def dumpit(buf, wm, pp):
2188
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002189 global out
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002190
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002191 i, length = 0, len(pp)
2192
2193 addspace = 0
2194
2195 while 1:
2196 if len(pp) != length:
2197 raise 'FATAL', 'inconsistent length'
2198 if i == length:
2199 break
2200 ch = pp[i]
2201 i = i + 1
2202
Guido van Rossum36f219d1996-09-11 21:30:40 +00002203 dospace = addspace
2204 addspace = 0
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002205
Guido van Rossum36f219d1996-09-11 21:30:40 +00002206 if ch.chtype == chunk_type[CSNAME]:
2207 s_buf_data = s(buf, ch.data)
Fred Drake74a11e51998-02-26 05:52:37 +00002208## if s_buf_data == 'e':
2209## wm('\\')
2210## continue
2211## if s_buf_data == '$':
2212## wm('$')
2213## continue
Guido van Rossum36f219d1996-09-11 21:30:40 +00002214 wm('@' + s_buf_data)
2215 if s_buf_data == 'node' and \
2216 pp[i].chtype == chunk_type[PLAIN] and \
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002217 s(buf, pp[i].data) in out.doublenodes:
2218 ##XXX doesnt work yet??
2219 wm(' ZZZ-' + zfill(`i`, 4))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002220 if s_buf_data[0] in string.letters:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002221 addspace = 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002222 elif ch.chtype == chunk_type[PLAIN]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002223 if dospace and s(buf, ch.data) not in (' ', '\t'):
2224 wm(' ')
2225 text = s(buf, ch.data)
2226 while 1:
2227 pos = re_atsign.search(text)
2228 if pos < 0:
2229 break
2230 wm(text[:pos] + '@' + text[pos])
2231 text = text[pos+1:]
2232 wm(text)
Guido van Rossum36f219d1996-09-11 21:30:40 +00002233 elif ch.chtype == chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002234 wm('{')
2235 dumpit(buf, wm, ch.data)
2236 wm('}')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002237 elif ch.chtype == chunk_type[DENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002238 wm('\n\n')
2239 while i != length and pp[i].chtype in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002240 (chunk_type[DENDLINE], chunk_type[ENDLINE]):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002241 i = i + 1
Guido van Rossum36f219d1996-09-11 21:30:40 +00002242 elif ch.chtype == chunk_type[OTHER]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002243 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002244 elif ch.chtype == chunk_type[ACTIVE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002245 wm(s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002246 elif ch.chtype == chunk_type[ENDLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002247 wm('\n')
Guido van Rossum36f219d1996-09-11 21:30:40 +00002248 elif ch.chtype == chunk_type[CSLINE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002249 if i >= 2 and pp[i-2].chtype not in \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002250 (chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2251 and (pp[i-2].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002252 or s(buf, pp[i-2].data)[-1] != '\n'):
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002253
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002254 wm('\n')
2255 wm('@' + s(buf, ch.data))
2256 if i == length:
2257 raise error, 'CSLINE expected another chunk'
Guido van Rossum36f219d1996-09-11 21:30:40 +00002258 if pp[i].chtype != chunk_type[GROUP]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002259 raise error, 'CSLINE expected GROUP'
2260 if type(pp[i].data) != ListType:
2261 raise error, 'GROUP chould contain []-data'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002262
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002263 wobj = Wobj()
2264 dumpit(buf, wobj.write, pp[i].data)
2265 i = i + 1
2266 text = wobj.data
2267 del wobj
2268 if text:
2269 wm(' ')
2270 while 1:
2271 pos = re_newline.search(text)
2272 if pos < 0:
2273 break
2274 print 'WARNING: found newline in csline arg'
2275 wm(text[:pos] + ' ')
2276 text = text[pos+1:]
2277 wm(text)
2278 if i >= length or \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002279 pp[i].chtype not in (chunk_type[CSLINE],
2280 chunk_type[ENDLINE], chunk_type[DENDLINE]) \
2281 and (pp[i].chtype != chunk_type[PLAIN]
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002282 or s(buf, pp[i].data)[0] != '\n'):
2283 wm('\n')
Guido van Rossum49604d31996-09-10 22:19:51 +00002284
Guido van Rossum36f219d1996-09-11 21:30:40 +00002285 elif ch.chtype == chunk_type[COMMENT]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002286 if s(buf, ch.data) and \
2287 regex.match('^[ \t]*$', s(buf, ch.data)) < 0:
Guido van Rossum36f219d1996-09-11 21:30:40 +00002288 if i >= 2 \
Fred Drake74a11e51998-02-26 05:52:37 +00002289 and pp[i-2].chtype not in (chunk_type[ENDLINE],
2290 chunk_type[DENDLINE]) \
Guido van Rossum36f219d1996-09-11 21:30:40 +00002291 and not (pp[i-2].chtype == chunk_type[PLAIN]
2292 and regex.match('\\(.\\|\n\\)*[ \t]*\n$', s(buf, pp[i-2].data)) >= 0):
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002293 wm('\n')
2294 wm('@c ' + s(buf, ch.data))
Guido van Rossum36f219d1996-09-11 21:30:40 +00002295 elif ch.chtype == chunk_type[IGNORE]:
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002296 pass
2297 else:
2298 try:
2299 str = `s(buf, ch.data)`
2300 except TypeError:
2301 str = `ch.data`
2302 if len(str) > 400:
2303 str = str[:400] + '...'
2304 print 'warning:', ch.chtype, 'not handled, data ' + str
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002305
2306
2307
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002308def main():
Fred Drakee8b46131998-02-17 05:54:46 +00002309 global release_version
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002310 outfile = None
2311 headerfile = 'texipre.dat'
2312 trailerfile = 'texipost.dat'
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002313
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002314 try:
Fred Drakee8b46131998-02-17 05:54:46 +00002315 opts, args = getopt.getopt(sys.argv[1:], 'o:h:t:v:')
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002316 except getopt.error:
2317 args = []
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002318
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002319 if not args:
2320 print 'usage: partparse [-o outfile] [-h headerfile]',
2321 print '[-t trailerfile] file ...'
2322 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002323
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002324 for opt, arg in opts:
2325 if opt == '-o': outfile = arg
2326 if opt == '-h': headerfile = arg
2327 if opt == '-t': trailerfile = arg
Fred Drakee8b46131998-02-17 05:54:46 +00002328 if opt == '-v': release_version = arg
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002329
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002330 if not outfile:
2331 root, ext = os.path.splitext(args[0])
2332 outfile = root + '.texi'
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002333
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002334 if outfile in args:
2335 print 'will not overwrite input file', outfile
2336 sys.exit(2)
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002337
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002338 outf = open(outfile, 'w')
2339 outf.write(open(headerfile, 'r').read())
Guido van Rossum7a2dba21993-11-05 14:45:11 +00002340
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002341 for file in args:
2342 if len(args) > 1: print '='*20, file, '='*20
2343 buf = open(file, 'r').read()
2344 w, pp = parseit(buf)
2345 startchange()
2346 changeit(buf, pp)
2347 dumpit(buf, outf.write, pp)
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002348
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002349 outf.write(open(trailerfile, 'r').read())
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002350
Guido van Rossum5f18d6c1996-09-10 22:34:20 +00002351 outf.close()
Guido van Rossum95cd2ef1992-12-08 14:37:55 +00002352
Guido van Rossum49604d31996-09-10 22:19:51 +00002353if __name__ == "__main__":
2354 main()