handlers/render.lua

changeset 3
b2df1b3f2c83
parent 2
3975fa5ed630
child 4
4cb0d1dbc65b
--- a/handlers/render.lua	Sat Sep 12 21:27:57 2009 +0300
+++ b/handlers/render.lua	Sun Sep 13 22:22:47 2009 +0300
@@ -1,25 +1,23 @@
 
 module("handlers.render", package.seeall)
 
+local ltp=require('ltp.template')
 require('markdown')
-require('etree')
-require('err')
-require('environment')
 require('config')
+require('path')
+require('filecache')
+require('log')
 
 --
 -- Phase 1: load & markup
 --
 
-local phase1_cache={}
-
 function phase1(file, env)
-    --local dir = string.match(file, "(.*)/[^/]*")
-    --local env = get_environment(dir)
-    local f = io.open(file, 'r')
-    local data = ''
+    local f = io.open(path.join(env.paths.src, file), 'r')
+    local data = nil
     local in_meta = false
     local linenum=1
+    local meta = {}
     
     for l in f:lines() do
         if string.match(l, config.meta_marker) then
@@ -27,78 +25,102 @@
         elseif in_meta then
             local key, val = string.match(l, "%s*([^:]*)%s*:%s*(.*)%s*")
             if key and val then
-                env[key] = val
+                -- very primitive quoting, primarily as a hack to
+                -- not need converting my files that much from Webgen.
+                local val_unq=string.match(val, '^"(.*)"$')
+                meta[key] = val_unq or val
             else
                 err.file_pos(file, linenum, "meta data syntax error")
             end
         else
-            data = data.."\n"..l
+            if data then
+                data = data.."\n"..l
+            elseif not string.match(l, "%s") then
+                data=l
+            end
         end
         linenum = linenum+1
     end
     
+    log.log("Load "..file.."\n")
+    
     f:close()
 
-    local data2=markdown(data)
+    local destination
+    if meta.destination then
+        destination=path.join(path.dirname(file), meta.destination)
+    else
+        destination=path.rmext(file)
+    end
+
+    local page={
+        data=data,
+        meta=meta,
+        destination=destination,
+        file=file,
+    }
     
-    phase1_cache[file]=data2
+    env.pages[file]=page
 end
 
-
---
--- Phase 2: Tag processing
---
-
--- Vaiko silti toistepäin? Inlinejen tagit pitää
--- prosessoida ennen inlinetystä. Mutta toisaalta
--- templateen myös prosessointi.
-
-local function tag_lgen_inline(env, t)
-    a.tag="div"
-    -- todo: get inlineable stuff from attrs
-    a.attr.class="lgen:inline"
-    --table.insert(a, get_inline(env, a)
+function process_lua(template, env)
+    env=table.join(env, {env=env}) -- TODO: should use __index
+    --return ltp.render(nil, 1, template, env, {}, "<%", "%>", {})
+    return ltp.render_template(template, "<%", "%>", 
+                               ltp.merge_index(env, _G))
 end
 
-local function tag_lgen_a(env, t)
+function env_for(file, env, path_prefix)
+    local newenv=table.copy(env)
+    
+    newenv.base_url=path.to_root(file)
+    newenv.path_prefix=(path_prefix or "")
+    newenv.page=env.pages[file]
+    
+    return newenv
 end
 
-
-local operations={
-    ["lgen:inline"] = tag_lgen_inline,
-    ["a"] = tag_lgen_a,
-}
-
-local function scan(env, et)
-    for _, v in ipairs(et) do
-        if type(v)=="table" then
-            operations[v.tag](env, v)
-        end
+function render(file, env, path_prefix)
+    local data=env.pages[file].data
+    if data then
+        local newenv=env_for(file, env, path_prefix)
+        local data2=process_lua(data, newenv)
+        return markdown(data2)
     end
 end
 
-setmetatable(operations, { __index = function() return scan end })
-
 function phase2(file, env)
-    local data=phase1_cache[file]
-    --print(data)
-    --print("----------")
-    local et, msg, line, col, pos = etree.fromstring([[<!DOCTYPE html
-    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><body>]]..data..'</body></html>')
-    --local et, msg, line, col, pos = lom.parse("<foo>"..data.."</foo>")
-    if not et then
-        error(string.format("%d:%d(%d): %s", line or -1 , col or -1, pos or -1, msg))
+    local page=env.pages[file]
+    local src = path.join(env.paths.src, file)
+    local dst = path.join(env.paths.dst, page.destination)
+    local tmpl = path.join(env.paths.tmpl,
+                           page.meta.template or "page.template")
+    local deps = {src}
+    
+    local build=page.meta.always_build
+    if not build then
+        if page.meta.dependencies then
+            for p, _ in pairs(env.pages) do
+                if string.match(page.meta.dependencies, p) then
+                    table.insert(deps, path.join(env.paths.src, p))
+                end
+            end
+        end
+        table.insert(deps, tmpl)
+        build=dependency.simple_update_check(dst, deps)
     end
     
-    operations[et.tag](env, et)
-    
-    -- TODO: inlining
-    -- maybe
-    --phase2_cache[file]=etree.tostring(et);
+    if build then 
+        log.log("Render "..file.."\n")
+        local content=render(file, env)
+        local page_template=filecache.get(tmpl)
+
+        local newenv=table.join({content=content}, env_for(file, env))
+        local data2=process_lua(page_template, newenv)
+        
+        log.log("Write "..page.destination.."\n")
+        local f=io.openX(dst, "w")
+        f:write(data2)
+    end
 end
 
-
-
-function phase3(file, env)
-end

mercurial