Added YamlParser.display()

* renders events with proper tag and anchor names
This commit is contained in:
Felix Krause 2017-02-14 19:40:40 +01:00
parent 58ef5da17b
commit c581f1acc2
4 changed files with 56 additions and 14 deletions

View File

@ -35,7 +35,7 @@ routes:
output = "+STR\n"
parser = newYamlParser()
events = parser.parse(newStringStream(@"input"))
for event in events: output.add($event & "\n")
for event in events: output.add(parser.display(event) & "\n")
output &= "-STR"
resultNode["code"] = %0
resultNode["output"] = %output

View File

@ -1083,3 +1083,46 @@ proc anchorName*(p: YamlParser, anchor: AnchorId): string {.raises: [].} =
for representation, value in p.anchors:
if value == anchor: return representation
return ""
proc renderAttrs(p: YamlParser, tag: TagId, anchor: AnchorId): string =
result = ""
case tag
of yTagQuestionmark: discard
of yTagExclamationmark: result = " !"
else:
let tagUri = p.taglib.uri(tag)
if tagUri.startsWith(yamlTagRepositoryPrefix):
result = " !!" & tagUri[yamlTagRepositoryPrefix.len..^1]
else:
result = " !<" & tagUri & ">"
proc display*(p: YamlParser, event: YamlStreamEvent): string
{.raises: [KeyError].} =
## Generate a representation of the given event with proper visualization of
## anchor and tag (if any). The generated representation is conformant to the
## format used in the yaml test suite.
##
## This proc is an informed version of ``$`` on ``YamlStreamEvent`` which can
## properly display the anchor and tag name as it occurs in the input.
## However, it shall only be used while using the streaming API because after
## finishing the parsing of a document, the parser drops all information about
## anchor and tag names.
case event.kind
of yamlEndMap: result = "-MAP"
of yamlEndSeq: result = "-SEQ"
of yamlStartDoc: result = "+DOC"
of yamlEndDoc: result = "-DOC"
of yamlStartMap: result = "+MAP" & p.renderAttrs(event.mapTag, event.mapAnchor)
of yamlStartSeq: result = "+SEQ" & p.renderAttrs(event.seqTag, event.seqAnchor)
of yamlScalar:
result = "=VAL" & p.renderAttrs(event.scalarTag, event.scalarAnchor)
when defined(yamlScalarRepInd):
case event.scalarRep
of srPlain: result &= " :"
of srSingleQuoted: result &= " \'"
of srDoubleQuoted: result &= " \""
of srLiteral: result &= " |"
of srFolded: result &= " >"
else: result &= " :"
result &= yamlTestSuiteEscape(event.scalarContent)
of yamlAlias: result = "=ALI *" & p.anchorName(event.aliasTarget)

View File

@ -27,3 +27,12 @@ template yAssert*(e: typed) =
except: discard
echo "[NimYAML] Please report this bug."
quit 1
proc yamlTestSuiteEscape*(s: string): string =
result = ""
for c in s:
case c
of '\l': result.add("\\n")
of '\c': result.add("\\c")
of '\\': result.add("\\\\")
else: result.add(c)

View File

@ -253,19 +253,9 @@ proc renderAttrs(tag: TagId, anchor: AnchorId): string =
else: result &= " !<" & $tag & ">"
if anchor != yAnchorNone: result &= " &" & $anchor
proc yamlEscape(s: string): string =
result = ""
for c in s:
case c
of '\l': result.add("\\n")
of '\c': result.add("\\c")
of '\\': result.add("\\\\")
else: result.add(c)
proc `$`*(event: YamlStreamEvent): string {.raises: [].} =
## outputs a human-readable string describing the given event.
## This string is compatible to the format used in the yaml test suite.
result = $event.kind & '('
case event.kind
of yamlEndMap: result = "-MAP"
of yamlEndSeq: result = "-SEQ"
@ -283,7 +273,7 @@ proc `$`*(event: YamlStreamEvent): string {.raises: [].} =
of srLiteral: result &= " |"
of srFolded: result &= " >"
else: result &= " :"
result &= yamlEscape(event.scalarContent)
result &= yamlTestSuiteEscape(event.scalarContent)
of yamlAlias: result = "=ALI *" & $event.aliasTarget
proc tag*(event: YamlStreamEvent): TagId {.raises: [FieldError].} =