trac-exp.lua /size: 9370 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['trac-exp'] = {
2    version   = 1.001,
3    comment   = "companion to trac-log.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local formatters   = string.formatters
10local reporters    = logs.reporters
11local xmlserialize = xml.serialize
12local xmlcollected = xml.collected
13local xmltext      = xml.text
14local xmlfirst     = xml.first
15local xmlfilter    = xml.filter
16
17-- there is no need for a newhandlers { name = "help", parent = "string" }
18
19local function flagdata(flag)
20    local name  = flag.at.name or ""
21    local value = flag.at.value or ""
22 -- local short = xmlfirst(s,"/short")
23 -- local short = xmlserialize(short,xs)
24    local short = xmltext(xmlfirst(flag,"/short")) or ""
25    return name, value, short
26end
27
28local function exampledata(example)
29    local command = xmltext(xmlfirst(example,"/command")) or ""
30    local comment = xmltext(xmlfirst(example,"/comment")) or ""
31    return command, comment
32end
33
34local function categorytitle(category)
35    return xmltext(xmlfirst(category,"/title")) or ""
36end
37
38local exporters = logs.exporters
39
40function exporters.man(specification,...)
41    local root = xml.convert(specification.helpinfo or "")
42    if not root then
43        return
44    end
45    local xs = xml.gethandlers("string")
46    xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
47    xml.sethandlersfunction(xs,"ref",  function(e,handler) handler.handle("--"..e.at.name) end)
48    local wantedcategories = select("#",...) == 0 and true or table.tohash { ... }
49    local nofcategories = xml.count(root,"/application/flags/category")
50    local name    = xmlfilter(root,"/application/metadata/entry[@name='name']/text()")
51    local detail  = xmlfilter(root,"/application/metadata/entry[@name='detail']/text()") or name
52    local version = xmlfilter(root,"/application/metadata/entry[@name='version']/text()") or "0.00"
53    local banner  = specification.banner or detail or name
54    --
55    local result = { }
56    --
57    -- .TH "context" "1" "some date" "version" "ConTeXt" -- we use a fake date as I don't want to polute the git repos
58    --
59    local runner = string.match(name,"^mtx%-(.*)")
60    if runner then
61        runner = formatters["mtxrun --script %s"](runner)
62    else
63        runner = name
64    end
65    --
66    result[#result+1] = formatters['.TH "%s" "1" "%s" "version %s" "%s"'](name,os.date("01-01-%Y"),version,detail)
67    result[#result+1] = formatters[".SH NAME\n %s - %s"](name,detail) -- KB/TL wants 'detail' in this line too
68    result[#result+1] = formatters[".SH SYNOPSIS\n.B %s [\n.I OPTIONS ...\n.B ] [\n.I FILENAMES\n.B ]"](runner)
69    result[#result+1] = formatters[".SH DESCRIPTION\n.B %s"](detail)
70    --
71    for category in xmlcollected(root,"/application/flags/category") do
72        if nofcategories > 1 then
73            result[#result+1] = formatters['.SH OPTIONS: %s'](string.upper(category.at.name or "all"))
74        else
75            result[#result+1] = ".SH OPTIONS"
76        end
77        for subcategory in xmlcollected(category,"/subcategory") do
78            for flag in xmlcollected(subcategory,"/flag") do
79                local name, value, short = flagdata(flag)
80                if value == "" then
81                    result[#result+1] = formatters[".TP\n.B --%s\n%s"](name,short)
82                else
83                    result[#result+1] = formatters[".TP\n.B --%s=%s\n%s"](name,value,short)
84                end
85            end
86        end
87    end
88    local moreinfo = specification.moreinfo
89    if moreinfo and moreinfo ~= "" then
90        moreinfo = string.gsub(moreinfo,"[\n\r]([%a]+)%s*:%s*",'\n\n.B "%1:"\n')
91        result[#result+1] = formatters[".SH AUTHOR\n%s"](moreinfo)
92    end
93    return table.concat(result,"\n")
94end
95
96local craptemplate = [[
97<?xml version="1.0"?>
98<application>
99<metadata>
100<entry name="banner">%s</entry>
101</metadata>
102<verbose>
103%s
104</verbose>
105]]
106
107function exporters.xml(specification,...)
108    local helpinfo = specification.helpinfo
109    if type(helpinfo) == "string" then
110        if string.find(helpinfo,"^<%?xml") then
111            return helpinfo
112        end
113    elseif type(helpinfo) == "table" then
114        helpinfo = table.concat(helpinfo,"\n\n")
115    else
116        helpinfo = "no help"
117    end
118    return formatters[craptemplate](specification.banner or "?",helpinfo)
119end
120
121-- the following template is optimized a bit for space
122
123-- local bodytemplate = [[
124-- <h1>Command line options</h1>
125-- <table>
126--     <tr>
127--         <th style="width: 10em">flag</th>
128--         <th style="width: 8em">value</th>
129--         <th>description</th>
130--     </tr>
131--     <?lua
132--         for category in xml.collected(variables.root,"/application/flags/category") do
133--             if variables.nofcategories > 1 then
134--                 ?><tr>
135--                     <th colspan="3"><?lua inject(category.at.name) ?></th>
136--                 </tr><?lua
137--             end
138--             for subcategory in xml.collected(category,"/subcategory") do
139--                 ?><tr><th/><td/><td/></tr><?lua
140--                 for flag in xml.collected(subcategory,"/flag") do
141--                     local name, value, short = variables.flagdata(flag)
142--                     ?><tr>
143--                         <th>--<?lua inject(name) ?></th>
144--                         <td><?lua inject(value) ?></td>
145--                         <td><?lua inject(short) ?></td>
146--                     </tr><?lua
147--                 end
148--             end
149--         end
150--     ?>
151-- </table>
152-- <br/>
153-- <?lua
154--     for category in xml.collected(variables.root,"/application/examples/category") do
155--         local title = variables.categorytitle(category)
156--         if title ~= "" then
157--             ?><h1><?lua inject(title) ?></h1><?lua
158--         end
159--         for subcategory in xml.collected(category,"/subcategory") do
160--             for example in xml.collected(subcategory,"/example") do
161--                 local command, comment = variables.exampledata(example)
162--                 ?><tt><?lua inject(command) ?></tt><br/><?lua
163--             end
164--             ?><br/><?lua
165--         end
166--     end
167--     for comment in xml.collected(root,"/application/comments/comment") do
168--         ?><br/><?lua inject(xml.text(comment)) ?><br/><?lua
169--     end
170-- ?>
171-- ]]
172
173local bodytemplate = [[
174<h1>Command line options</h1>
175<table>
176    <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
177    <?lua for category in xml.collected(variables.root,"/application/flags/category") do if variables.nofcategories > 1 then ?>
178    <tr><th colspan="3"><?lua inject(category.at.name) ?></th></tr>
179    <?lua end for subcategory in xml.collected(category,"/subcategory") do ?>
180    <tr><th/><td/><td/></tr>
181    <?lua for flag in xml.collected(subcategory,"/flag") do local name, value, short = variables.flagdata(flag) ?>
182    <tr><th>--<?lua inject(name) ?></th><td><?lua inject(value) ?></td><td><?lua inject(short) ?></td></tr>
183    <?lua end end end ?>
184</table>
185<br/>
186<?lua for category in xml.collected(variables.root,"/application/examples/category") do local title = variables.categorytitle(category) if title ~= "" then ?>
187<h1><?lua inject(title) ?></h1>
188<?lua end for subcategory in xml.collected(category,"/subcategory") do for example in xml.collected(subcategory,"/example") do local command, comment = variables.exampledata(example) ?>
189<tt><?lua inject(command) ?></tt>
190<br/><?lua end ?><br/><?lua end end for comment in xml.collected(root,"/application/comments/comment") do ?>
191<br/><?lua inject(xml.text(comment)) ?><br/><?lua end ?>
192]]
193
194function exporters.html(specification,...)
195    local root = xml.convert(specification.helpinfo or "")
196    if not root then
197        return
198    end
199    local xs = xml.gethandlers("string")
200    xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
201    xml.sethandlersfunction(xs,"ref",  function(e,handler) handler.handle("--"..e.at.name) end)
202    local wantedcategories = select("#",...) == 0 and true or table.tohash { ... }
203    local nofcategories = xml.count(root,"/application/flags/category")
204    local name    = xmlfilter(root,"/application/metadata/entry[@name='name']/text()")
205    local detail  = xmlfilter(root,"/application/metadata/entry[@name='detail']/text()") or name
206    local version = xmlfilter(root,"/application/metadata/entry[@name='version']/text()") or "0.00"
207    local banner  = specification.banner or detail or name
208    --
209    dofile(resolvers.findfile("trac-lmx.lua","tex"))
210    --
211    local htmltemplate = io.loaddata(resolvers.findfile("context-base.lmx","tex")) or "no template"
212    --
213    local body = lmx.convertstring(bodytemplate, {
214        nofcategories    = nofcategories,
215        wantedcategories = wantedcategories,
216        root             = root,
217    --  moreinfo         = specification.moreinfo,
218        flagdata         = flagdata,
219        exampledata      = exampledata,
220        categorytitle    = categorytitle,
221    })
222    local html = lmx.convertstring(htmltemplate, {
223        maintext   = body,
224        title      = banner,
225        bottomtext = "wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl",
226    })
227    --
228    return html
229end
230