diff options
Diffstat (limited to 'lua')
-rw-r--r-- | lua/compile-uff.lua | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/lua/compile-uff.lua b/lua/compile-uff.lua new file mode 100644 index 0000000..9da70b8 --- /dev/null +++ b/lua/compile-uff.lua | |||
@@ -0,0 +1,208 @@ | |||
1 | #!/usr/bin/env lua | ||
2 | -- A compiler for "Autocento of the breakfast table" by Case Duckworth | ||
3 | -- check it in action at: www.autocento.me | ||
4 | -- Usage: `lua compile.lua [options] <files> | ||
5 | -- Where [options] are | ||
6 | -- -- -html: compiles html files | ||
7 | -- -- -river: compiles river files (only words, one per line) | ||
8 | -- -- -lozenge: updates lozenge.js file | ||
9 | -- vim: fdm=indent | ||
10 | |||
11 | defaults = {} | ||
12 | defaults.dirs = { | ||
13 | root = "/d/Copy/projects/autocento/", | ||
14 | src = "/d/Copy/projects/autocento/src/", | ||
15 | lua = "/d/Copy/projects/autocento/lua/", | ||
16 | js = "/d/Copy/projects/autocento/js/", | ||
17 | css = "/d/Copy/projects/autocento/css/", | ||
18 | } | ||
19 | defaults.files = { | ||
20 | lozenge = defaults.dirs.js .. "lozenge.js", | ||
21 | } | ||
22 | defaults.formats = { | ||
23 | html = { | ||
24 | output_dir = defaults.dirs.root, | ||
25 | extension = "html", | ||
26 | pandoc_args = { | ||
27 | from = "markdown", | ||
28 | to = "html5", | ||
29 | template = ".template.html", | ||
30 | "smart", | ||
31 | "mathml", | ||
32 | "section-divs", | ||
33 | } | ||
34 | }, | ||
35 | river = { | ||
36 | output_dir = defaults.dirs.root .. "river/", | ||
37 | extension = "river", | ||
38 | pandoc_args = { | ||
39 | from = "markdown", | ||
40 | to = defaults.dirs.lua.."river.lua", | ||
41 | }, | ||
42 | }, | ||
43 | } | ||
44 | defaults.compile_args = { | ||
45 | '-html', | ||
46 | '-river', | ||
47 | '-lozenge', | ||
48 | } | ||
49 | helpers = { | ||
50 | -- Little helper functions | ||
51 | filter = function (list, filter) | ||
52 | -- Filter a list. | ||
53 | -- 1st return is list of terms that match. | ||
54 | -- 2nd return is list of terms that don't match. | ||
55 | local output_match = {} | ||
56 | local output_nomatch = {} | ||
57 | for _,v in ipairs(list) do | ||
58 | if string.match(v, filter) then | ||
59 | output_match[#output_match+1] = v | ||
60 | else | ||
61 | output_nomatch[#output_nomatch+1] = v | ||
62 | end | ||
63 | end | ||
64 | return output_match, output_nomatch | ||
65 | end, | ||
66 | in_table = function (table, term) | ||
67 | -- Search for term in table | ||
68 | for k,v in pairs(table) do | ||
69 | if v == term then | ||
70 | return k | ||
71 | end | ||
72 | end | ||
73 | return nil | ||
74 | end, | ||
75 | tsub = function (table, pattern, replace, i) | ||
76 | -- gsub on every term in a table | ||
77 | local output = {} | ||
78 | if i then -- 'i' option just does ipair part of table | ||
79 | for k,v in ipairs(table) do | ||
80 | output[k] = v:gsub(pattern, replace) | ||
81 | end | ||
82 | else | ||
83 | for k,v in pairs(table) do | ||
84 | output[k] = v:gsub(pattern, replace) | ||
85 | end | ||
86 | end | ||
87 | return output | ||
88 | end, | ||
89 | scandir = function (directory) | ||
90 | -- Find all files in a directory | ||
91 | local i, t, popen = 0, {}, io.popen | ||
92 | for filename in popen('ls -a "'..directory..'"'):lines() do | ||
93 | i = i+1 | ||
94 | t[i] = filename | ||
95 | end | ||
96 | return t | ||
97 | end | ||
98 | } | ||
99 | |||
100 | function compile (files, format_args) | ||
101 | -- Run pandoc on <files>, producing <output_format>, with [pandoc_args]. | ||
102 | local errors = 0 | ||
103 | if not format_args then | ||
104 | format_args = defaults.formats[output_format] | ||
105 | end | ||
106 | print("Compiling files to "..format_args.extension.." ...") | ||
107 | args = format_args.pandoc_args | ||
108 | for _, file in pairs(files) do | ||
109 | local pandoc_run = { | ||
110 | 'pandoc', | ||
111 | '-f', args.from, | ||
112 | '-t', args.to, | ||
113 | '-o', | ||
114 | file:gsub('%.%a+$', "."..format_args.extension) | ||
115 | } | ||
116 | if args.template then | ||
117 | table.insert(pandoc_run, '--template="'..args.template..'"') | ||
118 | end | ||
119 | for _,a in ipairs(args) do | ||
120 | pandoc_run[#pandoc_run+1] = a:gsub("^", "--") | ||
121 | end | ||
122 | table.insert(pandoc_run, file) | ||
123 | for k,v in pairs(pandoc_run) do | ||
124 | print(k, v) | ||
125 | end | ||
126 | if not os.execute(table.concat(pandoc_run, " ")) then | ||
127 | errors = errors+1 | ||
128 | end | ||
129 | io.write(".") | ||
130 | end | ||
131 | print("Compiling "..#files.." files completed with "..errors.." errors.") | ||
132 | end | ||
133 | |||
134 | function move (files, destination) | ||
135 | -- Move files to destination | ||
136 | print("Moving files to "..destination.." ...") | ||
137 | local errors = 0 | ||
138 | for _, file in pairs(files) do | ||
139 | if not os.execute("mv "..file.." "..destination) then | ||
140 | errors = errors+1 | ||
141 | end | ||
142 | end | ||
143 | print("Moving "..#files.." completed with "..errors.." errors.") | ||
144 | end | ||
145 | |||
146 | function lozenge_list (files, blacklist) | ||
147 | -- Produce list for placement in lozenge.js | ||
148 | local output = {} | ||
149 | for _,file in pairs(files) do | ||
150 | -- table.insert(output, #output+1, file:gsub('.*', '"%0"')) | ||
151 | output[#output+1] = file:gsub(".*", '"%0",') | ||
152 | end | ||
153 | if blacklist then | ||
154 | for _,unwanted in pairs(blacklist) do | ||
155 | _,output = helpers.filter(files, unwanted) | ||
156 | end | ||
157 | end | ||
158 | output = table.concat(output, " ") | ||
159 | output = "var files = ["..output | ||
160 | output = output:gsub('"",', '') | ||
161 | output = output:gsub(",$", "]") | ||
162 | print(output) | ||
163 | end | ||
164 | |||
165 | local args, files = helpers.filter(arg, "^%-") | ||
166 | if not files or #files == 0 then | ||
167 | -- Error: need files to work on! | ||
168 | -- TODO: don't technically need file list for -lozenge | ||
169 | print("ERROR: No file list.") | ||
170 | os.exit(1) | ||
171 | end | ||
172 | basenames = helpers.tsub(files, "^.*/", "") | ||
173 | basenames = helpers.tsub(files, "%.%a+$", "") | ||
174 | if not args or #args == 0 or args == { "-all" } then | ||
175 | args = defaults.compile_args | ||
176 | end | ||
177 | -- Option parsing | ||
178 | if helpers.in_table(args, "-html") then | ||
179 | compile(files, defaults.formats.html) | ||
180 | move(helpers.tsub(basenames, "$", "%0.html"), | ||
181 | defaults.formats.html.output_dir) | ||
182 | end | ||
183 | if helpers.in_table(args, "-river") then | ||
184 | compile(files, defaults.formats.river) | ||
185 | move(helpers.tsub(basenames, ".*", "%0.river"), | ||
186 | defaults.formats.river.output_dir) | ||
187 | end | ||
188 | if helpers.in_table(args, "-lozenge") then | ||
189 | -- TODO: should probably break this out into a function | ||
190 | print("Updating lozenge.js file list...") | ||
191 | local htmls = helpers.filter(helpers.scandir(defaults.dirs.root), | ||
192 | "html$") | ||
193 | local f = assert(io.open(defaults.files.lozenge, "r")) | ||
194 | local buffer = {} | ||
195 | for line in f:lines() do | ||
196 | if line:find("var files=") then | ||
197 | table.insert(buffer, lozenge_list(htmls)) | ||
198 | else | ||
199 | table.insert(buffer, line) | ||
200 | end | ||
201 | end | ||
202 | f:close() | ||
203 | -- Write the file we've just read | ||
204 | local F = assert(io.open(defaults.files.lozenge, "w")) | ||
205 | F:write(table.concat(buffer, "\n")) | ||
206 | F:close() | ||
207 | print("Done.") | ||
208 | end | ||