1if not modules then modules = { } end modules ['luatex-preprocessor'] = {
2 version = 1.001,
3 comment = "companion to luatex-preprocessor.tex",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12
13local rep, sub, gmatch = string.rep, string.sub, string.gmatch
14local insert, remove = table.insert, table.remove
15local setmetatable = setmetatable
16
17local stack, top, n, hashes = { }, nil, 0, { }
18
19local function set(s)
20 if top then
21 n = n + 1
22 if n > 9 then
23 texio.write_nl("number of arguments > 9, ignoring: " .. s)
24 else
25 local ns = #stack
26 local h = hashes[ns]
27 if not h then
28 h = rep("#",ns)
29 hashes[ns] = h
30 end
31 m = h .. n
32 top[s] = m
33 return m
34 end
35 end
36end
37
38local function get(s)
39 local m = top and top[s] or s
40 return m
41end
42
43local function push()
44 top = { }
45 n = 0
46 local s = stack[#stack]
47 if s then
48 setmetatable(top,{ __index = s })
49 end
50 insert(stack,top)
51end
52
53local function pop()
54 top = remove(stack)
55end
56
57local leftbrace = lpeg.P("{")
58local rightbrace = lpeg.P("}")
59local escape = lpeg.P("\\")
60
61local space = lpeg.P(" ")
62local spaces = space^1
63local newline = lpeg.S("\r\n")
64local nobrace = 1 - leftbrace - rightbrace
65
66local name = lpeg.R("AZ","az")^1
67local longname = (leftbrace/"") * (nobrace^1) * (rightbrace/"")
68local variable = lpeg.P("#") * lpeg.Cs(name + longname)
69local escapedname = escape * name
70local definer = escape * (lpeg.P("def") + lpeg.P("egdx") * lpeg.P("def"))
71local anything = lpeg.P(1)
72local always = lpeg.P(true)
73
74local pushlocal = always / push
75local poplocal = always / pop
76local declaration = variable / set
77local identifier = variable / get
78
79local function matcherror(str,pos)
80 texio.write_nl("runaway definition at: " .. sub(str,pos-30,pos))
81end
82
83local parser = lpeg.Cs { "converter",
84 definition = pushlocal
85 * definer
86 * escapedname
87 * (declaration + (1-leftbrace))^0
88 * lpeg.V("braced")
89 * poplocal,
90 braced = leftbrace
91 * ( lpeg.V("definition")
92 + identifier
93 + lpeg.V("braced")
94 + nobrace
95 )^0
96 * (rightbrace + lpeg.Cmt(always,matcherror)),
97 converter = (lpeg.V("definition") + anything)^1,
98}
99
100
101
102local function find_file(...)
103
104
105 return kpse.find_file(...) or ""
106end
107
108commands = commands or { }
109
110function commands.preprocessed(str)
111 return lpeg.match(parser,str)
112end
113
114function commands.inputpreprocessed(name)
115 local name = find_file(name) or ""
116 if name ~= "" then
117
118 local f = io.open(name,'rb')
119 if f then
120 texio.write("("..name)
121 local d = commands.preprocessed(f:read("*a"))
122 if d and d ~= "" then
123 texio.write("processed: " .. name)
124 for s in gmatch(d,"[^\n\r]+") do
125 tex.print(s)
126 end
127 end
128 f:close()
129 texio.write(")")
130 else
131 tex.error("preprocessor error, invalid file: " .. name)
132 end
133 else
134 tex.error("preprocessor error, unknown file: " .. name)
135 end
136end
137
138function commands.preprocessfile(oldfile,newfile)
139 if oldfile and oldfile ~= newfile then
140 local f = io.open(oldfile,'rb')
141 if f then
142 local g = io.open(newfile,'wb')
143 if g then
144 g:write(lpeg.match(parser,f:read("*a") or ""))
145 g:close()
146 end
147 f:close()
148 end
149 end
150end
151
152
153
154
155
156
157
158 |