| 1 |
1 |
| 2 module("handlers.render", package.seeall) |
2 module("handlers.render", package.seeall) |
| 3 |
3 |
| |
4 local ltp=require('ltp.template') |
| 4 require('markdown') |
5 require('markdown') |
| 5 require('etree') |
|
| 6 require('err') |
|
| 7 require('environment') |
|
| 8 require('config') |
6 require('config') |
| |
7 require('path') |
| |
8 require('filecache') |
| |
9 require('log') |
| 9 |
10 |
| 10 -- |
11 -- |
| 11 -- Phase 1: load & markup |
12 -- Phase 1: load & markup |
| 12 -- |
13 -- |
| 13 |
14 |
| 14 local phase1_cache={} |
|
| 15 |
|
| 16 function phase1(file, env) |
15 function phase1(file, env) |
| 17 --local dir = string.match(file, "(.*)/[^/]*") |
16 local f = io.open(path.join(env.paths.src, file), 'r') |
| 18 --local env = get_environment(dir) |
17 local data = nil |
| 19 local f = io.open(file, 'r') |
|
| 20 local data = '' |
|
| 21 local in_meta = false |
18 local in_meta = false |
| 22 local linenum=1 |
19 local linenum=1 |
| |
20 local meta = {} |
| 23 |
21 |
| 24 for l in f:lines() do |
22 for l in f:lines() do |
| 25 if string.match(l, config.meta_marker) then |
23 if string.match(l, config.meta_marker) then |
| 26 in_meta = not in_meta |
24 in_meta = not in_meta |
| 27 elseif in_meta then |
25 elseif in_meta then |
| 28 local key, val = string.match(l, "%s*([^:]*)%s*:%s*(.*)%s*") |
26 local key, val = string.match(l, "%s*([^:]*)%s*:%s*(.*)%s*") |
| 29 if key and val then |
27 if key and val then |
| 30 env[key] = val |
28 -- very primitive quoting, primarily as a hack to |
| |
29 -- not need converting my files that much from Webgen. |
| |
30 local val_unq=string.match(val, '^"(.*)"$') |
| |
31 meta[key] = val_unq or val |
| 31 else |
32 else |
| 32 err.file_pos(file, linenum, "meta data syntax error") |
33 err.file_pos(file, linenum, "meta data syntax error") |
| 33 end |
34 end |
| 34 else |
35 else |
| 35 data = data.."\n"..l |
36 if data then |
| |
37 data = data.."\n"..l |
| |
38 elseif not string.match(l, "%s") then |
| |
39 data=l |
| |
40 end |
| 36 end |
41 end |
| 37 linenum = linenum+1 |
42 linenum = linenum+1 |
| 38 end |
43 end |
| 39 |
44 |
| |
45 log.log("Load "..file.."\n") |
| |
46 |
| 40 f:close() |
47 f:close() |
| 41 |
48 |
| 42 local data2=markdown(data) |
49 local destination |
| |
50 if meta.destination then |
| |
51 destination=path.join(path.dirname(file), meta.destination) |
| |
52 else |
| |
53 destination=path.rmext(file) |
| |
54 end |
| |
55 |
| |
56 local page={ |
| |
57 data=data, |
| |
58 meta=meta, |
| |
59 destination=destination, |
| |
60 file=file, |
| |
61 } |
| 43 |
62 |
| 44 phase1_cache[file]=data2 |
63 env.pages[file]=page |
| 45 end |
64 end |
| 46 |
65 |
| 47 |
66 function process_lua(template, env) |
| 48 -- |
67 env=table.join(env, {env=env}) -- TODO: should use __index |
| 49 -- Phase 2: Tag processing |
68 --return ltp.render(nil, 1, template, env, {}, "<%", "%>", {}) |
| 50 -- |
69 return ltp.render_template(template, "<%", "%>", |
| 51 |
70 ltp.merge_index(env, _G)) |
| 52 -- Vaiko silti toistepäin? Inlinejen tagit pitää |
|
| 53 -- prosessoida ennen inlinetystä. Mutta toisaalta |
|
| 54 -- templateen myös prosessointi. |
|
| 55 |
|
| 56 local function tag_lgen_inline(env, t) |
|
| 57 a.tag="div" |
|
| 58 -- todo: get inlineable stuff from attrs |
|
| 59 a.attr.class="lgen:inline" |
|
| 60 --table.insert(a, get_inline(env, a) |
|
| 61 end |
71 end |
| 62 |
72 |
| 63 local function tag_lgen_a(env, t) |
73 function env_for(file, env, path_prefix) |
| |
74 local newenv=table.copy(env) |
| |
75 |
| |
76 newenv.base_url=path.to_root(file) |
| |
77 newenv.path_prefix=(path_prefix or "") |
| |
78 newenv.page=env.pages[file] |
| |
79 |
| |
80 return newenv |
| 64 end |
81 end |
| 65 |
82 |
| 66 |
83 function render(file, env, path_prefix) |
| 67 local operations={ |
84 local data=env.pages[file].data |
| 68 ["lgen:inline"] = tag_lgen_inline, |
85 if data then |
| 69 ["a"] = tag_lgen_a, |
86 local newenv=env_for(file, env, path_prefix) |
| 70 } |
87 local data2=process_lua(data, newenv) |
| 71 |
88 return markdown(data2) |
| 72 local function scan(env, et) |
|
| 73 for _, v in ipairs(et) do |
|
| 74 if type(v)=="table" then |
|
| 75 operations[v.tag](env, v) |
|
| 76 end |
|
| 77 end |
89 end |
| 78 end |
90 end |
| 79 |
91 |
| 80 setmetatable(operations, { __index = function() return scan end }) |
|
| 81 |
|
| 82 function phase2(file, env) |
92 function phase2(file, env) |
| 83 local data=phase1_cache[file] |
93 local page=env.pages[file] |
| 84 --print(data) |
94 local src = path.join(env.paths.src, file) |
| 85 --print("----------") |
95 local dst = path.join(env.paths.dst, page.destination) |
| 86 local et, msg, line, col, pos = etree.fromstring([[<!DOCTYPE html |
96 local tmpl = path.join(env.paths.tmpl, |
| 87 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
97 page.meta.template or "page.template") |
| 88 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><body>]]..data..'</body></html>') |
98 local deps = {src} |
| 89 --local et, msg, line, col, pos = lom.parse("<foo>"..data.."</foo>") |
99 |
| 90 if not et then |
100 local build=page.meta.always_build |
| 91 error(string.format("%d:%d(%d): %s", line or -1 , col or -1, pos or -1, msg)) |
101 if not build then |
| |
102 if page.meta.dependencies then |
| |
103 for p, _ in pairs(env.pages) do |
| |
104 if string.match(page.meta.dependencies, p) then |
| |
105 table.insert(deps, path.join(env.paths.src, p)) |
| |
106 end |
| |
107 end |
| |
108 end |
| |
109 table.insert(deps, tmpl) |
| |
110 build=dependency.simple_update_check(dst, deps) |
| 92 end |
111 end |
| 93 |
112 |
| 94 operations[et.tag](env, et) |
113 if build then |
| 95 |
114 log.log("Render "..file.."\n") |
| 96 -- TODO: inlining |
115 local content=render(file, env) |
| 97 -- maybe |
116 local page_template=filecache.get(tmpl) |
| 98 --phase2_cache[file]=etree.tostring(et); |
117 |
| |
118 local newenv=table.join({content=content}, env_for(file, env)) |
| |
119 local data2=process_lua(page_template, newenv) |
| |
120 |
| |
121 log.log("Write "..page.destination.."\n") |
| |
122 local f=io.openX(dst, "w") |
| |
123 f:write(data2) |
| |
124 end |
| 99 end |
125 end |
| 100 |
126 |
| 101 |
|
| 102 |
|
| 103 function phase3(file, env) |
|
| 104 end |
|