trac-xml.lua /size: 6407 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['trac-xml'] = {
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
9-- Application helpinfo can be defined in several ways:
10--
11-- helpinfo = "big blob of help"
12--
13-- helpinfo = { basic = "blob of basic help", extra = "blob of extra help" }
14--
15-- helpinfo = "<?xml version=1.0?><application>...</application/>"
16--
17-- helpinfo = "somefile.xml"
18--
19-- In the case of an xml file, the file should be either present on the same path
20-- as the script, or we should be be able to locate it using the resolver.
21
22local formatters   = string.formatters
23local reporters    = logs.reporters
24local xmlserialize = xml.serialize
25local xmlcollected = xml.collected
26local xmltext      = xml.text
27local xmlfirst     = xml.first
28
29-- there is no need for a newhandlers { name = "help", parent = "string" }
30
31local function showhelp(specification,...)
32    local root = xml.convert(specification.helpinfo or "")
33    if not root then
34        return
35    end
36    local xs = xml.gethandlers("string")
37    xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
38    xml.sethandlersfunction(xs,"ref",  function(e,handler) handler.handle("--"..e.at.name) end)
39    local wantedcategories = select("#",...) == 0 and true or table.tohash { ... }
40    local nofcategories = xml.count(root,"/application/flags/category")
41    local report = specification.report
42    for category in xmlcollected(root,"/application/flags/category") do
43        local categoryname = category.at.name or ""
44        if wantedcategories == true or wantedcategories[categoryname] then
45            if nofcategories > 1 then
46                report("%s options:",categoryname)
47                report()
48            end
49            for subcategory in xmlcollected(category,"/subcategory") do
50                for flag in xmlcollected(subcategory,"/flag") do
51                    local name  = flag.at.name
52                    local value = flag.at.value
53                 -- local short = xmlfirst(s,"/short")
54                 -- local short = xmlserialize(short,xs)
55                    local short = xmltext(xmlfirst(flag,"/short"))
56                    if value then
57                        report("--%-20s %s",formatters["%s=%s"](name,value),short)
58                    else
59                        report("--%-20s %s",name,short)
60                    end
61                end
62                report()
63            end
64        end
65    end
66    for category in xmlcollected(root,"/application/examples/category") do
67        local title = xmltext(xmlfirst(category,"/title"))
68        if title and title ~= "" then
69            report()
70            report(title)
71            report()
72        end
73        for subcategory in xmlcollected(category,"/subcategory") do
74            for example in xmlcollected(subcategory,"/example") do
75                local command = xmltext(xmlfirst(example,"/command"))
76                local comment = xmltext(xmlfirst(example,"/comment"))
77                report(command)
78            end
79            report()
80        end
81    end
82    for comment in xmlcollected(root,"/application/comments/comment") do
83        local comment = xmltext(comment)
84        report()
85        report(comment)
86        report()
87    end
88end
89
90local reporthelp = reporters.help
91local exporthelp = reporters.export
92
93local function xmlfound(t)
94    local helpinfo = t.helpinfo
95    if type(helpinfo) == "table" then
96        return false
97    end
98    if type(helpinfo) ~= "string" then
99        helpinfo = "Warning: no helpinfo found."
100        t.helpinfo = helpinfo
101        return false
102    end
103    if string.find(helpinfo,".xml$") then
104        local ownscript = environment.ownscript
105        local helpdata  = false
106        if ownscript then
107            local helpfile = file.join(file.pathpart(ownscript),helpinfo)
108            helpdata = io.loaddata(helpfile)
109            if helpdata == "" then
110                helpdata = false
111            end
112        end
113        if not helpdata then
114            local helpfile = resolvers.findfile(helpinfo,"tex")
115            helpdata = helpfile and io.loaddata(helpfile)
116        end
117        if helpdata and helpdata ~= "" then
118            helpinfo = helpdata
119        else
120            helpinfo = formatters["Warning: help file %a is not found."](helpinfo)
121        end
122    end
123    t.helpinfo = helpinfo
124    return string.find(t.helpinfo,"^<%?xml") and true or false
125end
126
127function reporters.help(t,...)
128    if xmlfound(t) then
129        showhelp(t,...)
130    else
131        reporthelp(t,...)
132    end
133end
134
135function reporters.export(t,methods,filename)
136    if not xmlfound(t) then
137        return exporthelp(t)
138    end
139    if not methods or methods == "" then
140        methods = environment.arguments["exporthelp"]
141    end
142    if not filename or filename == "" then
143        filename = environment.files[1]
144    end
145    dofile(resolvers.findfile("trac-exp.lua","tex"))
146    local exporters = logs.exporters
147    if not exporters or not methods then
148        return exporthelp(t)
149    end
150    if methods == "all" then
151        methods = table.keys(exporters)
152    elseif type(methods) == "string" then
153        methods = utilities.parsers.settings_to_array(methods)
154    else
155        return exporthelp(t)
156    end
157    if type(filename) ~= "string" or filename == "" then
158        filename = false
159    elseif file.pathpart(filename) == "" then
160        t.report("export file %a will not be saved on the current path (safeguard)",filename)
161        return
162    end
163    for i=1,#methods do
164        local method = methods[i]
165        local exporter = exporters[method]
166        if exporter then
167            local result = exporter(t,method)
168            if result and result ~= "" then
169                if filename then
170                    local fullname = file.replacesuffix(filename,method)
171                    t.report("saving export in %a",fullname)
172                    dir.mkdirs(file.pathpart(fullname))
173                    io.savedata(fullname,result)
174                else
175                    reporters.lines(t,result)
176                end
177            else
178                t.report("no output from exporter %a",method)
179            end
180        else
181            t.report("unknown exporter %a",method)
182        end
183    end
184end
185