summaryrefslogtreecommitdiff
path: root/tex/context/base/pret-xml.lua
blob: e449d9d98c37f853561d3b1888757bf3c8936dcb (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
if not modules then modules = { } end modules ['pret-xml'] = {
    version   = 1.001,
    comment   = "companion to buff-ver.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- line by line, no check because can be snippet (educational) and
-- a somewhat simplified view on xml; we forget about dtd's and
-- cdata (some day i'll make a visualizer for valid xml using the
-- built in parser)

local utf = unicode.utf8
local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
local utfbyte, utffind = utf.byte, utf.find
local rep = string.rep
local texsprint, texwrite = tex.sprint, tex.write
local ctxcatcodes = tex.ctxcatcodes

local buffers = buffers

local changestate, finishstate = buffers.changestate, buffers.finishstate

local visualizer = buffers.newvisualizer("xml")

local colors = {
    "prettytwo",
    "prettyone",
    "prettythree",
    "prettyfour"
}

local states = {
    ['"']=2, ["'"]=2,
    ["-"]=1, ["?"]=1, ["!"]=1, [":"]=1, ["_"]=1, ["/"]=1,
}

local state, intag, dotag, inentity, inquote

function visualizer.reset()
    state, intag, dotag, inentity, inquote = 0, false, false, false, false
end

function visualizer.flush_line(str,nested)
    buffers.currentcolors = colors
    for c in utfcharacters(str) do
        if c == "&" then
            inentity = true -- no further checking
            state = changestate(3, state)
            texwrite(c)
        elseif c == ";" then
            if inentity then
                inentity = false
                state = changestate(3, state)
                texwrite(c)
                state = finishstate(state)
            else
                texwrite(c)
            end
        elseif inentity then
            state = changestate(3, state)
            texwrite(c)
        elseif c == " " then
            state = finishstate(state)
            texsprint(ctxcatcodes,"\\obs")
            intag = false
        elseif c == "\t" then
            state = finishstate(state)
            texsprint(ctxcatcodes,"\\obs")
            if buffers.visualizers.enabletab then
                texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength))
            end
            intag = false
        elseif c == "<" then
            if intag then
                state = finishstate(state)
                -- error
            else
                intag = 1
                dotag = true
                state = changestate(1, state)
            end
            texwrite(c)
        elseif c == ">" then
            if intag then
                texwrite(c)
                state = finishstate(state)
                intag, dotag = false, false
            elseif dotag then
                state = changestate(1, state)
                texwrite(c)
                state = finishstate(state)
                intag, dotag = false, false
            else
                state = finishstate(state)
                texwrite(c)
            end
        elseif intag then
            if utffind(c,"^[%S]$") then
                state = changestate(1, state)
                texwrite(c)
                intag = intag + 1
            else
                intag = false
                state = finishstate(state)
                texwrite(c)
            end
        elseif dotag then
            if c == "'" or c == '"' then
                if inquote then
                    if c == inquote then
                        state = changestate(states[c], state) -- 2
                        texwrite(c)
                        state = finishstate(state)
                        inquote = false
                    else
                        texwrite(c)
                    end
                else
                    inquote = c
                    state = changestate(states[c], state)
                    texwrite(c)
                    state = finishstate(state)
                end
            elseif inquote then
                texwrite(c)
            else
                state = changestate(states[c], state)
                texwrite(c)
            end
        else
            texwrite(c)
        end
    end
    state = finishstate(state)
end