handlers/render.lua

Sun, 06 Sep 2020 22:12:52 +0300

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 06 Sep 2020 22:12:52 +0300
changeset 35
2f927eae429b
parent 30
3ac53da03439
child 42
260f867d46c0
permissions
-rwxr-xr-x

Don't auto-create directories that will be empty

2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
2 --@module handlers.render
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
3
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
4 local handlers_render={}
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
6 local ltp=require('ltp.template')
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
7 local markdown=require('markdown')
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
8 local config=require('config')
26
77cd7b8fb6a6 Rename path.lua mypath.lua not conflict with other lua path modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 25
diff changeset
9 local path=require('mypath')
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
10 local filecache=require('filecache')
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
11 local log=require('log')
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
12 local dependency=require('dependency')
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
13 local pandoc=require('pandoc')
21
3c71c525cec2 Use markdown-it as default markdown parser.
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
14 local markdown_it=require('markdown_it')
22
8c8e70569d81 Add missing error handler loading
Tuomo Valkonen <tuomov@iki.fi>
parents: 21
diff changeset
15 local err=require('err')
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 --
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 -- Phase 1: load & markup
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 --
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
21 function handlers_render.phase1(file, env)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
22 local f = io.open(path.join(env.paths.src, file), 'r')
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
23 local data = nil
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 local in_meta = false
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 local linenum=1
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
26 local meta = {}
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 for l in f:lines() do
23
0ea4b0786b43 Only parse metadata if starts on first line
Tuomo Valkonen <tuomov@iki.fi>
parents: 22
diff changeset
29 if (linenum==1 or in_meta) and string.match(l, config.meta_marker) then
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 in_meta = not in_meta
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 elseif in_meta then
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 local key, val = string.match(l, "%s*([^:]*)%s*:%s*(.*)%s*")
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 if key and val then
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
34 -- very primitive quoting, primarily as a hack to
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
35 -- not need converting my files that much from Webgen.
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
36 local val_unq=string.match(val, '^"(.*)"$')
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
37 meta[key] = val_unq or val
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 else
23
0ea4b0786b43 Only parse metadata if starts on first line
Tuomo Valkonen <tuomov@iki.fi>
parents: 22
diff changeset
39 err.file_pos(file, linenum, "meta data syntax error: " .. l)
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 else
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
42 if data then
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
43 data = data.."\n"..l
29
Tuomo Valkonen <tuomov@iki.fi>
parents: 26
diff changeset
44 else
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
45 data=l
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
46 end
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 linenum = linenum+1
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
51 log.log("Load "..file.."\n")
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
52
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 f:close()
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
55 local destination
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
56 if meta.destination then
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
57 destination=path.join(path.dirname(file), meta.destination)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
58 else
25
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
59 -- If the file has two extensions, then only remove last extension.
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
60 -- Otherwise replace extension with .html.
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
61 destination=path.rmext(file)
25
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
62 base=path.rmext(destination)
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
63 if base==destination then
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
64 destination = destination .. ".html"
11ae9103f59d Destination name creation changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 23
diff changeset
65 end
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
66 end
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
67
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
68 local page={
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
69 data=data,
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
70 meta=meta,
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
71 destination=destination,
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
72 file=file,
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
73 }
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
75 env.pages[file]=page
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
78 function handlers_render.process_lua(template, env)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
79 env=table.join(env, {env=env}) -- TODO: should use __index
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
80 --return ltp.render(nil, 1, template, env, {}, "<%", "%>", {})
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
81 return ltp.render_template(template, "<%", "%>",
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
82 ltp.merge_index(env, _G))
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
85 function handlers_render.env_for(file, env, path_prefix)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
86 local newenv=table.copy(env)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
87
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
88 newenv.base_url=path.to_root(file)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
89 newenv.path_prefix=(path_prefix or "")
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
90 newenv.page=env.pages[file]
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
91
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
92 return newenv
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94
30
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
95 function handlers_render.render(file, env, path_prefix, renderer)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
96 local data=env.pages[file].data
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
97 if data then
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
98 local newenv=handlers_render.env_for(file, env, path_prefix)
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
99 local data2=handlers_render.process_lua(data, newenv)
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
100 meta = env.pages[file].meta
21
3c71c525cec2 Use markdown-it as default markdown parser.
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
101 if renderer == "markdown-it" then
3c71c525cec2 Use markdown-it as default markdown parser.
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
102 return markdown_it.markdown(data2, env)
3c71c525cec2 Use markdown-it as default markdown parser.
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
103 elseif renderer == "pandoc" then
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
104 return pandoc.pandoc(data2)
21
3c71c525cec2 Use markdown-it as default markdown parser.
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
105 elseif renderer == "lua-markdown" then
15
82d254b8f01e added markdown: true/false meta-tag
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
106 return markdown(data2)
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
107 elseif renderer == "none" then
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
108 return data2
15
82d254b8f01e added markdown: true/false meta-tag
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
109 else
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
110 error('Unknown renderer')
15
82d254b8f01e added markdown: true/false meta-tag
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
111 end
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
115 function handlers_render.phase2(file, env)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
116 local page=env.pages[file]
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
117 local src = path.join(env.paths.src, file)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
118 local dst = path.join(env.paths.dst, page.destination)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
119 local tmpl = path.join(env.paths.tmpl,
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
120 page.meta.template or "page.template")
30
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
121 renderer = page.meta.renderer or "markdown-it"
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
122
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
123 local deps = {src}
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
124
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
125 local build=page.meta.always_build
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
126 if not build then
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
127 if page.meta.dependencies then
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
128 for p, _ in pairs(env.pages) do
4
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
129 if string.match(p, page.meta.dependencies) then
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
130 table.insert(deps, path.join(env.paths.src, p))
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
131 end
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
132 end
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
133 end
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
134 table.insert(deps, tmpl)
30
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
135 if renderer=="markdown-it" then
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
136 markdown_it.add_deps(deps, env)
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
137 end
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
138 build=dependency.simple_update_check(dst, deps)
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140
16
e377590e9b19 Support Pandoc rendering
Tuomo Valkonen <tuomov@iki.fi>
parents: 15
diff changeset
141 if build then
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
142 log.log("Render "..file.."\n")
30
3ac53da03439 Support loading TEMPLATE_PATH/katex_config.json.
Tuomo Valkonen <tuomov@iki.fi>
parents: 29
diff changeset
143 local content=handlers_render.render(file, env, page.meta, renderer)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
144 local page_template=filecache.get(tmpl)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
145
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
146 local newenv=table.join({content=content}, handlers_render.env_for(file, env))
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
147 local data2=handlers_render.process_lua(page_template, newenv)
3
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
148
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
149 log.log("Write "..page.destination.."\n")
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
150 local f=io.openX(dst, "w")
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
151 f:write(data2)
b2df1b3f2c83 Improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
152 end
2
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 end
3975fa5ed630 (don't know)
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154
7
038275cd92ed Convert module stuff to lua 5.3
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
155 return handlers_render

mercurial