1
+ -- TODO: this has to go
2
+ local preamble = [[
3
+ \usetikzlibrary{3d,arrows,arrows.spaced,arrows.meta,bending,babel,calc,
4
+ fit,patterns,plotmarks,shapes.geometric,shapes.misc,shapes.symbols,
5
+ shapes.arrows,shapes.callouts,shapes.multipart,shapes.gates.logic.US,
6
+ shapes.gates.logic.IEC,circuits.logic.US,circuits.logic.IEC,
7
+ circuits.logic.CDH,circuits.ee.IEC,datavisualization,
8
+ datavisualization.polar,datavisualization.formats.functions,er,automata,
9
+ backgrounds,chains,topaths,trees,petri,mindmap,matrix,calendar,folding,
10
+ fadings,shadings,spy,through,turtle,positioning,scopes,
11
+ decorations.fractals,decorations.shapes,decorations.text,
12
+ decorations.pathmorphing,decorations.pathreplacing,decorations.footprints,
13
+ decorations.markings,shadows,lindenmayersystems,intersections,
14
+ fixedpointarithmetic,fpu,svg.path,external,graphs,graphs.standard,quotes,
15
+ math,angles,views,animations,rdf,perspective}
16
+ \usetikzlibrary{graphdrawing}
17
+ \usegdlibrary{trees,circular,layered,examples,force,phylogenetics,routing}
18
+ ]]
19
+
1
20
local lfs = require (" lfs" )
2
- local lpeg = require " lpeg"
21
+ local lpeg = require ( " lpeg" )
3
22
local C , Cf , Cg , Ct , P , S , V = lpeg .C , lpeg .Cf , lpeg .Cg , lpeg .Ct , lpeg .P , lpeg .S , lpeg .V
4
23
5
24
-- strip leading and trailing whitespace
6
25
local function strip (str )
7
26
return str :match " ^%s*(.-)%s*$"
8
27
end
28
+ -- strip braces
29
+ local function strip_braces (str )
30
+ return str :match " ^{?(.-)}?$"
31
+ end
9
32
10
33
-- optional whitespace
11
34
local ws = S " \t\n\r " ^ 0
@@ -21,14 +44,14 @@ local function set(t,k,v)
21
44
-- strip whitespace from keys
22
45
k = strip (k )
23
46
-- if the value is empty, set it to invalid character
24
- v = v or invalid
47
+ v = v and strip_braces ( v ) or invalid
25
48
return rawset (t ,k ,v )
26
49
end
27
50
28
51
-- Grammar to extract code examples
29
52
local extractor = lpeg .P {" document" ,
30
53
name =
31
- C ((1 - S " ]=" )^ 1 ),
54
+ C ((1 - S " , ]=" )^ 1 ),
32
55
33
56
pair =
34
57
Cg (V " name" * (lit " =" * V " braces" )^ 0 ) * lit " ," ^- 1 ,
@@ -78,42 +101,63 @@ local basename = function(file)
78
101
end
79
102
80
103
-- Main loop
81
- sourcedir = " text-en/"
82
- targetdir = " /tmp/"
104
+ if # arg ~= 2 then
105
+ print (" Usage: " .. arg [- 1 ] .. " " .. arg [0 ] .. " <source-dir> <target-dir>" )
106
+ os.exit (1 )
107
+ end
108
+ local pathsep = package.config :sub (1 ,1 )
109
+ sourcedir = arg [1 ] .. pathsep
110
+ targetdir = arg [2 ] .. pathsep
111
+ assert (lfs .attributes (sourcedir , " mode" ) == " directory" , sourcedir .. " is not a directory" )
112
+ assert (lfs .attributes (targetdir , " mode" ) == " directory" , targetdir .. " is not a directory" )
83
113
84
114
for file in lfs .dir (sourcedir ) do
85
115
if lfs .attributes (sourcedir .. file , " mode" ) == " file" then
116
+ print (" Processing " .. file )
117
+
86
118
-- Read file into memory
87
119
local f = io.open (sourcedir .. file )
88
120
local text = f :read (" *all" )
89
121
f :close ()
90
122
local name , ext = basename (file )
91
123
124
+ -- preprocess, strip all commented lines
125
+ text = text :gsub (" \n %%[^\n ]*\n " ," " )
126
+
92
127
-- extract all code examples
93
128
local matches = extractor :match (text ) or {}
94
129
95
130
-- write code examples to separate files
131
+ local setup_code = " "
96
132
for n , e in ipairs (matches ) do
97
133
local options = e [1 ]
98
134
local content = e [2 ]
99
135
136
+ -- If the snippet is marked as setup code, we have to put it before
137
+ -- every other snippet in the same file
138
+ if options [" setup code" ] then
139
+ setup_code = setup_code .. strip (content ) .. " \n "
140
+ end
141
+
100
142
-- Skip those that say "code only"
101
143
if not options [" code only" ] then
102
144
local newname = name .. " -" .. n .. " ." .. ext
103
-
104
145
local examplefile = io.open (targetdir .. newname , " w" )
105
146
106
- -- TODO: Use options to convert to MWE
107
- examplefile :write (" ===Options===\n " )
108
- for key , value in pairs (options ) do
109
- examplefile :write (key )
110
- if value ~= invalid then
111
- examplefile :write (" =" .. value )
112
- end
113
- examplefile :write (" \n " )
147
+ examplefile :write " \\ documentclass{article}\n "
148
+ examplefile :write " \\ usepackage{fp,pgf,tikz,xcolor}\n "
149
+ examplefile :write (preamble )
150
+ examplefile :write " \\ begin{document}\n "
151
+ examplefile :write " \\ makeatletter\n " -- TODO: this has to go
152
+ examplefile :write (setup_code )
153
+ examplefile :write (options [" pre" ] and options [" pre" ] .. " \n " or " " )
154
+ if options [" render instead" ] then
155
+ examplefile :write (options [" render instead" ] .. " \n " )
156
+ else
157
+ examplefile :write (strip (content ) .. " \n " )
114
158
end
115
- examplefile :write (" ===Content=== \n " )
116
- examplefile :write ( strip ( content ))
159
+ examplefile :write (options [ " post " ] and options [ " post " ] .. " \n " or " " )
160
+ examplefile :write " \\ end{document} \n "
117
161
118
162
examplefile :close ()
119
163
end
0 commit comments