trac-lmx.lua /size: 20 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
trac-lmx
'
]
=
{
2
version
=
1
.
002
,
3
comment
=
"
companion to trac-lmx.mkiv
"
,
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
-- this one will be adpated to the latest helpers
10 11
local
type
,
tostring
,
rawget
,
loadstring
,
pcall
=
type
,
tostring
,
rawget
,
loadstring
,
pcall
12
local
format
,
sub
,
gsub
=
string
.
format
,
string
.
sub
,
string
.
gsub
13
local
concat
=
table
.
concat
14
local
collapsespaces
=
string
.
collapsespaces
15
local
P
,
Cc
,
Cs
,
C
,
Carg
,
lpegmatch
=
lpeg
.
P
,
lpeg
.
Cc
,
lpeg
.
Cs
,
lpeg
.
C
,
lpeg
.
Carg
,
lpeg
.
match
16
local
joinpath
,
replacesuffix
,
pathpart
,
filesuffix
=
file
.
join
,
file
.
replacesuffix
,
file
.
pathpart
,
file
.
suffix
17 18
local
allocate
=
utilities
.
storage
.
allocate
19
local
setmetatableindex
=
table
.
setmetatableindex
20 21
----- trace_templates = false trackers .register("lmx.templates", function(v) trace_templates = v end)
22
local
trace_variables
=
false
trackers
.
register
(
"
lmx.variables
"
,
function
(
v
)
trace_variables
=
v
end
)
23 24
local
cache_templates
=
true
directives
.
register
(
"
lmx.cache.templates
"
,
function
(
v
)
cache_templates
=
v
end
)
25
local
cache_files
=
true
directives
.
register
(
"
lmx.cache.files
"
,
function
(
v
)
cache_files
=
v
end
)
26 27
local
report_lmx
=
logs
.
reporter
(
"
lmx
"
)
28
local
report_error
=
logs
.
reporter
(
"
lmx
"
,
"
error
"
)
29 30
lmx
=
lmx
or
{
}
31
local
lmx
=
lmx
32 33
-- This will change: we will just pass the global defaults as argument, but then we need
34
-- to rewrite some older code or come up with an ugly trick.
35 36
local
lmxvariables
=
{
37
[
'
title-default
'
]
=
'
ConTeXt LMX File
'
,
38
[
'
color-background-green
'
]
=
'
#4F6F6F
'
,
39
[
'
color-background-blue
'
]
=
'
#6F6F8F
'
,
40
[
'
color-background-yellow
'
]
=
'
#8F8F6F
'
,
41
[
'
color-background-purple
'
]
=
'
#8F6F8F
'
,
42
[
'
color-background-body
'
]
=
'
#808080
'
,
43
[
'
color-background-main
'
]
=
'
#3F3F3F
'
,
44
}
45 46
local
lmxinherited
=
{
47
[
'
title
'
]
=
'
title-default
'
,
48
[
'
color-background-one
'
]
=
'
color-background-green
'
,
49
[
'
color-background-two
'
]
=
'
color-background-blue
'
,
50
[
'
color-background-three
'
]
=
'
color-background-one
'
,
51
[
'
color-background-four
'
]
=
'
color-background-two
'
,
52
}
53 54
lmx
.
variables
=
lmxvariables
55
lmx
.
inherited
=
lmxinherited
56 57
setmetatableindex
(
lmxvariables
,
function
(
t
,
k
)
58
k
=
lmxinherited
[
k
]
59
while
k
do
60
local
v
=
rawget
(
lmxvariables
,
k
)
61
if
v
then
62
return
v
63
end
64
k
=
lmxinherited
[
k
]
65
end
66
end
)
67 68
function
lmx
.
set
(
key
,
value
)
69
lmxvariables
[
key
]
=
value
70
end
71 72
function
lmx
.
get
(
key
)
73
return
lmxvariables
[
key
]
or
"
"
74
end
75 76
lmx
.
report
=
report_lmx
77 78
-- helpers
79 80
-- the variables table is an empty one that gets linked to a defaults table
81
-- that gets passed with a creation (first time only) and that itself links
82
-- to one that gets passed to the converter
83 84
local
variables
=
{
}
-- we assume no nesting
85
local
result
=
{
}
-- we assume no nesting
86 87
local
function
do_print
(
one
,
two
,
...
)
88
if
two
then
89
result
[
#
result
+
1
]
=
concat
{
one
,
two
,
...
}
90
else
91
result
[
#
result
+
1
]
=
one
92
end
93
end
94 95
-- Although it does not make much sense for most elements, we provide a mechanism
96
-- to print wrapped content, something that is more efficient when we are constructing
97
-- tables.
98 99
local
html
=
{
}
100
lmx
.
html
=
html
101 102
function
html
.
td
(
str
)
103
if
type
(
str
)
=
=
"
table
"
then
104
for
i
=
1
,
#
str
do
-- spoils t !
105
str
[
i
]
=
format
(
"
<td>%s</td>
"
,
str
[
i
]
or
"
"
)
106
end
107
result
[
#
result
+
1
]
=
concat
(
str
)
108
else
109
result
[
#
result
+
1
]
=
format
(
"
<td>%s</td>
"
,
str
or
"
"
)
110
end
111
end
112 113
function
html
.
th
(
str
)
114
if
type
(
str
)
=
=
"
table
"
then
115
for
i
=
1
,
#
str
do
-- spoils t !
116
str
[
i
]
=
format
(
"
<th>%s</th>
"
,
str
[
i
]
)
117
end
118
result
[
#
result
+
1
]
=
concat
(
str
)
119
else
120
result
[
#
result
+
1
]
=
format
(
"
<th>%s</th>
"
,
str
or
"
"
)
121
end
122
end
123 124
function
html
.
a
(
text
,
url
)
125
result
[
#
result
+
1
]
=
format
(
"
<a href=%q>%s</a>
"
,
url
,
text
)
126
end
127 128
setmetatableindex
(
html
,
function
(
t
,
k
)
129
local
f
=
format
(
"
<%s>%%s</%s>
"
,
k
,
k
)
130
local
v
=
function
(
str
)
result
[
#
result
+
1
]
=
format
(
f
,
str
or
"
"
)
end
131
t
[
k
]
=
v
132
return
v
133
end
)
134 135
-- Loading templates:
136 137
local
function
loadedfile
(
name
)
138
name
=
resolvers
and
resolvers
.
findfile
and
resolvers
.
findfile
(
name
)
or
name
139
local
data
=
io
.
loaddata
(
name
)
140
if
not
data
or
data
=
=
"
"
then
141
report_lmx
(
"
file %a is empty
"
,
name
)
142
end
143
return
data
144
end
145 146
local
function
loadedsubfile
(
name
)
147
return
io
.
loaddata
(
resolvers
and
resolvers
.
findfile
and
resolvers
.
findfile
(
name
)
or
name
)
148
end
149 150
lmx
.
loadedfile
=
loadedfile
151 152
-- A few helpers (the next one could end up in l-lpeg):
153 154
local
usedpaths
=
{
}
155
local
givenpath
=
nil
156 157
local
do_nested_include
=
nil
158 159
local
pattern
=
lpeg
.
replacer
{
160
[
"
&
"
]
=
"
&amp;
"
,
161
[
"
>
"
]
=
"
&gt;
"
,
162
[
"
<
"
]
=
"
&lt;
"
,
163
[
'
"
'
]
=
"
&quot;
"
,
164
}
165 166
local
function
do_escape
(
str
)
167
return
lpegmatch
(
pattern
,
str
)
or
str
168
end
169 170
local
function
do_variable
(
str
)
171
local
value
=
variables
[
str
]
172
if
not
trace_variables
then
173
-- nothing
174
elseif
type
(
value
)
=
=
"
string
"
then
175
if
#
value
>
80
then
176
report_lmx
(
"
variable %a is set to: %s ...
"
,
str
,
collapsespaces
(
sub
(
value
,
1
,
80
)
)
)
177
else
178
report_lmx
(
"
variable %a is set to: %s
"
,
str
,
collapsespaces
(
value
)
)
179
end
180
elseif
type
(
value
)
=
=
"
nil
"
then
181
report_lmx
(
"
variable %a is set to: %s
"
,
str
,
"
<!-- unset -->
"
)
182
else
183
report_lmx
(
"
variable %a is set to: %S
"
,
str
,
value
)
184
end
185
if
type
(
value
)
=
=
"
function
"
then
-- obsolete ... will go away
186
return
value
(
str
)
187
else
188
return
value
189
end
190
end
191 192
local
function
do_type
(
str
)
193
if
str
and
str
~
=
"
"
then
194
result
[
#
result
+
1
]
=
format
(
"
<tt>%s</tt>
"
,
do_escape
(
str
)
)
195
end
196
end
197 198
local
function
do_fprint
(
str
,
...
)
199
if
str
and
str
~
=
"
"
then
200
result
[
#
result
+
1
]
=
format
(
str
,
...
)
201
end
202
end
203 204
local
function
do_eprint
(
str
,
...
)
205
if
str
and
str
~
=
"
"
then
206
result
[
#
result
+
1
]
=
lpegmatch
(
pattern
,
format
(
str
,
...
)
)
207
end
208
end
209 210
local
function
do_print_variable
(
str
)
211
local
str
=
do_variable
(
str
)
-- variables[str]
212
if
str
and
str
~
=
"
"
then
213
result
[
#
result
+
1
]
=
str
214
end
215
end
216 217
local
function
do_type_variable
(
str
)
218
local
str
=
do_variable
(
str
)
-- variables[str]
219
if
str
and
str
~
=
"
"
then
220
result
[
#
result
+
1
]
=
format
(
"
<tt>%s</tt>
"
,
do_escape
(
str
)
)
221
end
222
end
223 224
local
function
do_include
(
filename
,
option
)
225
local
data
=
loadedsubfile
(
filename
)
226
if
(
not
data
or
data
=
=
"
"
)
and
givenpath
then
227
data
=
loadedsubfile
(
joinpath
(
givenpath
,
filename
)
)
228
end
229
if
(
not
data
or
data
=
=
"
"
)
and
type
(
usedpaths
)
=
=
"
table
"
then
230
for
i
=
1
,
#
usedpaths
do
231
data
=
loadedsubfile
(
joinpath
(
usedpaths
[
i
]
,
filename
)
)
232
if
data
and
data
~
=
"
"
then
233
break
234
end
235
end
236
end
237
if
not
data
or
data
=
=
"
"
then
238
data
=
format
(
"
<!-- unknown lmx include file: %s -->
"
,
filename
)
239
report_lmx
(
"
include file %a is empty
"
,
filename
)
240
else
241
-- report_lmx("included file: %s",filename)
242
data
=
do_nested_include
(
data
)
243
end
244
if
filesuffix
(
filename
,
"
css
"
)
and
option
=
=
"
strip
"
then
-- new
245
data
=
lmx
.
stripcss
(
data
)
246
end
247
return
data
248
end
249 250
-- Flushers:
251 252
lmx
.
print
=
do_print
253
lmx
.
type
=
do_type
254
lmx
.
eprint
=
do_eprint
255
lmx
.
fprint
=
do_fprint
256 257
lmx
.
escape
=
do_escape
258
lmx
.
urlescape
=
url
.
escape
259
lmx
.
variable
=
do_variable
260
lmx
.
include
=
do_include
261 262
lmx
.
inject
=
do_print
263
lmx
.
finject
=
do_fprint
264
lmx
.
einject
=
do_eprint
265 266
lmx
.
pv
=
do_print_variable
267
lmx
.
tv
=
do_type_variable
268 269
-- The next functions set up the closure.
270 271
function
lmx
.
initialize
(
d
,
v
)
272
if
not
v
then
273
setmetatableindex
(
d
,
lmxvariables
)
274
if
variables
~
=
d
then
275
setmetatableindex
(
variables
,
d
)
276
if
trace_variables
then
277
report_lmx
(
"
using chain: variables => given defaults => lmx variables
"
)
278
end
279
elseif
trace_variables
then
280
report_lmx
(
"
using chain: variables == given defaults => lmx variables
"
)
281
end
282
elseif
d
~
=
v
then
283
setmetatableindex
(
v
,
d
)
284
if
d
~
=
lmxvariables
then
285
setmetatableindex
(
d
,
lmxvariables
)
286
if
variables
~
=
v
then
287
setmetatableindex
(
variables
,
v
)
288
if
trace_variables
then
289
report_lmx
(
"
using chain: variables => given variables => given defaults => lmx variables
"
)
290
end
291
elseif
trace_variables
then
292
report_lmx
(
"
using chain: variables == given variables => given defaults => lmx variables
"
)
293
end
294
else
295
if
variables
~
=
v
then
296
setmetatableindex
(
variables
,
v
)
297
if
trace_variables
then
298
report_lmx
(
"
using chain: variabes => given variables => given defaults
"
)
299
end
300
elseif
trace_variables
then
301
report_lmx
(
"
using chain: variables == given variables => given defaults
"
)
302
end
303
end
304
else
305
setmetatableindex
(
v
,
lmxvariables
)
306
if
variables
~
=
v
then
307
setmetatableindex
(
variables
,
v
)
308
if
trace_variables
then
309
report_lmx
(
"
using chain: variables => given variables => lmx variables
"
)
310
end
311
elseif
trace_variables
then
312
report_lmx
(
"
using chain: variables == given variables => lmx variables
"
)
313
end
314
end
315
result
=
{
}
316
end
317 318
function
lmx
.
finalized
(
)
319
local
collapsed
=
concat
(
result
)
320
result
=
{
}
-- free memory
321
return
collapsed
322
end
323 324
function
lmx
.
getvariables
(
)
325
return
variables
326
end
327 328
function
lmx
.
reset
(
)
329
-- obsolete
330
end
331 332
-- Creation: (todo: strip <!-- -->)
333 334
-- local template = [[
335
-- return function(defaults,variables)
336
--
337
-- -- initialize
338
--
339
-- lmx.initialize(defaults,variables)
340
--
341
-- -- interface
342
--
343
-- local definitions = { }
344
-- local variables = lmx.getvariables()
345
-- local html = lmx.html
346
-- local inject = lmx.print
347
-- local finject = lmx.fprint
348
-- local einject = lmx.eprint
349
-- local escape = lmx.escape
350
-- local verbose = lmx.type
351
--
352
-- -- shortcuts (sort of obsolete as there is no gain)
353
--
354
-- local p = lmx.print
355
-- local f = lmx.fprint
356
-- local v = lmx.variable
357
-- local e = lmx.escape
358
-- local t = lmx.type
359
-- local pv = lmx.pv
360
-- local tv = lmx.tv
361
--
362
-- -- generator
363
--
364
-- %s
365
--
366
-- -- finalize
367
--
368
-- return lmx.finalized()
369
--
370
-- end
371
-- ]]
372 373
local
template
=
[[
374-- interface 375 376local html = lmx.html 377local inject = lmx.print 378local finject = lmx.fprint -- better use the following 379local einject = lmx.eprint -- better use the following 380local injectf = lmx.fprint 381local injecte = lmx.eprint 382local injectfmt = lmx.fprint 383local injectesc = lmx.eprint 384local escape = lmx.escape 385local verbose = lmx.type 386 387local i_n_j_e_c_t = lmx.print 388 389-- shortcuts (sort of obsolete as there is no gain) 390 391local p = lmx.print 392local f = lmx.fprint 393local v = lmx.variable 394local e = lmx.escape 395local t = lmx.type 396local pv = lmx.pv 397local tv = lmx.tv 398 399local lmx_initialize = lmx.initialize 400local lmx_finalized = lmx.finalized 401local lmx_getvariables = lmx.getvariables 402 403-- generator 404 405return function(defaults,variables) 406 407 lmx_initialize(defaults,variables) 408 409 local definitions = { } 410 local variables = lmx_getvariables() 411 412 %s -- the action: appends to result 413 414 return lmx_finalized() 415 416end 417
]]
418 419
local
function
savedefinition
(
definitions
,
tag
,
content
)
420
definitions
[
tag
]
=
content
421
return
"
"
422
end
423 424
local
function
getdefinition
(
definitions
,
tag
)
425
return
definitions
[
tag
]
or
"
"
426
end
427 428
local
whitespace
=
lpeg
.
patterns
.
whitespace
429
local
optionalspaces
=
whitespace
^
0
430 431
local
dquote
=
P
(
'
"
'
)
432 433
local
begincomment
=
P
(
"
<!--
"
)
-- only makes sense when we in intercept pre|script|style
434
local
endcomment
=
P
(
"
-->
"
)
435 436
local
beginembedxml
=
P
(
"
<?
"
)
437
local
endembedxml
=
P
(
"
?>
"
)
438 439
local
beginembedcss
=
P
(
"
/*
"
)
440
local
endembedcss
=
P
(
"
*/
"
)
441 442
local
gobbledendxml
=
(
optionalspaces
*
endembedxml
)
/
"
"
443
----- argumentxml = (1-gobbledendxml)^0
444
local
argumentxml
=
(
whitespace
^
1
+
dquote
*
C
(
(
1
-
dquote
)
^
1
)
*
dquote
+
C
(
(
1
-
gobbledendxml
-
whitespace
)
^
1
)
)
^
0
445 446
local
gobbledendcss
=
(
optionalspaces
*
endembedcss
)
/
"
"
447
----- argumentcss = (1-gobbledendcss)^0
448
local
argumentcss
=
(
whitespace
^
1
+
dquote
*
C
(
(
1
-
dquote
)
^
1
)
*
dquote
+
C
(
(
1
-
gobbledendcss
-
whitespace
)
^
1
)
)
^
0
449 450
local
commentxml
=
(
begincomment
*
(
1
-
endcomment
)
^
0
*
endcomment
)
/
"
"
451 452
local
beginluaxml
=
(
beginembedxml
*
P
(
"
lua
"
)
)
/
"
"
453
local
endluaxml
=
endembedxml
/
"
"
454 455
local
luacodexml
=
beginluaxml
456
*
(
1
-
endluaxml
)
^
1
457
*
endluaxml
458 459
local
beginluacss
=
(
beginembedcss
*
P
(
"
lua
"
)
)
/
"
"
460
local
endluacss
=
endembedcss
/
"
"
461 462
local
luacodecss
=
beginluacss
463
*
(
1
-
endluacss
)
^
1
464
*
endluacss
465 466
local
othercode
=
(
1
-
beginluaxml
-
beginluacss
)
^
1
/
"
i_n_j_e_c_t[==[%0]==]
"
467 468
local
includexml
=
(
(
beginembedxml
*
P
(
"
lmx-include
"
)
*
optionalspaces
)
/
"
"
)
469
*
(
argumentxml
/
do_include
)
470
*
gobbledendxml
471 472
local
includecss
=
(
(
beginembedcss
*
P
(
"
lmx-include
"
)
*
optionalspaces
)
/
"
"
)
473
*
(
argumentcss
/
do_include
)
474
*
gobbledendcss
475 476
local
definexml_b
=
(
(
beginembedxml
*
P
(
"
lmx-define-begin
"
)
*
optionalspaces
)
/
"
"
)
477
*
argumentxml
478
*
gobbledendxml
479 480
local
definexml_e
=
(
(
beginembedxml
*
P
(
"
lmx-define-end
"
)
*
optionalspaces
)
/
"
"
)
481
*
argumentxml
482
*
gobbledendxml
483 484
local
definexml_c
=
C
(
(
1
-
definexml_e
)
^
0
)
485 486
local
definexml
=
(
Carg
(
1
)
*
C
(
definexml_b
)
*
definexml_c
*
definexml_e
)
/
savedefinition
487 488
local
resolvexml
=
(
(
beginembedxml
*
P
(
"
lmx-resolve
"
)
*
optionalspaces
)
/
"
"
)
489
*
(
(
Carg
(
1
)
*
C
(
argumentxml
)
)
/
getdefinition
)
490
*
gobbledendxml
491 492
local
definecss_b
=
(
(
beginembedcss
*
P
(
"
lmx-define-begin
"
)
*
optionalspaces
)
/
"
"
)
493
*
argumentcss
494
*
gobbledendcss
495 496
local
definecss_e
=
(
(
beginembedcss
*
P
(
"
lmx-define-end
"
)
*
optionalspaces
)
/
"
"
)
497
*
argumentcss
498
*
gobbledendcss
499 500
local
definecss_c
=
C
(
(
1
-
definecss_e
)
^
0
)
501 502
local
definecss
=
(
Carg
(
1
)
*
C
(
definecss_b
)
*
definecss_c
*
definecss_e
)
/
savedefinition
503 504
local
resolvecss
=
(
(
beginembedcss
*
P
(
"
lmx-resolve
"
)
*
optionalspaces
)
/
"
"
)
505
*
(
(
Carg
(
1
)
*
C
(
argumentcss
)
)
/
getdefinition
)
506
*
gobbledendcss
507 508
----- pattern_1 = Cs((commentxml + includexml + includecss + P(1))^0) -- get rid of xml comments asap .. not good enough: embedded css and script is in <!-- .. also <pre>
509
local
pattern_1
=
Cs
(
(
includexml
+
includecss
+
P
(
1
)
)
^
0
)
510
local
pattern_2
=
Cs
(
(
definexml
+
resolvexml
+
definecss
+
resolvecss
+
P
(
1
)
)
^
0
)
511
local
pattern_3
=
Cs
(
(
luacodexml
+
luacodecss
+
othercode
)
^
0
)
512 513
local
cache
=
{
}
514 515
local
function
lmxerror
(
str
)
516
report_error
(
str
)
517
return
html
.
tt
(
str
)
518
end
519 520
local
function
wrapper
(
converter
,
defaults
,
variables
)
521
local
outcome
,
message
=
pcall
(
converter
,
defaults
,
variables
)
522
if
not
outcome
then
523
return
lmxerror
(
format
(
"
error in conversion: %s
"
,
message
)
)
524
else
525
return
message
526
end
527
end
528 529
do_nested_include
=
function
(
data
)
-- also used in include
530
return
lpegmatch
(
pattern_1
,
data
)
531
end
532 533
local
function
lmxnew
(
data
,
defaults
,
nocache
,
path
)
-- todo: use defaults in calling routines
534
data
=
data
or
"
"
535
local
known
=
cache
[
data
]
536
if
not
known
then
537
givenpath
=
path
538
usedpaths
=
lmxvariables
.
includepath
or
{
}
539
if
type
(
usedpaths
)
=
=
"
string
"
then
540
usedpaths
=
{
usedpaths
}
541
end
542
data
=
lpegmatch
(
pattern_1
,
data
)
543
data
=
lpegmatch
(
pattern_2
,
data
,
1
,
{
}
)
544
data
=
lpegmatch
(
pattern_3
,
data
)
545
local
converted
=
loadstring
(
format
(
template
,
data
)
)
546
if
converted
then
547
converted
=
converted
(
)
548
end
549
defaults
=
defaults
or
{
}
550
local
converter
551
if
converted
then
552
converter
=
function
(
variables
)
553
return
wrapper
(
converted
,
defaults
,
variables
)
554
end
555
else
556
report_error
(
"
error in:\n%s\n:
"
,
data
)
557
converter
=
function
(
)
lmxerror
(
"
error in template
"
)
end
558
end
559
known
=
{
560
data
=
defaults
.
trace
and
data
or
"
"
,
561
variables
=
defaults
,
562
converter
=
converter
,
563
}
564
if
cache_templates
and
nocache
~
=
false
then
565
cache
[
data
]
=
known
566
end
567
elseif
variables
then
568
known
.
variables
=
variables
569
end
570
return
known
,
known
.
variables
571
end
572 573
local
function
lmxresult
(
self
,
variables
)
574
if
self
then
575
local
converter
=
self
.
converter
576
if
converter
then
577
local
converted
=
converter
(
variables
)
578
if
trace_variables
then
-- will become templates
579
report_lmx
(
"
converted size: %s
"
,
#
converted
)
580
end
581
return
converted
or
lmxerror
(
"
no result from converter
"
)
582
else
583
return
lmxerror
(
"
invalid converter
"
)
584
end
585
else
586
return
lmxerror
(
"
invalid specification
"
)
587
end
588
end
589 590
lmx
.
new
=
lmxnew
591
lmx
.
result
=
lmxresult
592 593
local
loadedfiles
=
{
}
594 595
function
lmx
.
convertstring
(
templatestring
,
variables
,
nocache
,
path
)
596
return
lmxresult
(
lmxnew
(
templatestring
,
nil
,
nocache
,
path
)
,
variables
)
597
end
598 599
function
lmx
.
convertfile
(
templatefile
,
variables
,
nocache
)
600
if
trace_variables
then
-- will become templates
601
report_lmx
(
"
converting file %a
"
,
templatefile
)
602
end
603
local
converter
=
loadedfiles
[
templatefile
]
604
if
not
converter
then
605
converter
=
lmxnew
(
loadedfile
(
templatefile
)
,
nil
,
nocache
,
pathpart
(
templatefile
)
)
606
loadedfiles
[
templatefile
]
=
converter
607
end
608
return
lmxresult
(
converter
,
variables
)
609
end
610 611
local
function
lmxconvert
(
templatefile
,
resultfile
,
variables
,
nocache
)
-- or (templatefile,variables)
612
if
trace_variables
then
-- will become templates
613
report_lmx
(
"
converting file %a
"
,
templatefile
)
614
end
615
if
not
variables
and
type
(
resultfile
)
=
=
"
table
"
then
616
variables
=
resultfile
617
end
618
local
converter
=
loadedfiles
[
templatefile
]
619
if
not
converter
then
620
converter
=
lmxnew
(
loadedfile
(
templatefile
)
,
nil
,
nocache
,
pathpart
(
templatefile
)
)
621
if
cache_files
then
622
loadedfiles
[
templatefile
]
=
converter
623
end
624
end
625
local
result
=
lmxresult
(
converter
,
variables
)
626
if
resultfile
then
627
io
.
savedata
(
resultfile
,
result
)
628
else
629
return
result
630
end
631
end
632 633
lmx
.
convert
=
lmxconvert
634 635
-- helpers
636 637
local
nocomment
=
(
beginembedcss
*
(
1
-
endembedcss
)
^
1
*
endembedcss
)
/
"
"
638
local
nowhitespace
=
whitespace
^
1
/
"
"
-- ""
639
local
semistripped
=
whitespace
^
1
/
"
"
*
P
(
"
;
"
)
640
local
stripper
=
Cs
(
(
nocomment
+
semistripped
+
nowhitespace
+
1
)
^
1
)
641 642
function
lmx
.
stripcss
(
str
)
643
return
lpegmatch
(
stripper
,
str
)
644
end
645 646
function
lmx
.
color
(
r
,
g
,
b
,
a
)
647
if
r
>
1
then
648
r
=
1
649
end
650
if
g
>
1
then
651
g
=
1
652
end
653
if
b
>
1
then
654
b
=
1
655
end
656
if
not
a
then
657
a
=
0
658
elseif
a
>
1
then
659
a
=
1
660
end
661
if
a
>
0
then
662
return
format
(
"
rgba(%s%%,%s%%,%s%%,%s)
"
,
r
*
100
,
g
*
100
,
b
*
100
,
a
)
663
else
664
return
format
(
"
rgb(%s%%,%s%%,%s%%)
"
,
r
*
100
,
g
*
100
,
b
*
100
)
665
end
666
end
667 668
-- these can be overloaded
669 670
lmx
.
lmxfile
=
string
.
itself
671
lmx
.
htmfile
=
string
.
itself
672
lmx
.
popupfile
=
os
.
launch
673 674
local
function
lmxmake
(
name
,
variables
)
675
local
lmxfile
=
lmx
.
lmxfile
(
name
)
676
local
htmfile
=
lmx
.
htmfile
(
name
)
677
if
lmxfile
=
=
htmfile
then
678
htmfile
=
replacesuffix
(
lmxfile
,
"
html
"
)
679
end
680
lmxconvert
(
lmxfile
,
htmfile
,
variables
)
681
return
htmfile
682
end
683 684
lmx
.
make
=
lmxmake
685 686
function
lmx
.
show
(
name
,
variables
)
687
-- todo: pcall
688
local
htmfile
=
lmxmake
(
name
,
variables
)
689
-- lmx.popupfile(htmfile)
690
return
htmfile
691
end
692 693
-- Command line (will become mtx-lmx):
694 695
if
arg
then
696
if
arg
[
1
]
=
=
"
--show
"
then
if
arg
[
2
]
then
lmx
.
show
(
arg
[
2
]
)
end
697
elseif
arg
[
1
]
=
=
"
--convert
"
then
if
arg
[
2
]
then
lmx
.
convert
(
arg
[
2
]
,
arg
[
3
]
or
"
temp.html
"
)
end
698
end
699
else
700
return
lmx
701
end
702 703
-- Test 1:
704 705
-- inspect(lmx.result(lmx.new(io.loaddata("t:/sources/context-timing.lmx"))))
706 707
-- Test 2:
708 709
-- local str = [[
710
-- <?lmx-include context.css strip ?>
711
-- <test>
712
-- <?lmx-define-begin whatever?>some content a<?lmx-define-end ?>
713
-- <?lmx-define-begin somemore?>some content b<?lmx-define-end ?>
714
-- <more>
715
-- <?lmx-resolve whatever ?>
716
-- <?lua
717
-- for i=1,10 do end
718
-- ?>
719
-- <?lmx-resolve somemore ?>
720
-- </more>
721
-- <td><?lua p(100) ?></td>
722
-- <td><?lua p(variables.a) ?></td>
723
-- <td><?lua p(variables.b) ?></td>
724
-- <td><?lua p(variables.c) ?></td>
725
-- <td><?lua pv('title-default') ?></td>
726
-- </test>
727
-- ]]
728 729
-- local defaults = { trace = true, a = 3, b = 3 }
730
-- local result = lmx.new(str,defaults)
731
-- inspect(result.data)
732
-- inspect(result.converter(defaults))
733
-- inspect(result.converter { a = 1 })
734
-- inspect(lmx.result(result, { b = 2 }))
735
-- inspect(lmx.result(result, { a = 20000, b = 40000 }))
736