summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/lxml-ctx.lua
blob: 677fd6a0154992e00068a9d8f00793258cd9d8c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
if not modules then modules = { } end modules ['lxml-ctx'] = {
    version   = 1.001,
    comment   = "companion to lxml-ini.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- will be cleaned up

local format, find, gsub = string.format, string.find, string.gsub

local xml         = xml
xml.ctx           = { }
xml.ctx.enhancers = { }

local context     = context
local commands    = commands

-- hashen

function xml.ctx.enhancers.compound(root,lpath,before,tokens,after) -- todo lpeg
    local before  = before or "[%a%d][%a%d][%a%d]"
    local tokens  = tokens or "[%/%-]"
    local after   = after  or "[%a%d][%a%d][%a%d]"
    local pattern = "(" .. before .. ")(" .. tokens .. ")(" .. after .. ")"
    local action  = function(a,b,c)
        return a .. "<compound token=" .. format("%q",b) .. "/>" .. c -- formatters["%s<compound token=%q/>%s"](a,b,c)
    end
    xml.enhance(root,lpath,pattern,action) -- still present?
end

local loaded = { }

local nodesettostring = xml.nodesettostring

-- maybe use detokenize instead of \type

local function cleaned(str)
    str = gsub(str,"|","\\textbar ")
    return str
end

function xml.ctx.tshow(specification)
    local pattern = specification.pattern
    local xmlroot = specification.xmlroot
    local attribute = specification.attribute
    if context then
        local xmlpattern = pattern
        if not find(xmlpattern,"^[%a]+://") then
            xmlpattern = "xml://" .. pattern
        end
        local parsed = xml.lpath(xmlpattern)
        local titlecommand = specification.title or "type"
        if parsed.state then
            context[titlecommand]("pattern: " .. cleaned(pattern) .. " (".. parsed.state .. ")")
        else
            context[titlecommand]("pattern: " .. cleaned(pattern))
        end
        context.starttabulate({ "|Tr|Tl|Tp|" } )
        if specification.warning then
            local comment = parsed.comment
            if comment then
                for k=1,#comment do
                    context.NC()
                    context("!")
                    context.NC()
                    context.rlap(comment[k])
                    context.NR()
                end
                context.TB()
            end
        end
        for p=1,#parsed do
            local pp = parsed[p]
            local kind = pp.kind
            context.NC()
            context(p)
            context.NC()
            context(kind)
            context.NC()
            if kind == "axis" then
                context(cleaned(pp.axis))
            elseif kind == "nodes" then
                context(cleaned(nodesettostring(pp.nodes,pp.nodetest)))
            elseif kind == "expression" then
--              -- context("%s => %s",pp.expression,pp.converted)
                context(cleaned(pp.expression))
            elseif kind == "finalizer" then
                context("%s(%s)",pp.name,pp.arguments)
            elseif kind == "error" and pp.eqrror then
                context(pp.error)
            end
            context.NC()
            context.NR()
        end
        context.stoptabulate()
        if xmlroot and xmlroot ~= "" then
            if not loaded[xmlroot] then
                loaded[xmlroot] = xml.convert(buffers.getcontent(xmlroot))
            end
            local collected = xml.filter(loaded[xmlroot],xmlpattern)
            if collected then
                local tc = type(collected)
                if not tc then
                    -- skip
                else
                    context.blank()
                    context.type("result : ")
                    if tc == "string" then
                        context.type(collected)
                    elseif tc == "table" then
                        if collected.tg then
                            collected  = { collected }
                        end
                        for c=1,#collected do
                            local cc = collected[c]
                            if attribute and attribute ~= "" then
                                local ccat = cc.at
                                local a = ccat and ccat[attribute]
                                if a and a ~= "" then
                                    context.type(a)
                                    context.type(">")
                                end
                            end
                            local ccns = cc.ns
                            if ccns == "" then
                                context.type(cc.tg)
                            else
                                context.type(ccns .. ":" .. cc.tg)
                            end
                            context.space()
                        end
                    else
                        context.type(tostring(tc))
                    end
                    context.blank()
                end
            end
        end
    end
end