about summary refs log tree commit diff stats
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/compile-uff.lua208
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
11defaults = {}
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 }
49helpers = {
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
100function 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.")
132end
133
134function 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.")
144end
145
146function 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)
163end
164
165local args, files = helpers.filter(arg, "^%-")
166if 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)
171end
172basenames = helpers.tsub(files, "^.*/", "")
173basenames = helpers.tsub(files, "%.%a+$", "")
174if not args or #args == 0 or args == { "-all" } then
175 args = defaults.compile_args
176end
177-- Option parsing
178if 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)
182end
183if 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)
187end
188if 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.")
208end