Rename PNimrodNode to NimNode
This commit is contained in:
parent
8e651fa0d4
commit
fd4e629905
30 changed files with 508 additions and 518 deletions
|
|
@ -1064,13 +1064,13 @@ proc accept*(socket: TAsyncFD,
|
|||
|
||||
# -- Await Macro
|
||||
|
||||
proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
proc skipUntilStmtList(node: NimNode): NimNode {.compileTime.} =
|
||||
# Skips a nest of StmtList's.
|
||||
result = node
|
||||
if node[0].kind == nnkStmtList:
|
||||
result = skipUntilStmtList(node[0])
|
||||
|
||||
proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
proc skipStmtList(node: NimNode): NimNode {.compileTime.} =
|
||||
result = node
|
||||
if node[0].kind == nnkStmtList:
|
||||
result = node[0]
|
||||
|
|
@ -1098,11 +1098,11 @@ template createCb(retFutureSym, iteratorNameSym,
|
|||
cb()
|
||||
#{.pop.}
|
||||
proc generateExceptionCheck(futSym,
|
||||
tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
tryStmt, rootReceiver, fromNode: NimNode): NimNode {.compileTime.} =
|
||||
if tryStmt.kind == nnkNilLit:
|
||||
result = rootReceiver
|
||||
else:
|
||||
var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[]
|
||||
var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[]
|
||||
let errorNode = newDotExpr(futSym, newIdentNode("error"))
|
||||
for i in 1 .. <tryStmt.len:
|
||||
let exceptBranch = tryStmt[i]
|
||||
|
|
@ -1110,7 +1110,7 @@ proc generateExceptionCheck(futSym,
|
|||
exceptionChecks.add((newIdentNode("true"), exceptBranch[0]))
|
||||
else:
|
||||
var exceptIdentCount = 0
|
||||
var ifCond: PNimrodNode
|
||||
var ifCond: NimNode
|
||||
for i in 0 .. <exceptBranch.len:
|
||||
let child = exceptBranch[i]
|
||||
if child.kind == nnkIdent:
|
||||
|
|
@ -1144,10 +1144,10 @@ proc generateExceptionCheck(futSym,
|
|||
)
|
||||
result.add elseNode
|
||||
|
||||
template createVar(result: var PNimrodNode, futSymName: string,
|
||||
asyncProc: PNimrodNode,
|
||||
template createVar(result: var NimNode, futSymName: string,
|
||||
asyncProc: NimNode,
|
||||
valueReceiver, rootReceiver: expr,
|
||||
fromNode: PNimrodNode) =
|
||||
fromNode: NimNode) =
|
||||
result = newNimNode(nnkStmtList, fromNode)
|
||||
var futSym = genSym(nskVar, "future")
|
||||
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
||||
|
|
@ -1155,9 +1155,9 @@ template createVar(result: var PNimrodNode, futSymName: string,
|
|||
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
||||
result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode)
|
||||
|
||||
proc processBody(node, retFutureSym: PNimrodNode,
|
||||
proc processBody(node, retFutureSym: NimNode,
|
||||
subTypeIsVoid: bool,
|
||||
tryStmt: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
tryStmt: NimNode): NimNode {.compileTime.} =
|
||||
#echo(node.treeRepr)
|
||||
result = node
|
||||
case node.kind
|
||||
|
|
@ -1183,7 +1183,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
|||
result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
|
||||
of nnkCall, nnkCommand:
|
||||
# await foo(p, x)
|
||||
var futureValue: PNimrodNode
|
||||
var futureValue: NimNode
|
||||
result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
|
||||
futureValue, node)
|
||||
else:
|
||||
|
|
@ -1232,8 +1232,8 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
|||
# working in ``except``?
|
||||
tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
|
||||
|
||||
proc processForTry(n: PNimrodNode, i: var int,
|
||||
res: PNimrodNode): bool {.compileTime.} =
|
||||
proc processForTry(n: NimNode, i: var int,
|
||||
res: NimNode): bool {.compileTime.} =
|
||||
## Transforms the body of the tryStmt. Does not transform the
|
||||
## body in ``except``.
|
||||
## Returns true if the tryStmt node was transformed into an ifStmt.
|
||||
|
|
@ -1275,7 +1275,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
|||
for i in 0 .. <result.len:
|
||||
result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt)
|
||||
|
||||
proc getName(node: PNimrodNode): string {.compileTime.} =
|
||||
proc getName(node: NimNode): string {.compileTime.} =
|
||||
case node.kind
|
||||
of nnkPostfix:
|
||||
return $node[1].ident
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
import macros
|
||||
|
||||
proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
||||
#echo treeRepr(p)
|
||||
#echo treeRepr(b)
|
||||
result = newNimNode(nnkProcTy)
|
||||
|
|
@ -44,7 +44,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
|||
formalParams.add identDefs
|
||||
else:
|
||||
error("Incorrect type list in proc type declaration.")
|
||||
|
||||
|
||||
result.add formalParams
|
||||
result.add newEmptyNode()
|
||||
#echo(treeRepr(result))
|
||||
|
|
@ -59,10 +59,10 @@ macro `=>`*(p, b: expr): expr {.immediate.} =
|
|||
## f(2, 2)
|
||||
##
|
||||
## passTwoAndTwo((x, y) => x + y) # 4
|
||||
|
||||
|
||||
#echo treeRepr(p)
|
||||
#echo(treeRepr(b))
|
||||
var params: seq[PNimrodNode] = @[newIdentNode("auto")]
|
||||
var params: seq[NimNode] = @[newIdentNode("auto")]
|
||||
|
||||
case p.kind
|
||||
of nnkPar:
|
||||
|
|
@ -118,7 +118,7 @@ macro `->`*(p, b: expr): expr {.immediate.} =
|
|||
##
|
||||
## proc pass2(f: (float, float) -> float): float =
|
||||
## f(2, 2)
|
||||
##
|
||||
##
|
||||
## # is the same as:
|
||||
##
|
||||
## proc pass2(f: proc (x, y: float): float): float =
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
## as ``from htmlgen import nil`` and then fully qualify the macros.
|
||||
##
|
||||
##
|
||||
## This module implements a simple `XML`:idx: and `HTML`:idx: code
|
||||
## This module implements a simple `XML`:idx: and `HTML`:idx: code
|
||||
## generator. Each commonly used HTML tag has a corresponding macro
|
||||
## that generates a string with its HTML representation.
|
||||
##
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
## .. code-block:: Nim
|
||||
## var nim = "Nim"
|
||||
## echo h1(a(href="http://nim-lang.org", nim))
|
||||
##
|
||||
##
|
||||
## Writes the string::
|
||||
##
|
||||
##
|
||||
## <h1><a href="http://nim-lang.org">Nim</a></h1>
|
||||
##
|
||||
|
||||
|
|
@ -36,16 +36,16 @@ const
|
|||
"onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup "
|
||||
commonAttr* = coreAttr & eventAttr
|
||||
|
||||
proc getIdent(e: PNimrodNode): string {.compileTime.} =
|
||||
proc getIdent(e: NimNode): string {.compileTime.} =
|
||||
case e.kind
|
||||
of nnkIdent: result = normalize($e.ident)
|
||||
of nnkAccQuoted:
|
||||
of nnkAccQuoted:
|
||||
result = getIdent(e[0])
|
||||
for i in 1 .. e.len-1:
|
||||
result.add getIdent(e[i])
|
||||
else: error("cannot extract identifier from node: " & toStrLit(e).strVal)
|
||||
|
||||
proc delete[T](s: var seq[T], attr: T): bool =
|
||||
proc delete[T](s: var seq[T], attr: T): bool =
|
||||
var idx = find(s, attr)
|
||||
if idx >= 0:
|
||||
var L = s.len
|
||||
|
|
@ -53,10 +53,10 @@ proc delete[T](s: var seq[T], attr: T): bool =
|
|||
setLen(s, L-1)
|
||||
result = true
|
||||
|
||||
proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
||||
isLeaf = false): PNimrodNode {.compileTime.} =
|
||||
proc xmlCheckedTag*(e: NimNode, tag: string, optAttr = "", reqAttr = "",
|
||||
isLeaf = false): NimNode {.compileTime.} =
|
||||
## use this procedure to define a new XML tag
|
||||
|
||||
|
||||
# copy the attributes; when iterating over them these lists
|
||||
# will be modified, so that each attribute is only given one value
|
||||
var req = split(reqAttr)
|
||||
|
|
@ -66,7 +66,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
|||
result.add(newStrLitNode(tag))
|
||||
# first pass over attributes:
|
||||
for i in 1..e.len-1:
|
||||
if e[i].kind == nnkExprEqExpr:
|
||||
if e[i].kind == nnkExprEqExpr:
|
||||
var name = getIdent(e[i][0])
|
||||
if delete(req, name) or delete(opt, name):
|
||||
result.add(newStrLitNode(" "))
|
||||
|
|
@ -81,7 +81,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
|||
error(req[0] & " attribute for '" & tag & "' element expected")
|
||||
if isLeaf:
|
||||
for i in 1..e.len-1:
|
||||
if e[i].kind != nnkExprEqExpr:
|
||||
if e[i].kind != nnkExprEqExpr:
|
||||
error("element " & tag & " cannot be nested")
|
||||
result.add(newStrLitNode(" />"))
|
||||
else:
|
||||
|
|
@ -95,389 +95,389 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "",
|
|||
result = nestList(!"&", result)
|
||||
|
||||
|
||||
macro a*(e: expr): expr {.immediate.} =
|
||||
macro a*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``a`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "a", "href charset type hreflang rel rev " &
|
||||
"accesskey tabindex" & commonAttr)
|
||||
|
||||
macro acronym*(e: expr): expr {.immediate.} =
|
||||
macro acronym*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``acronym`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "acronym", commonAttr)
|
||||
|
||||
macro address*(e: expr): expr {.immediate.} =
|
||||
macro address*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``address`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "address", commonAttr)
|
||||
|
||||
macro area*(e: expr): expr {.immediate.} =
|
||||
macro area*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``area`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "area", "shape coords href nohref" &
|
||||
" accesskey tabindex" & commonAttr, "alt", true)
|
||||
|
||||
macro b*(e: expr): expr {.immediate.} =
|
||||
macro b*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``b`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "b", commonAttr)
|
||||
|
||||
macro base*(e: expr): expr {.immediate.} =
|
||||
macro base*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``base`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "base", "", "href", true)
|
||||
|
||||
macro big*(e: expr): expr {.immediate.} =
|
||||
macro big*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``big`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "big", commonAttr)
|
||||
|
||||
macro blockquote*(e: expr): expr {.immediate.} =
|
||||
macro blockquote*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``blockquote`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "blockquote", " cite" & commonAttr)
|
||||
|
||||
macro body*(e: expr): expr {.immediate.} =
|
||||
macro body*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``body`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "body", commonAttr)
|
||||
|
||||
macro br*(e: expr): expr {.immediate.} =
|
||||
macro br*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``br`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "br", "", "", true)
|
||||
|
||||
macro button*(e: expr): expr {.immediate.} =
|
||||
macro button*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``button`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "button", "accesskey tabindex " &
|
||||
"disabled name type value" & commonAttr)
|
||||
|
||||
macro caption*(e: expr): expr {.immediate.} =
|
||||
macro caption*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``caption`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "caption", commonAttr)
|
||||
|
||||
macro cite*(e: expr): expr {.immediate.} =
|
||||
macro cite*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``cite`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "cite", commonAttr)
|
||||
|
||||
macro code*(e: expr): expr {.immediate.} =
|
||||
macro code*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``code`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "code", commonAttr)
|
||||
|
||||
macro col*(e: expr): expr {.immediate.} =
|
||||
macro col*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``col`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "col", "span align valign" & commonAttr, "", true)
|
||||
|
||||
macro colgroup*(e: expr): expr {.immediate.} =
|
||||
macro colgroup*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``colgroup`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "colgroup", "span align valign" & commonAttr)
|
||||
|
||||
macro dd*(e: expr): expr {.immediate.} =
|
||||
macro dd*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``dd`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "dd", commonAttr)
|
||||
|
||||
macro del*(e: expr): expr {.immediate.} =
|
||||
macro del*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``del`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "del", "cite datetime" & commonAttr)
|
||||
|
||||
macro dfn*(e: expr): expr {.immediate.} =
|
||||
macro dfn*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``dfn`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "dfn", commonAttr)
|
||||
|
||||
macro `div`*(e: expr): expr {.immediate.} =
|
||||
macro `div`*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``div`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "div", commonAttr)
|
||||
|
||||
macro dl*(e: expr): expr {.immediate.} =
|
||||
macro dl*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``dl`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "dl", commonAttr)
|
||||
|
||||
macro dt*(e: expr): expr {.immediate.} =
|
||||
macro dt*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``dt`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "dt", commonAttr)
|
||||
|
||||
macro em*(e: expr): expr {.immediate.} =
|
||||
macro em*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``em`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "em", commonAttr)
|
||||
|
||||
macro fieldset*(e: expr): expr {.immediate.} =
|
||||
macro fieldset*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``fieldset`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "fieldset", commonAttr)
|
||||
|
||||
macro form*(e: expr): expr {.immediate.} =
|
||||
macro form*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``form`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "form", "method encype accept accept-charset" &
|
||||
result = xmlCheckedTag(e, "form", "method encype accept accept-charset" &
|
||||
commonAttr, "action")
|
||||
|
||||
macro h1*(e: expr): expr {.immediate.} =
|
||||
macro h1*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h1`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h1", commonAttr)
|
||||
|
||||
macro h2*(e: expr): expr {.immediate.} =
|
||||
macro h2*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h2`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h2", commonAttr)
|
||||
|
||||
macro h3*(e: expr): expr {.immediate.} =
|
||||
macro h3*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h3`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h3", commonAttr)
|
||||
|
||||
macro h4*(e: expr): expr {.immediate.} =
|
||||
macro h4*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h4`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h4", commonAttr)
|
||||
|
||||
macro h5*(e: expr): expr {.immediate.} =
|
||||
macro h5*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h5`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h5", commonAttr)
|
||||
|
||||
macro h6*(e: expr): expr {.immediate.} =
|
||||
macro h6*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``h6`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "h6", commonAttr)
|
||||
|
||||
macro head*(e: expr): expr {.immediate.} =
|
||||
macro head*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``head`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "head", "profile")
|
||||
|
||||
macro html*(e: expr): expr {.immediate.} =
|
||||
macro html*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``html`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "html", "xmlns", "")
|
||||
|
||||
macro hr*(): expr {.immediate.} =
|
||||
macro hr*(): expr {.immediate.} =
|
||||
## generates the HTML ``hr`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "hr", commonAttr, "", true)
|
||||
|
||||
macro i*(e: expr): expr {.immediate.} =
|
||||
macro i*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``i`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "i", commonAttr)
|
||||
|
||||
macro img*(e: expr): expr {.immediate.} =
|
||||
macro img*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``img`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "img", "longdesc height width", "src alt", true)
|
||||
|
||||
macro input*(e: expr): expr {.immediate.} =
|
||||
macro input*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``input`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "input", "name type value checked maxlength src" &
|
||||
" alt accept disabled readonly accesskey tabindex" & commonAttr, "", true)
|
||||
|
||||
macro ins*(e: expr): expr {.immediate.} =
|
||||
macro ins*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``ins`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "ins", "cite datetime" & commonAttr)
|
||||
|
||||
macro kbd*(e: expr): expr {.immediate.} =
|
||||
macro kbd*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``kbd`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "kbd", commonAttr)
|
||||
|
||||
macro label*(e: expr): expr {.immediate.} =
|
||||
macro label*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``label`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "label", "for accesskey" & commonAttr)
|
||||
|
||||
macro legend*(e: expr): expr {.immediate.} =
|
||||
macro legend*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``legend`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "legend", "accesskey" & commonAttr)
|
||||
|
||||
macro li*(e: expr): expr {.immediate.} =
|
||||
macro li*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``li`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "li", commonAttr)
|
||||
|
||||
macro link*(e: expr): expr {.immediate.} =
|
||||
macro link*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``link`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" &
|
||||
result = xmlCheckedTag(e, "link", "href charset hreflang type rel rev media" &
|
||||
commonAttr, "", true)
|
||||
|
||||
macro map*(e: expr): expr {.immediate.} =
|
||||
macro map*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``map`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "map", "class title" & eventAttr, "id", false)
|
||||
|
||||
macro meta*(e: expr): expr {.immediate.} =
|
||||
macro meta*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``meta`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "meta", "name http-equiv scheme", "content", true)
|
||||
|
||||
macro noscript*(e: expr): expr {.immediate.} =
|
||||
macro noscript*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``noscript`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "noscript", commonAttr)
|
||||
|
||||
macro `object`*(e: expr): expr {.immediate.} =
|
||||
macro `object`*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``object`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "object", "classid data codebase declare type " &
|
||||
"codetype archive standby width height name tabindex" & commonAttr)
|
||||
|
||||
macro ol*(e: expr): expr {.immediate.} =
|
||||
macro ol*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``ol`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "ol", commonAttr)
|
||||
|
||||
macro optgroup*(e: expr): expr {.immediate.} =
|
||||
macro optgroup*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``optgroup`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "optgroup", "disabled" & commonAttr, "label", false)
|
||||
|
||||
macro option*(e: expr): expr {.immediate.} =
|
||||
macro option*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``option`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "option", "selected value" & commonAttr)
|
||||
|
||||
macro p*(e: expr): expr {.immediate.} =
|
||||
macro p*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``p`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "p", commonAttr)
|
||||
|
||||
macro param*(e: expr): expr {.immediate.} =
|
||||
macro param*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``param`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "param", "value id type valuetype", "name", true)
|
||||
|
||||
macro pre*(e: expr): expr {.immediate.} =
|
||||
macro pre*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``pre`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "pre", commonAttr)
|
||||
|
||||
macro q*(e: expr): expr {.immediate.} =
|
||||
macro q*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``q`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "q", "cite" & commonAttr)
|
||||
|
||||
macro samp*(e: expr): expr {.immediate.} =
|
||||
macro samp*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``samp`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "samp", commonAttr)
|
||||
|
||||
macro script*(e: expr): expr {.immediate.} =
|
||||
macro script*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``script`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "script", "src charset defer", "type", false)
|
||||
|
||||
macro select*(e: expr): expr {.immediate.} =
|
||||
macro select*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``select`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" &
|
||||
result = xmlCheckedTag(e, "select", "name size multiple disabled tabindex" &
|
||||
commonAttr)
|
||||
|
||||
macro small*(e: expr): expr {.immediate.} =
|
||||
macro small*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``small`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "small", commonAttr)
|
||||
|
||||
macro span*(e: expr): expr {.immediate.} =
|
||||
macro span*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``span`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "span", commonAttr)
|
||||
|
||||
macro strong*(e: expr): expr {.immediate.} =
|
||||
macro strong*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``strong`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "strong", commonAttr)
|
||||
|
||||
macro style*(e: expr): expr {.immediate.} =
|
||||
macro style*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``style`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "style", "media title", "type")
|
||||
|
||||
macro sub*(e: expr): expr {.immediate.} =
|
||||
macro sub*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``sub`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "sub", commonAttr)
|
||||
|
||||
macro sup*(e: expr): expr {.immediate.} =
|
||||
macro sup*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``sup`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "sup", commonAttr)
|
||||
|
||||
macro table*(e: expr): expr {.immediate.} =
|
||||
macro table*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``table`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "table", "summary border cellpadding cellspacing" &
|
||||
" frame rules width" & commonAttr)
|
||||
|
||||
macro tbody*(e: expr): expr {.immediate.} =
|
||||
macro tbody*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``tbody`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "tbody", "align valign" & commonAttr)
|
||||
|
||||
macro td*(e: expr): expr {.immediate.} =
|
||||
macro td*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``td`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "td", "colspan rowspan abbr axis headers scope" &
|
||||
" align valign" & commonAttr)
|
||||
|
||||
macro textarea*(e: expr): expr {.immediate.} =
|
||||
macro textarea*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``textarea`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "textarea", " name disabled readonly accesskey" &
|
||||
" tabindex" & commonAttr, "rows cols", false)
|
||||
|
||||
macro tfoot*(e: expr): expr {.immediate.} =
|
||||
macro tfoot*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``tfoot`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "tfoot", "align valign" & commonAttr)
|
||||
|
||||
macro th*(e: expr): expr {.immediate.} =
|
||||
macro th*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``th`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "th", "colspan rowspan abbr axis headers scope" &
|
||||
" align valign" & commonAttr)
|
||||
|
||||
macro thead*(e: expr): expr {.immediate.} =
|
||||
macro thead*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``thead`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "thead", "align valign" & commonAttr)
|
||||
|
||||
macro title*(e: expr): expr {.immediate.} =
|
||||
macro title*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``title`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "title")
|
||||
|
||||
macro tr*(e: expr): expr {.immediate.} =
|
||||
macro tr*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``tr`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "tr", "align valign" & commonAttr)
|
||||
|
||||
macro tt*(e: expr): expr {.immediate.} =
|
||||
macro tt*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``tt`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "tt", commonAttr)
|
||||
|
||||
macro ul*(e: expr): expr {.immediate.} =
|
||||
macro ul*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``ul`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "ul", commonAttr)
|
||||
|
||||
macro `var`*(e: expr): expr {.immediate.} =
|
||||
macro `var`*(e: expr): expr {.immediate.} =
|
||||
## generates the HTML ``var`` element.
|
||||
let e = callsite()
|
||||
result = xmlCheckedTag(e, "var", commonAttr)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#
|
||||
|
||||
## This module implements a simple high performance `JSON`:idx:
|
||||
## parser. JSON (JavaScript Object Notation) is a lightweight
|
||||
## data-interchange format that is easy for humans to read and write
|
||||
## parser. JSON (JavaScript Object Notation) is a lightweight
|
||||
## data-interchange format that is easy for humans to read and write
|
||||
## (unlike XML). It is easy for machines to parse and generate.
|
||||
## JSON is based on a subset of the JavaScript Programming Language,
|
||||
## Standard ECMA-262 3rd Edition - December 1999.
|
||||
|
|
@ -50,10 +50,10 @@
|
|||
## }
|
||||
## ]
|
||||
|
||||
import
|
||||
import
|
||||
hashes, strutils, lexbase, streams, unicode, macros
|
||||
|
||||
type
|
||||
type
|
||||
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
||||
jsonError, ## an error occurred during parsing
|
||||
jsonEof, ## end of file reached
|
||||
|
|
@ -67,7 +67,7 @@ type
|
|||
jsonObjectEnd, ## end of an object: the ``}`` token
|
||||
jsonArrayStart, ## start of an array: the ``[`` token
|
||||
jsonArrayEnd ## start of an array: the ``]`` token
|
||||
|
||||
|
||||
TTokKind = enum # must be synchronized with TJsonEventKind!
|
||||
tkError,
|
||||
tkEof,
|
||||
|
|
@ -83,7 +83,7 @@ type
|
|||
tkBracketRi,
|
||||
tkColon,
|
||||
tkComma
|
||||
|
||||
|
||||
JsonError* = enum ## enumeration that lists all errors that can occur
|
||||
errNone, ## no error
|
||||
errInvalidToken, ## invalid token
|
||||
|
|
@ -96,8 +96,8 @@ type
|
|||
errEOC_Expected, ## ``*/`` expected
|
||||
errEofExpected, ## EOF expected
|
||||
errExprExpected ## expr expected
|
||||
|
||||
ParserState = enum
|
||||
|
||||
ParserState = enum
|
||||
stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
|
||||
stateExpectObjectComma, stateExpectColon, stateExpectValue
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ type
|
|||
|
||||
{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
|
||||
TJsonParser: JsonParser].}
|
||||
|
||||
|
||||
const
|
||||
errorMessages: array [JsonError, string] = [
|
||||
"no error",
|
||||
|
|
@ -146,56 +146,56 @@ proc open*(my: var JsonParser, input: Stream, filename: string) =
|
|||
my.state = @[stateStart]
|
||||
my.kind = jsonError
|
||||
my.a = ""
|
||||
|
||||
proc close*(my: var JsonParser) {.inline.} =
|
||||
|
||||
proc close*(my: var JsonParser) {.inline.} =
|
||||
## closes the parser `my` and its associated input stream.
|
||||
lexbase.close(my)
|
||||
|
||||
proc str*(my: JsonParser): string {.inline.} =
|
||||
## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
|
||||
proc str*(my: JsonParser): string {.inline.} =
|
||||
## returns the character data for the events: ``jsonInt``, ``jsonFloat``,
|
||||
## ``jsonString``
|
||||
assert(my.kind in {jsonInt, jsonFloat, jsonString})
|
||||
return my.a
|
||||
|
||||
proc getInt*(my: JsonParser): BiggestInt {.inline.} =
|
||||
proc getInt*(my: JsonParser): BiggestInt {.inline.} =
|
||||
## returns the number for the event: ``jsonInt``
|
||||
assert(my.kind == jsonInt)
|
||||
return parseBiggestInt(my.a)
|
||||
|
||||
proc getFloat*(my: JsonParser): float {.inline.} =
|
||||
proc getFloat*(my: JsonParser): float {.inline.} =
|
||||
## returns the number for the event: ``jsonFloat``
|
||||
assert(my.kind == jsonFloat)
|
||||
return parseFloat(my.a)
|
||||
|
||||
proc kind*(my: JsonParser): JsonEventKind {.inline.} =
|
||||
proc kind*(my: JsonParser): JsonEventKind {.inline.} =
|
||||
## returns the current event type for the JSON parser
|
||||
return my.kind
|
||||
|
||||
proc getColumn*(my: JsonParser): int {.inline.} =
|
||||
|
||||
proc getColumn*(my: JsonParser): int {.inline.} =
|
||||
## get the current column the parser has arrived at.
|
||||
result = getColNumber(my, my.bufpos)
|
||||
|
||||
proc getLine*(my: JsonParser): int {.inline.} =
|
||||
proc getLine*(my: JsonParser): int {.inline.} =
|
||||
## get the current line the parser has arrived at.
|
||||
result = my.lineNumber
|
||||
|
||||
proc getFilename*(my: JsonParser): string {.inline.} =
|
||||
proc getFilename*(my: JsonParser): string {.inline.} =
|
||||
## get the filename of the file that the parser processes.
|
||||
result = my.filename
|
||||
|
||||
proc errorMsg*(my: JsonParser): string =
|
||||
|
||||
proc errorMsg*(my: JsonParser): string =
|
||||
## returns a helpful error message for the event ``jsonError``
|
||||
assert(my.kind == jsonError)
|
||||
result = "$1($2, $3) Error: $4" % [
|
||||
my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]]
|
||||
|
||||
proc errorMsgExpected*(my: JsonParser, e: string): string =
|
||||
proc errorMsgExpected*(my: JsonParser, e: string): string =
|
||||
## returns an error message "`e` expected" in the same format as the
|
||||
## other error messages
|
||||
## other error messages
|
||||
result = "$1($2, $3) Error: $4" % [
|
||||
my.filename, $getLine(my), $getColumn(my), e & " expected"]
|
||||
|
||||
proc handleHexChar(c: char, x: var int): bool =
|
||||
proc handleHexChar(c: char, x: var int): bool =
|
||||
result = true # Success
|
||||
case c
|
||||
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
||||
|
|
@ -208,8 +208,8 @@ proc parseString(my: var JsonParser): TTokKind =
|
|||
var pos = my.bufpos + 1
|
||||
var buf = my.buf
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
my.err = errQuoteExpected
|
||||
result = tkError
|
||||
break
|
||||
|
|
@ -218,21 +218,21 @@ proc parseString(my: var JsonParser): TTokKind =
|
|||
break
|
||||
of '\\':
|
||||
case buf[pos+1]
|
||||
of '\\', '"', '\'', '/':
|
||||
of '\\', '"', '\'', '/':
|
||||
add(my.a, buf[pos+1])
|
||||
inc(pos, 2)
|
||||
of 'b':
|
||||
add(my.a, '\b')
|
||||
inc(pos, 2)
|
||||
inc(pos, 2)
|
||||
of 'f':
|
||||
add(my.a, '\f')
|
||||
inc(pos, 2)
|
||||
inc(pos, 2)
|
||||
of 'n':
|
||||
add(my.a, '\L')
|
||||
inc(pos, 2)
|
||||
inc(pos, 2)
|
||||
of 'r':
|
||||
add(my.a, '\C')
|
||||
inc(pos, 2)
|
||||
inc(pos, 2)
|
||||
of 't':
|
||||
add(my.a, '\t')
|
||||
inc(pos, 2)
|
||||
|
|
@ -244,15 +244,15 @@ proc parseString(my: var JsonParser): TTokKind =
|
|||
if handleHexChar(buf[pos], r): inc(pos)
|
||||
if handleHexChar(buf[pos], r): inc(pos)
|
||||
add(my.a, toUTF8(Rune(r)))
|
||||
else:
|
||||
else:
|
||||
# don't bother with the error
|
||||
add(my.a, buf[pos])
|
||||
inc(pos)
|
||||
of '\c':
|
||||
of '\c':
|
||||
pos = lexbase.handleCR(my, pos)
|
||||
buf = my.buf
|
||||
add(my.a, '\c')
|
||||
of '\L':
|
||||
of '\L':
|
||||
pos = lexbase.handleLF(my, pos)
|
||||
buf = my.buf
|
||||
add(my.a, '\L')
|
||||
|
|
@ -260,25 +260,25 @@ proc parseString(my: var JsonParser): TTokKind =
|
|||
add(my.a, buf[pos])
|
||||
inc(pos)
|
||||
my.bufpos = pos # store back
|
||||
|
||||
proc skip(my: var JsonParser) =
|
||||
|
||||
proc skip(my: var JsonParser) =
|
||||
var pos = my.bufpos
|
||||
var buf = my.buf
|
||||
while true:
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '/':
|
||||
if buf[pos+1] == '/':
|
||||
of '/':
|
||||
if buf[pos+1] == '/':
|
||||
# skip line comment:
|
||||
inc(pos, 2)
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
break
|
||||
of '\c':
|
||||
of '\c':
|
||||
pos = lexbase.handleCR(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
of '\L':
|
||||
of '\L':
|
||||
pos = lexbase.handleLF(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
|
|
@ -288,44 +288,44 @@ proc skip(my: var JsonParser) =
|
|||
# skip long comment:
|
||||
inc(pos, 2)
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
case buf[pos]
|
||||
of '\0':
|
||||
my.err = errEOC_Expected
|
||||
break
|
||||
of '\c':
|
||||
of '\c':
|
||||
pos = lexbase.handleCR(my, pos)
|
||||
buf = my.buf
|
||||
of '\L':
|
||||
of '\L':
|
||||
pos = lexbase.handleLF(my, pos)
|
||||
buf = my.buf
|
||||
of '*':
|
||||
inc(pos)
|
||||
if buf[pos] == '/':
|
||||
if buf[pos] == '/':
|
||||
inc(pos)
|
||||
break
|
||||
else:
|
||||
inc(pos)
|
||||
else:
|
||||
else:
|
||||
break
|
||||
of ' ', '\t':
|
||||
of ' ', '\t':
|
||||
inc(pos)
|
||||
of '\c':
|
||||
of '\c':
|
||||
pos = lexbase.handleCR(my, pos)
|
||||
buf = my.buf
|
||||
of '\L':
|
||||
of '\L':
|
||||
pos = lexbase.handleLF(my, pos)
|
||||
buf = my.buf
|
||||
else:
|
||||
break
|
||||
my.bufpos = pos
|
||||
|
||||
proc parseNumber(my: var JsonParser) =
|
||||
proc parseNumber(my: var JsonParser) =
|
||||
var pos = my.bufpos
|
||||
var buf = my.buf
|
||||
if buf[pos] == '-':
|
||||
if buf[pos] == '-':
|
||||
add(my.a, '-')
|
||||
inc(pos)
|
||||
if buf[pos] == '.':
|
||||
if buf[pos] == '.':
|
||||
add(my.a, "0.")
|
||||
inc(pos)
|
||||
else:
|
||||
|
|
@ -350,7 +350,7 @@ proc parseNumber(my: var JsonParser) =
|
|||
inc(pos)
|
||||
my.bufpos = pos
|
||||
|
||||
proc parseName(my: var JsonParser) =
|
||||
proc parseName(my: var JsonParser) =
|
||||
var pos = my.bufpos
|
||||
var buf = my.buf
|
||||
if buf[pos] in IdentStartChars:
|
||||
|
|
@ -359,11 +359,11 @@ proc parseName(my: var JsonParser) =
|
|||
inc(pos)
|
||||
my.bufpos = pos
|
||||
|
||||
proc getTok(my: var JsonParser): TTokKind =
|
||||
proc getTok(my: var JsonParser): TTokKind =
|
||||
setLen(my.a, 0)
|
||||
skip(my) # skip whitespace, comments
|
||||
case my.buf[my.bufpos]
|
||||
of '-', '.', '0'..'9':
|
||||
of '-', '.', '0'..'9':
|
||||
parseNumber(my)
|
||||
if {'.', 'e', 'E'} in my.a:
|
||||
result = tkFloat
|
||||
|
|
@ -393,17 +393,17 @@ proc getTok(my: var JsonParser): TTokKind =
|
|||
result = tkEof
|
||||
of 'a'..'z', 'A'..'Z', '_':
|
||||
parseName(my)
|
||||
case my.a
|
||||
case my.a
|
||||
of "null": result = tkNull
|
||||
of "true": result = tkTrue
|
||||
of "false": result = tkFalse
|
||||
else: result = tkError
|
||||
else:
|
||||
else:
|
||||
inc(my.bufpos)
|
||||
result = tkError
|
||||
my.tok = result
|
||||
|
||||
proc next*(my: var JsonParser) =
|
||||
proc next*(my: var JsonParser) =
|
||||
## retrieves the first/next event. This controls the parser.
|
||||
var tk = getTok(my)
|
||||
var i = my.state.len-1
|
||||
|
|
@ -416,13 +416,13 @@ proc next*(my: var JsonParser) =
|
|||
else:
|
||||
my.kind = jsonError
|
||||
my.err = errEofExpected
|
||||
of stateStart:
|
||||
# tokens allowed?
|
||||
of stateStart:
|
||||
# tokens allowed?
|
||||
case tk
|
||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||
my.state[i] = stateEof # expect EOF next!
|
||||
my.kind = JsonEventKind(ord(tk))
|
||||
of tkBracketLe:
|
||||
of tkBracketLe:
|
||||
my.state.add(stateArray) # we expect any
|
||||
my.kind = jsonArrayStart
|
||||
of tkCurlyLe:
|
||||
|
|
@ -433,12 +433,12 @@ proc next*(my: var JsonParser) =
|
|||
else:
|
||||
my.kind = jsonError
|
||||
my.err = errEofExpected
|
||||
of stateObject:
|
||||
of stateObject:
|
||||
case tk
|
||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||
my.state.add(stateExpectColon)
|
||||
my.kind = JsonEventKind(ord(tk))
|
||||
of tkBracketLe:
|
||||
of tkBracketLe:
|
||||
my.state.add(stateExpectColon)
|
||||
my.state.add(stateArray)
|
||||
my.kind = jsonArrayStart
|
||||
|
|
@ -457,7 +457,7 @@ proc next*(my: var JsonParser) =
|
|||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||
my.state.add(stateExpectArrayComma) # expect value next!
|
||||
my.kind = JsonEventKind(ord(tk))
|
||||
of tkBracketLe:
|
||||
of tkBracketLe:
|
||||
my.state.add(stateExpectArrayComma)
|
||||
my.state.add(stateArray)
|
||||
my.kind = jsonArrayStart
|
||||
|
|
@ -472,8 +472,8 @@ proc next*(my: var JsonParser) =
|
|||
my.kind = jsonError
|
||||
my.err = errBracketRiExpected
|
||||
of stateExpectArrayComma:
|
||||
case tk
|
||||
of tkComma:
|
||||
case tk
|
||||
of tkComma:
|
||||
discard my.state.pop()
|
||||
next(my)
|
||||
of tkBracketRi:
|
||||
|
|
@ -484,8 +484,8 @@ proc next*(my: var JsonParser) =
|
|||
my.kind = jsonError
|
||||
my.err = errBracketRiExpected
|
||||
of stateExpectObjectComma:
|
||||
case tk
|
||||
of tkComma:
|
||||
case tk
|
||||
of tkComma:
|
||||
discard my.state.pop()
|
||||
next(my)
|
||||
of tkCurlyRi:
|
||||
|
|
@ -495,9 +495,9 @@ proc next*(my: var JsonParser) =
|
|||
else:
|
||||
my.kind = jsonError
|
||||
my.err = errCurlyRiExpected
|
||||
of stateExpectColon:
|
||||
case tk
|
||||
of tkColon:
|
||||
of stateExpectColon:
|
||||
case tk
|
||||
of tkColon:
|
||||
my.state[i] = stateExpectValue
|
||||
next(my)
|
||||
else:
|
||||
|
|
@ -508,7 +508,7 @@ proc next*(my: var JsonParser) =
|
|||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||
my.state[i] = stateExpectObjectComma
|
||||
my.kind = JsonEventKind(ord(tk))
|
||||
of tkBracketLe:
|
||||
of tkBracketLe:
|
||||
my.state[i] = stateExpectObjectComma
|
||||
my.state.add(stateArray)
|
||||
my.kind = jsonArrayStart
|
||||
|
|
@ -532,8 +532,8 @@ type
|
|||
JString,
|
||||
JObject,
|
||||
JArray
|
||||
|
||||
JsonNode* = ref JsonNodeObj ## JSON node
|
||||
|
||||
JsonNode* = ref JsonNodeObj ## JSON node
|
||||
JsonNodeObj* {.acyclic.} = object
|
||||
case kind*: JsonNodeKind
|
||||
of JString:
|
||||
|
|
@ -644,7 +644,7 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
|||
newSeq(result.elems, elements.len)
|
||||
for i, p in pairs(elements): result.elems[i] = p
|
||||
|
||||
proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||
proc toJson(x: NimNode): NimNode {.compiletime.} =
|
||||
case x.kind
|
||||
of nnkBracket:
|
||||
result = newNimNode(nnkBracket)
|
||||
|
|
@ -672,7 +672,7 @@ proc `==`* (a,b: JsonNode): bool =
|
|||
if a.isNil:
|
||||
if b.isNil: return true
|
||||
return false
|
||||
elif b.isNil or a.kind != b.kind:
|
||||
elif b.isNil or a.kind != b.kind:
|
||||
return false
|
||||
else:
|
||||
return case a.kind
|
||||
|
|
@ -709,7 +709,7 @@ proc hash* (n:JsonNode): THash =
|
|||
of JNull:
|
||||
result = hash(0)
|
||||
|
||||
proc len*(n: JsonNode): int =
|
||||
proc len*(n: JsonNode): int =
|
||||
## If `n` is a `JArray`, it returns the number of elements.
|
||||
## If `n` is a `JObject`, it returns the number of pairs.
|
||||
## Else it returns 0.
|
||||
|
|
@ -727,7 +727,7 @@ proc `[]`*(node: JsonNode, name: string): JsonNode =
|
|||
if key == name:
|
||||
return item
|
||||
return nil
|
||||
|
||||
|
||||
proc `[]`*(node: JsonNode, index: int): JsonNode =
|
||||
## Gets the node at `index` in an Array. Result is undefined if `index`
|
||||
## is out of bounds
|
||||
|
|
@ -744,12 +744,12 @@ proc hasKey*(node: JsonNode, key: string): bool =
|
|||
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
||||
## Deprecated for `hasKey`
|
||||
|
||||
proc add*(father, child: JsonNode) =
|
||||
## Adds `child` to a JArray node `father`.
|
||||
proc add*(father, child: JsonNode) =
|
||||
## Adds `child` to a JArray node `father`.
|
||||
assert father.kind == JArray
|
||||
father.elems.add(child)
|
||||
|
||||
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
||||
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
||||
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
||||
## reasons no check for duplicate keys is performed!
|
||||
## But ``[]=`` performs the check.
|
||||
|
|
@ -760,7 +760,7 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) =
|
|||
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
||||
assert(obj.kind == JObject)
|
||||
for i in 0..obj.fields.len-1:
|
||||
if obj.fields[i].key == key:
|
||||
if obj.fields[i].key == key:
|
||||
obj.fields[i].val = val
|
||||
return
|
||||
obj.fields.add((key, val))
|
||||
|
|
@ -815,17 +815,17 @@ proc copy*(p: JsonNode): JsonNode =
|
|||
|
||||
# ------------- pretty printing ----------------------------------------------
|
||||
|
||||
proc indent(s: var string, i: int) =
|
||||
proc indent(s: var string, i: int) =
|
||||
s.add(spaces(i))
|
||||
|
||||
proc newIndent(curr, indent: int, ml: bool): int =
|
||||
if ml: return curr + indent
|
||||
else: return indent
|
||||
|
||||
proc nl(s: var string, ml: bool) =
|
||||
proc nl(s: var string, ml: bool) =
|
||||
if ml: s.add("\n")
|
||||
|
||||
proc escapeJson*(s: string): string =
|
||||
proc escapeJson*(s: string): string =
|
||||
## Converts a string `s` to its JSON representation.
|
||||
result = newStringOfCap(s.len + s.len shr 3)
|
||||
result.add("\"")
|
||||
|
|
@ -842,13 +842,13 @@ proc escapeJson*(s: string): string =
|
|||
result.add(toHex(r, 4))
|
||||
result.add("\"")
|
||||
|
||||
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||
lstArr = false, currIndent = 0) =
|
||||
case node.kind
|
||||
of JObject:
|
||||
if currIndent != 0 and not lstArr: result.nl(ml)
|
||||
result.indent(currIndent) # Indentation
|
||||
if node.fields.len > 0:
|
||||
if node.fields.len > 0:
|
||||
result.add("{")
|
||||
result.nl(ml) # New line
|
||||
for i in 0..len(node.fields)-1:
|
||||
|
|
@ -856,17 +856,17 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
|||
result.add(", ")
|
||||
result.nl(ml) # New Line
|
||||
# Need to indent more than {
|
||||
result.indent(newIndent(currIndent, indent, ml))
|
||||
result.indent(newIndent(currIndent, indent, ml))
|
||||
result.add(escapeJson(node.fields[i].key))
|
||||
result.add(": ")
|
||||
toPretty(result, node.fields[i].val, indent, ml, false,
|
||||
toPretty(result, node.fields[i].val, indent, ml, false,
|
||||
newIndent(currIndent, indent, ml))
|
||||
result.nl(ml)
|
||||
result.indent(currIndent) # indent the same as {
|
||||
result.add("}")
|
||||
else:
|
||||
result.add("{}")
|
||||
of JString:
|
||||
of JString:
|
||||
if lstArr: result.indent(currIndent)
|
||||
result.add(escapeJson(node.str))
|
||||
of JInt:
|
||||
|
|
@ -934,11 +934,11 @@ iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
|
|||
for keyVal in mitems(node.fields):
|
||||
yield keyVal
|
||||
|
||||
proc eat(p: var JsonParser, tok: TTokKind) =
|
||||
proc eat(p: var JsonParser, tok: TTokKind) =
|
||||
if p.tok == tok: discard getTok(p)
|
||||
else: raiseParseErr(p, tokToStr[tok])
|
||||
|
||||
proc parseJson(p: var JsonParser): JsonNode =
|
||||
proc parseJson(p: var JsonParser): JsonNode =
|
||||
## Parses JSON from a JSON Parser `p`.
|
||||
case p.tok
|
||||
of tkString:
|
||||
|
|
@ -955,17 +955,17 @@ proc parseJson(p: var JsonParser): JsonNode =
|
|||
of tkTrue:
|
||||
result = newJBool(true)
|
||||
discard getTok(p)
|
||||
of tkFalse:
|
||||
of tkFalse:
|
||||
result = newJBool(false)
|
||||
discard getTok(p)
|
||||
of tkNull:
|
||||
of tkNull:
|
||||
result = newJNull()
|
||||
discard getTok(p)
|
||||
of tkCurlyLe:
|
||||
of tkCurlyLe:
|
||||
result = newJObject()
|
||||
discard getTok(p)
|
||||
while p.tok != tkCurlyRi:
|
||||
if p.tok != tkString:
|
||||
while p.tok != tkCurlyRi:
|
||||
if p.tok != tkString:
|
||||
raiseParseErr(p, "string literal as key expected")
|
||||
var key = p.a
|
||||
discard getTok(p)
|
||||
|
|
@ -978,7 +978,7 @@ proc parseJson(p: var JsonParser): JsonNode =
|
|||
of tkBracketLe:
|
||||
result = newJArray()
|
||||
discard getTok(p)
|
||||
while p.tok != tkBracketRi:
|
||||
while p.tok != tkBracketRi:
|
||||
result.add(parseJson(p))
|
||||
if p.tok != tkComma: break
|
||||
discard getTok(p)
|
||||
|
|
@ -1098,10 +1098,10 @@ when false:
|
|||
of jsonObjectEnd: echo("}")
|
||||
of jsonArrayStart: echo("[")
|
||||
of jsonArrayEnd: echo("]")
|
||||
|
||||
|
||||
close(x)
|
||||
|
||||
# { "json": 5 }
|
||||
# { "json": 5 }
|
||||
# To get that we shall use, obj["json"]
|
||||
|
||||
when isMainModule:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ type
|
|||
|
||||
{.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]}
|
||||
|
||||
var
|
||||
var
|
||||
abortOnError* {.threadvar.}: bool
|
||||
outputLevel* {.threadvar.}: OutputLevel
|
||||
colorOutput* {.threadvar.}: bool
|
||||
|
|
@ -144,7 +144,7 @@ macro check*(conditions: stmt): stmt {.immediate.} =
|
|||
when compiles(string($value)):
|
||||
checkpoint(name & " was " & $value)
|
||||
|
||||
proc inspectArgs(exp: PNimrodNode) =
|
||||
proc inspectArgs(exp: NimNode) =
|
||||
for i in 1 .. <exp.len:
|
||||
if exp[i].kind notin nnkLiterals:
|
||||
inc counter
|
||||
|
|
@ -202,7 +202,7 @@ template require*(conditions: stmt): stmt {.immediate, dirty.} =
|
|||
macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
||||
let exp = callsite()
|
||||
template expectBody(errorTypes, lineInfoLit: expr,
|
||||
body: stmt): PNimrodNode {.dirty.} =
|
||||
body: stmt): NimNode {.dirty.} =
|
||||
try:
|
||||
body
|
||||
checkpoint(lineInfoLit & ": Expect Failed, no exception was thrown.")
|
||||
|
|
|
|||
|
|
@ -12,20 +12,20 @@
|
|||
import macros, strtabs
|
||||
|
||||
type
|
||||
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
|
||||
|
||||
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s.
|
||||
|
||||
XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
||||
xnText, ## a text element
|
||||
xnElement, ## an element with 0 or more children
|
||||
xnCData, ## a CDATA node
|
||||
xnEntity, ## an entity (like ``&thing;``)
|
||||
xnComment ## an XML comment
|
||||
|
||||
|
||||
XmlAttributes* = StringTableRef ## an alias for a string to string mapping
|
||||
|
||||
XmlNodeObj {.acyclic.} = object
|
||||
|
||||
XmlNodeObj {.acyclic.} = object
|
||||
case k: XmlNodeKind # private, use the kind() proc to read this field.
|
||||
of xnText, xnComment, xnCData, xnEntity:
|
||||
of xnText, xnComment, xnCData, xnEntity:
|
||||
fText: string
|
||||
of xnElement:
|
||||
fTag: string
|
||||
|
|
@ -41,34 +41,34 @@ proc newXmlNode(kind: XmlNodeKind): XmlNode =
|
|||
new(result)
|
||||
result.k = kind
|
||||
|
||||
proc newElement*(tag: string): XmlNode =
|
||||
proc newElement*(tag: string): XmlNode =
|
||||
## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
|
||||
result = newXmlNode(xnElement)
|
||||
result.fTag = tag
|
||||
result.s = @[]
|
||||
# init attributes lazily to safe memory
|
||||
|
||||
proc newText*(text: string): XmlNode =
|
||||
proc newText*(text: string): XmlNode =
|
||||
## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`.
|
||||
result = newXmlNode(xnText)
|
||||
result.fText = text
|
||||
|
||||
proc newComment*(comment: string): XmlNode =
|
||||
proc newComment*(comment: string): XmlNode =
|
||||
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`.
|
||||
result = newXmlNode(xnComment)
|
||||
result.fText = comment
|
||||
|
||||
proc newCData*(cdata: string): XmlNode =
|
||||
proc newCData*(cdata: string): XmlNode =
|
||||
## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`.
|
||||
result = newXmlNode(xnCData)
|
||||
result.fText = cdata
|
||||
|
||||
proc newEntity*(entity: string): XmlNode =
|
||||
proc newEntity*(entity: string): XmlNode =
|
||||
## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`.
|
||||
result = newXmlNode(xnCData)
|
||||
result.fText = entity
|
||||
|
||||
proc text*(n: XmlNode): string {.inline.} =
|
||||
proc text*(n: XmlNode): string {.inline.} =
|
||||
## gets the associated text with the node `n`. `n` can be a CDATA, Text,
|
||||
## comment, or entity node.
|
||||
assert n.k in {xnText, xnComment, xnCData, xnEntity}
|
||||
|
|
@ -93,16 +93,16 @@ proc innerText*(n: XmlNode): string =
|
|||
for i in 0 .. n.s.len-1:
|
||||
if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText)
|
||||
|
||||
proc tag*(n: XmlNode): string {.inline.} =
|
||||
proc tag*(n: XmlNode): string {.inline.} =
|
||||
## gets the tag name of `n`. `n` has to be an ``xnElement`` node.
|
||||
assert n.k == xnElement
|
||||
result = n.fTag
|
||||
|
||||
proc add*(father, son: XmlNode) {.inline.} =
|
||||
|
||||
proc add*(father, son: XmlNode) {.inline.} =
|
||||
## adds the child `son` to `father`.
|
||||
add(father.s, son)
|
||||
|
||||
proc len*(n: XmlNode): int {.inline.} =
|
||||
|
||||
proc len*(n: XmlNode): int {.inline.} =
|
||||
## returns the number `n`'s children.
|
||||
if n.k == xnElement: result = len(n.s)
|
||||
|
||||
|
|
@ -110,38 +110,38 @@ proc kind*(n: XmlNode): XmlNodeKind {.inline.} =
|
|||
## returns `n`'s kind.
|
||||
result = n.k
|
||||
|
||||
proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
|
||||
proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} =
|
||||
## returns the `i`'th child of `n`.
|
||||
assert n.k == xnElement
|
||||
result = n.s[i]
|
||||
|
||||
proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} =
|
||||
proc mget* (n: var XmlNode, i: int): var XmlNode {.inline.} =
|
||||
## returns the `i`'th child of `n` so that it can be modified
|
||||
assert n.k == xnElement
|
||||
result = n.s[i]
|
||||
|
||||
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
||||
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
||||
## iterates over any child of `n`.
|
||||
assert n.k == xnElement
|
||||
for i in 0 .. n.len-1: yield n[i]
|
||||
|
||||
iterator mitems*(n: var XmlNode): var XmlNode {.inline.} =
|
||||
iterator mitems*(n: var XmlNode): var XmlNode {.inline.} =
|
||||
## iterates over any child of `n`.
|
||||
assert n.k == xnElement
|
||||
for i in 0 .. n.len-1: yield mget(n, i)
|
||||
|
||||
proc attrs*(n: XmlNode): XmlAttributes {.inline.} =
|
||||
proc attrs*(n: XmlNode): XmlAttributes {.inline.} =
|
||||
## gets the attributes belonging to `n`.
|
||||
## Returns `nil` if attributes have not been initialised for this node.
|
||||
assert n.k == xnElement
|
||||
result = n.fAttr
|
||||
|
||||
proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} =
|
||||
|
||||
proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} =
|
||||
## sets the attributes belonging to `n`.
|
||||
assert n.k == xnElement
|
||||
n.fAttr = attr
|
||||
|
||||
proc attrsLen*(n: XmlNode): int {.inline.} =
|
||||
proc attrsLen*(n: XmlNode): int {.inline.} =
|
||||
## returns the number of `n`'s attributes.
|
||||
assert n.k == xnElement
|
||||
if not isNil(n.fAttr): result = len(n.fAttr)
|
||||
|
|
@ -151,12 +151,12 @@ proc clientData*(n: XmlNode): int {.inline.} =
|
|||
## parser and generator.
|
||||
result = n.fClientData
|
||||
|
||||
proc `clientData=`*(n: XmlNode, data: int) {.inline.} =
|
||||
proc `clientData=`*(n: XmlNode, data: int) {.inline.} =
|
||||
## sets the client data of `n`. The client data field is used by the HTML
|
||||
## parser and generator.
|
||||
n.fClientData = data
|
||||
|
||||
proc addEscaped*(result: var string, s: string) =
|
||||
proc addEscaped*(result: var string, s: string) =
|
||||
## same as ``result.add(escape(s))``, but more efficient.
|
||||
for c in items(s):
|
||||
case c
|
||||
|
|
@ -168,8 +168,8 @@ proc addEscaped*(result: var string, s: string) =
|
|||
of '/': result.add("/")
|
||||
else: result.add(c)
|
||||
|
||||
proc escape*(s: string): string =
|
||||
## escapes `s` for inclusion into an XML document.
|
||||
proc escape*(s: string): string =
|
||||
## escapes `s` for inclusion into an XML document.
|
||||
## Escapes these characters:
|
||||
##
|
||||
## ------------ -------------------
|
||||
|
|
@ -184,26 +184,26 @@ proc escape*(s: string): string =
|
|||
## ------------ -------------------
|
||||
result = newStringOfCap(s.len)
|
||||
addEscaped(result, s)
|
||||
|
||||
proc addIndent(result: var string, indent: int) =
|
||||
|
||||
proc addIndent(result: var string, indent: int) =
|
||||
result.add("\n")
|
||||
for i in 1..indent: result.add(' ')
|
||||
|
||||
|
||||
proc noWhitespace(n: XmlNode): bool =
|
||||
#for i in 1..n.len-1:
|
||||
# if n[i].kind != n[0].kind: return true
|
||||
for i in 0..n.len-1:
|
||||
if n[i].kind in {xnText, xnEntity}: return true
|
||||
|
||||
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||
|
||||
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||
## adds the textual representation of `n` to `result`.
|
||||
if n == nil: return
|
||||
case n.k
|
||||
of xnElement:
|
||||
result.add('<')
|
||||
result.add(n.fTag)
|
||||
if not isNil(n.fAttr):
|
||||
for key, val in pairs(n.fAttr):
|
||||
if not isNil(n.fAttr):
|
||||
for key, val in pairs(n.fAttr):
|
||||
result.add(' ')
|
||||
result.add(key)
|
||||
result.add("=\"")
|
||||
|
|
@ -217,7 +217,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
|||
# because this would be wrong. For example: ``a<b>b</b>`` is
|
||||
# different from ``a <b>b</b>``.
|
||||
for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
|
||||
else:
|
||||
else:
|
||||
for i in 0..n.len-1:
|
||||
result.addIndent(indent+indWidth)
|
||||
result.add(n[i], indent+indWidth, indWidth)
|
||||
|
|
@ -227,7 +227,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
|||
result.add("</")
|
||||
result.add(n.fTag)
|
||||
result.add(">")
|
||||
else:
|
||||
else:
|
||||
result.add(" />")
|
||||
of xnText:
|
||||
result.addEscaped(n.fText)
|
||||
|
|
@ -245,7 +245,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
|||
result.add(';')
|
||||
|
||||
const
|
||||
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||
## header to use for complete XML output
|
||||
|
||||
proc `$`*(n: XmlNode): string =
|
||||
|
|
@ -255,21 +255,21 @@ proc `$`*(n: XmlNode): string =
|
|||
result.add(n)
|
||||
|
||||
proc newXmlTree*(tag: string, children: openArray[XmlNode],
|
||||
attributes: XmlAttributes = nil): XmlNode =
|
||||
attributes: XmlAttributes = nil): XmlNode =
|
||||
## creates a new XML tree with `tag`, `children` and `attributes`
|
||||
result = newXmlNode(xnElement)
|
||||
result.fTag = tag
|
||||
newSeq(result.s, children.len)
|
||||
for i in 0..children.len-1: result.s[i] = children[i]
|
||||
result.fAttr = attributes
|
||||
|
||||
proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
|
||||
proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
|
||||
expectLen(e, 2)
|
||||
var a = e[1]
|
||||
if a.kind == nnkCall:
|
||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||
var attrs = newNimNode(nnkBracket, a)
|
||||
var newStringTabCall = newCall("newStringTable", attrs,
|
||||
var newStringTabCall = newCall("newStringTable", attrs,
|
||||
newIdentNode("modeCaseSensitive"))
|
||||
var elements = newNimNode(nnkBracket, a)
|
||||
for i in 1..a.len-1:
|
||||
|
|
@ -280,13 +280,13 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
|||
else:
|
||||
elements.add(a[i])
|
||||
result.add(elements)
|
||||
if attrs.len > 1:
|
||||
if attrs.len > 1:
|
||||
#echo repr(newStringTabCall)
|
||||
result.add(newStringTabCall)
|
||||
else:
|
||||
result = newCall("newXmlTree", toStrLit(a))
|
||||
|
||||
macro `<>`*(x: expr): expr {.immediate.} =
|
||||
macro `<>`*(x: expr): expr {.immediate.} =
|
||||
## Constructor macro for XML. Example usage:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue