Fri, 23 Apr 2021 21:15:05 +0100
New implementation of lxp.lom by Tom?s Guisasola
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 | -- See Copyright Notice in license.html |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 | |
10
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
3 | local lxp = require "lxp" |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 | |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
5 | local table = require"table" |
10
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
6 | local tinsert, tremove = table.insert, table.remove |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
7 | local assert, pairs, type = assert, pairs, type |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 | |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 | |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
10 | -- auxiliary functions ------------------------------------------------------- |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 | local function starttag (p, tag, attr) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 | local stack = p:getcallbacks().stack |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 | local newelement = {tag = tag, attr = attr} |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 | tinsert(stack, newelement) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 | end |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 | |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 | local function endtag (p, tag) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 | local stack = p:getcallbacks().stack |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 | local element = tremove(stack) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 | assert(element.tag == tag) |
10
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
21 | local level = #stack |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 | tinsert(stack[level], element) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 | end |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 | |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 | local function text (p, txt) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 | local stack = p:getcallbacks().stack |
10
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
27 | local element = stack[#stack] |
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
28 | local n = #element |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 | if type(element[n]) == "string" then |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 | element[n] = element[n] .. txt |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 | else |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 | tinsert(element, txt) |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 | end |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 | end |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 | |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
36 | -- main function ------------------------------------------------------------- |
10
e981a82571cf
Add compatibility with Lua 5.2
Tom?s Guisasola Gorham <tomas@tecgraf.puc-rio.br>
parents:
0
diff
changeset
|
37 | local function parse (o) |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
38 | local c = { StartElement = starttag, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
39 | EndElement = endtag, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
40 | CharacterData = text, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
41 | _nonstrict = true, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
42 | stack = {{}} |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
43 | } |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
44 | local p = lxp.new(c) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
45 | local to = type(o) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
46 | if to == "string" then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
47 | local status, err, line, col, pos = p:parse(o) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
48 | if not status then return nil, err, line, col, pos end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
49 | else |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
50 | local iter, state, init |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
51 | if to == "table" then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
52 | iter, state, init = pairs(o) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
53 | elseif to == "function" then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
54 | iter = o |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
55 | elseif to == "userdata" and o.read then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
56 | iter, state = o.read, o |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
57 | else |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
58 | error ("Bad argument #1 to parse: expected a string, a table, a function or a file, but got "..to, 2) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
59 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
60 | for l in iter, state, init do |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
61 | local status, err, line, col, pos = p:parse(l) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
62 | if not status then return nil, err, line, col, pos end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
63 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
64 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
65 | local status, err, line, col, pos = p:parse() -- close document |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
66 | if not status then return nil, err, line, col, pos end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
67 | p:close() |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
68 | return c.stack[1][1] |
0
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 | end |
24d141cb2d1e
Initial commit of LuaExpat 1.1.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 | |
36
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
71 | -- utility functions --------------------------------------------------------- |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
72 | local function find_elem (self, tag) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
73 | if self.tag == tag then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
74 | return self |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
75 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
76 | for i = 1, #self do |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
77 | local v = self[i] |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
78 | if type(v) == "table" then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
79 | local found = find_elem (v, tag) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
80 | if found then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
81 | return found |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
82 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
83 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
84 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
85 | return nil |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
86 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
87 | |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
88 | local function list_children (self, tag) |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
89 | local i = 0 |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
90 | return function () |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
91 | i = i+1 |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
92 | local v = self[i] |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
93 | while v do |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
94 | if type (v) == "table" and (tag == nil or tag == v.tag) then |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
95 | return v |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
96 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
97 | i = i+1 |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
98 | v = self[i] |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
99 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
100 | return nil |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
101 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
102 | end |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
103 | |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
104 | return { |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
105 | find_elem = find_elem, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
106 | list_children = list_children, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
107 | parse = parse, |
4a61f00ee916
New implementation of lxp.lom by Tom?s Guisasola
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
108 | } |