UVLDoc: Rendering optimizations and CSS style
[project/luci.git] / libs / uvldoc / luasrc / uvldoc / renderer.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14 ]]--
15
16 local io = require "io"
17 local fs = require "luci.fs"
18 local uvl = require "luci.uvl"
19 local util = require "luci.util"
20 local ltn12 = require "luci.ltn12"
21 local template = require "luci.template"
22
23 local ipairs, getfenv, pairs, require, unpack = ipairs, getfenv, pairs, require, unpack
24 local luci = luci
25
26 module "luci.uvldoc.renderer"
27
28
29 Generator = util.class()
30
31 function Generator.__init__(self, schemes, output, uvlpath)
32         self.names   = schemes
33         self.output  = output or "doc"
34         self.schemes = {}
35         self.uvl     = uvl.UVL()
36         
37         self.extension = ".xml"
38         self.additionals = {"uvldoc.css"}
39         self.sourcedir = util.libpath() .. "/uvldoc/proto/xhtml/"
40 end
41
42
43 function Generator.make(self)
44         for i, scheme in ipairs(self.names) do
45                 self.schemes[scheme] = self.uvl:get_scheme(scheme)
46         end
47
48         fs.mkdir(self.output)
49
50         for i, file in ipairs(self.additionals) do
51                 fs.copy(self.sourcedir .. file, self.output .. "/" .. file)
52         end
53
54         template.compiler_mode = "memory"
55         template.viewdir = self.sourcedir
56         template.context.viewns = {
57                 include = function(name) template.Template(name):render(getfenv(2)) end,
58                 pairs = pairs,
59                 ipairs = ipairs,
60                 unpack = unpack,
61                 luci = luci,
62                 require = require
63         }
64
65         self:_make_index()
66
67         for scheme, package in pairs(self.schemes) do
68                 self:_make_package(scheme)
69                 for type, section in pairs(package.sections) do
70                         self:_make_section(scheme, type)
71                 end
72         end
73 end
74
75 function Generator._make_index(self)
76         local t = template.Template("index.xml")
77         local sink = ltn12.sink.file(
78                 io.open(self.output .. "/" .. self:_index_filename(), "w")
79         )
80         t:render({self = self, write = sink})
81         sink()
82 end
83
84 function Generator._make_package(self, scheme)
85         local t = template.Template("scheme.xml")
86         local sink = ltn12.sink.file(
87                 io.open(self.output .. "/" .. self:_scheme_filename(scheme), "w")
88         )
89         t:render({self = self, package = self.schemes[scheme], scheme = scheme, write = sink})
90         sink()
91 end
92
93 function Generator._make_section(self, scheme, section)
94         local t = template.Template("section.xml")
95         local sink = ltn12.sink.file(
96                 io.open(self.output .. "/" .. self:_section_filename(scheme, section), "w")
97         )
98         local pkg = self.schemes[scheme]
99         t:render({self = self, package = pkg,
100                 scheme = scheme, type=section, section=pkg.sections[section],
101                 write = sink})
102         sink()
103 end
104
105 function Generator._index_filename(self)
106         return "index%s" % self.extension
107 end
108
109 function Generator._scheme_filename(self, scheme)
110         return "scheme.%s%s" % {scheme, self.extension}
111 end
112
113 function Generator._section_filename(self, scheme, section)
114         if self.schemes[scheme] and self.schemes[scheme].sections[section] then
115                 return "section.%s.%s%s" % {scheme, section, self.extension}
116         end
117 end
118
119 function Generator._variable_target(self, scheme, section, variable)
120         if self.schemes[scheme] and self.schemes[scheme].variables[section] and
121          self.schemes[scheme].variables[section][variable] then
122                 return "section.%s.%s%s#variable.%s" % {scheme, section, self.extension, variable}
123         end
124 end