1 from pyparsing import Word, CharsNotIn, Optional, OneOrMore, ZeroOrMore, Group, Forward, ParseException, Literal, Suppress, replaceWith, StringEnd, lineno, QuotedString, White, NotAny, ParserElement, MatchFirst
5 def __init__(self, s, loc, toks):
8 return "[%s]" % self.str
11 def argfun(s, loc, toks):
12 return Argument(s, loc, toks)
15 def __init__(self, s, loc, toks):
16 self.str = toks[0].asList()
18 return '{' + "".join([str(s) for s in self.str]) + '}'
19 return "{%s}" % self.str
21 return "".join([str(s) for s in self.str])
22 def paramfun(s, loc, toks):
23 return Parameter(s, loc, toks)
26 def __init__(self, s, loc, toks):
27 self.cmd = str(toks[0])[1:]
28 #print 'cmd', self.cmd
29 self.args = toks[1].asList()
30 self.params = toks[2].asList()
31 self.lineno = lineno(loc, s)
34 return '\\' + self.cmd + "".join([repr(a) for a in self.args]) + "".join([repr(p) for p in self.params])
36 class ZeroOrMoreAsList(ZeroOrMore):
37 def __init__(self, *args):
38 ZeroOrMore.__init__(self, *args)
39 def listify(s, loc, toks):
41 self.setParseAction(listify)
43 ParserElement.setDefaultWhitespaceChars("\n\t")
47 filler = CharsNotIn(backslash + '$')
48 filler2 = CharsNotIn(backslash + '$' + '{}')
50 arg = '[' + CharsNotIn("]") + ']'
51 arg.setParseAction(argfun)
53 dollarmath = QuotedString('$', multiline=True, unquoteResults=False)
54 param = Suppress(Literal('{')) + ZeroOrMoreAsList(dollarmath | filler2 | QuotedString('{', endQuoteChar='}', unquoteResults=False) | texcmd) + Suppress(Literal('}'))
55 param.setParseAction(paramfun)
56 def bs(c): return Literal("\\" + c)
57 singles = bs("[") | bs("]") | bs("{") | bs("}") | bs("\\") | bs("&") | bs("_") | bs(",") | bs("#") | bs("\n") | bs(";") | bs("|") | bs("%") | bs("*")
58 texcmd << (singles | Word("\\", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", min = 2)) + ZeroOrMoreAsList(arg) + ZeroOrMoreAsList(param)
59 def texcmdfun(s, loc, toks):
60 if str(toks[0])[1:] == 'input':
61 filename = "../" + toks[2].asList()[0].str[0] + ".tex"
62 print 'Now parsing', filename, loc
63 return latexparser(filename, lineno(loc, s))
65 return TexCmd(s, loc, toks)
66 texcmd.setParseAction(texcmdfun)
68 #legal = "".join([chr(x) for x in set(range(32, 127)) - set(backslash)])
70 document = ZeroOrMore(dollarmath | texcmd | filler) + StringEnd().suppress()
73 s = "This is \\\\ test"
75 for t in document.parseString(s):
76 if isinstance(t, TexCmd):
77 print '====> cmd=[%s]' % t.cmd, t
82 def latexparser(filename, startline):
83 f = open(filename, "rt")
87 if '%' in s and not '\\%' in s:
88 return s[:s.index('%')] + '\n'
92 lines = [uncomment(l) for l in lines]
93 print len(lines), "lines"
95 docstr = "".join(lines)
96 # document.setFailAction(None)
98 r = document.parseString(docstr)
100 if isinstance(x, TexCmd) and not x.filename:
101 x.filename = filename
103 except ParseException, pe:
104 print 'Fatal problem at %s line %d col %d' % (filename, pe.lineno, pe.col)