Строка 7: |
Строка 7: |
| local lt, gt, slash, backslash = P'<', P'>', P'/', P'\\' | | local lt, gt, slash, backslash = P'<', P'>', P'/', P'\\' |
| local colon, hyphen, equals = P':', P':', P'=' | | local colon, hyphen, equals = P':', P':', P'=' |
| + | |
| + | |
| + | -- Serialise a parsed tag back: |
| + | local function serialise (tag) |
| + | if not tag then |
| + | return '' |
| + | end |
| + | if type (tag) == 'string' then |
| + | return tag |
| + | end |
| + | local serialised = {} |
| + | if tag.__name then |
| + | serialised [#serialised + 1] = '<' .. tag.__name |
| + | for attr, value in pairs (tag) do |
| + | if type (attr) ~= 'number' and attr ~= '__name' and value ~= '' then |
| + | serialised [#serialised + 1] = attr .. '="' .. gsub (value, '"', '\\"', 1, true) .. '"' |
| + | end |
| + | end |
| + | serialised [#serialised + 1] = '>' |
| + | end |
| + | |
| + | for _, node in ipairs (tag) do |
| + | serialised [#serialised + 1] = serialise (node) |
| + | end |
| + | |
| + | if tag.__name then |
| + | serialised [#serialised + 1] = '</' .. tag.__name .. '>' |
| + | end |
| + | |
| + | return concat (serialised, ' ') |
| + | end |
| | | |
| local function memoize (func) | | local function memoize (func) |
| local memoized = {} | | local memoized = {} |
| return function (...) | | return function (...) |
− | local key = tostring {...} | + | --local key = tostring (setmetatable ({...}, { __tostring = serialise })) |
| + | local key = concat {...} |
| if not memoized [key] then | | if not memoized [key] then |
| memoized [key] = { func (...) } | | memoized [key] = { func (...) } |
Строка 39: |
Строка 71: |
| end | | end |
| return set | | return set |
− | end
| |
− |
| |
− | -- Serialise a parsed tag back:
| |
− | local function serialise (tag)
| |
− | if not tag then
| |
− | return ''
| |
− | end
| |
− | if type (tag) == 'string' then
| |
− | return tag
| |
− | end
| |
− | local serialised = {}
| |
− | if tag.__name then
| |
− | serialised [#serialised + 1] = '<' .. tag.__name
| |
− | for attr, value in pairs (tag) do
| |
− | if type (attr) ~= 'number' and attr ~= '__name' and value ~= '' then
| |
− | serialised [#serialised + 1] = attr .. '="' .. gsub (value, '"', '\\"', 1, true) .. '"'
| |
− | end
| |
− | end
| |
− | serialised [#serialised + 1] = '>'
| |
− | end
| |
− |
| |
− | for _, node in ipairs (tag) do
| |
− | serialised [#serialised + 1] = serialise (node)
| |
− | end
| |
− |
| |
− | if tag.__name then
| |
− | serialised [#serialised + 1] = '</' .. tag.__name .. '>'
| |
− | end
| |
− |
| |
− | return concat (serialised, ' ')
| |
| end | | end |
| | | |
Строка 229: |
Строка 231: |
| return nil | | return nil |
| end | | end |
− | return tag --setmetatable (tag, {__tostring = serialise }) | + | return setmetatable (tag, {__tostring = serialise }) |
| end, | | end, |
| open = lt * spaces * Cg (possible, '__name') * V'attributes' * spaces * gt, | | open = lt * spaces * Cg (possible, '__name') * V'attributes' * spaces * gt, |