handlers/render.lua

changeset 46
86950ef7dbcb
parent 42
260f867d46c0
equal deleted inserted replaced
45:25ba15b1982a 46:86950ef7dbcb
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

mercurial