From c581f1acc26d7ee446f9cf38be7e8748525207e6 Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Tue, 14 Feb 2017 19:40:40 +0100 Subject: [PATCH] Added YamlParser.display() * renders events with proper tag and anchor names --- server/server.nim | 2 +- yaml/parser.nim | 45 ++++++++++++++++++++++++++++++++++++++- yaml/private/internal.nim | 11 +++++++++- yaml/stream.nim | 12 +---------- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/server/server.nim b/server/server.nim index c353a81..398ae38 100644 --- a/server/server.nim +++ b/server/server.nim @@ -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 diff --git a/yaml/parser.nim b/yaml/parser.nim index 2855390..4b5ce26 100644 --- a/yaml/parser.nim +++ b/yaml/parser.nim @@ -1082,4 +1082,47 @@ proc anchorName*(p: YamlParser, anchor: AnchorId): string {.raises: [].} = ## anchors. for representation, value in p.anchors: if value == anchor: return representation - return "" \ No newline at end of file + 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) \ No newline at end of file diff --git a/yaml/private/internal.nim b/yaml/private/internal.nim index af74036..5179872 100644 --- a/yaml/private/internal.nim +++ b/yaml/private/internal.nim @@ -26,4 +26,13 @@ template yAssert*(e: typed) = try: writeStackTrace() except: discard echo "[NimYAML] Please report this bug." - quit 1 \ No newline at end of file + 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) \ No newline at end of file diff --git a/yaml/stream.nim b/yaml/stream.nim index c45faf0..d16948d 100644 --- a/yaml/stream.nim +++ b/yaml/stream.nim @@ -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].} =