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