2021-12-06 23:28:00 +00:00
|
|
|
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
|
|
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
|
|
|
|
import std/[xmltree, strtabs, tables]
|
|
|
|
import ../preserves
|
|
|
|
|
|
|
|
proc toPreserveHook*(xn: XmlNode; E: typedesc): Preserve[E] =
|
|
|
|
case xn.kind
|
|
|
|
of xnElement:
|
2021-12-22 21:27:18 +00:00
|
|
|
result = initSequence[E](xn.len + 2)
|
|
|
|
result[0] = toSymbol(xn.tag, E)
|
|
|
|
var attrs = initDictionary[E]()
|
2021-12-06 23:28:00 +00:00
|
|
|
if not xn.attrs.isNil:
|
|
|
|
for key, val in xn.attrs.pairs:
|
2021-12-22 21:27:18 +00:00
|
|
|
attrs[toPreserve(key, E)] = toPreserve(val, E)
|
|
|
|
result[1] = attrs
|
|
|
|
var i = 2
|
|
|
|
for child in xn.items:
|
|
|
|
result[i] = toPreserveHook(child, E)
|
|
|
|
inc i
|
2021-12-06 23:28:00 +00:00
|
|
|
of xnText:
|
2021-12-22 21:27:18 +00:00
|
|
|
result = initSequence[E](1)
|
|
|
|
result[0] = toPreserve(xn.text, E)
|
2021-12-06 23:28:00 +00:00
|
|
|
of xnVerbatimText:
|
|
|
|
result = initRecord[E]("verbatim", xn.text.toPreserve(E))
|
|
|
|
of xnComment:
|
|
|
|
result = initRecord[E]("comment", xn.text.toPreserve(E))
|
|
|
|
of xnCData:
|
|
|
|
result = initRecord[E]("cdata", xn.text.toPreserve(E))
|
|
|
|
of xnEntity:
|
|
|
|
result = initRecord[E]("entity", xn.text.toPreserve(E))
|
|
|
|
|
|
|
|
proc fromPreserveHook*[E](xn: var XmlNode; pr: Preserve[E]): bool =
|
|
|
|
case pr.kind:
|
2021-12-22 21:27:18 +00:00
|
|
|
of pkSequence:
|
|
|
|
if pr.len == 1 and pr[0].isString:
|
|
|
|
xn = newText(pr[0].string)
|
2021-12-06 23:28:00 +00:00
|
|
|
result = true
|
2021-12-22 21:27:18 +00:00
|
|
|
elif pr.len >= 2 and pr[0].isSymbol and pr[1].isDictionary:
|
|
|
|
result = true
|
|
|
|
var children = newSeq[XmlNode](pr.len - 2)
|
|
|
|
for i in 2..<pr.len:
|
|
|
|
result = fromPreserve(children[i-2], pr[i])
|
|
|
|
if not result: break
|
|
|
|
var attrs: XmlAttributes
|
|
|
|
if pr[1].len > 0:
|
|
|
|
attrs = newStringTable()
|
|
|
|
for key, val in pr[1].dict.items:
|
|
|
|
if key.isString and val.isString:
|
|
|
|
attrs[key.string] = val.string
|
|
|
|
else:
|
2021-12-06 23:28:00 +00:00
|
|
|
result = false
|
|
|
|
break
|
2021-12-22 21:27:18 +00:00
|
|
|
if result:
|
2022-02-20 04:33:15 +00:00
|
|
|
xn = newXmlTree(string pr[0].symbol, children, attrs)
|
2021-12-22 21:27:18 +00:00
|
|
|
of pkRecord:
|
|
|
|
if pr.len == 1 and pr[0].isString and pr.label.isSymbol:
|
2021-12-06 23:28:00 +00:00
|
|
|
result = true
|
2022-02-20 04:33:15 +00:00
|
|
|
case pr.label.symbol.string:
|
2021-12-06 23:28:00 +00:00
|
|
|
of "verbatim":
|
|
|
|
xn = newVerbatimText(pr[0].string)
|
|
|
|
of "comment":
|
|
|
|
xn = newComment(pr[0].string)
|
|
|
|
of "cdata":
|
|
|
|
xn = newCData(pr[0].string)
|
|
|
|
of "entity":
|
|
|
|
xn = newEntity(pr[0].string)
|
|
|
|
else:
|
|
|
|
result = false
|
|
|
|
else: discard
|
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
var xn = XmlNode()
|
|
|
|
var pr = xn.toPreserveHook(void)
|
|
|
|
assert fromPreserveHook(xn, pr)
|