diff --git a/.gitignore b/.gitignore index 2b7f03b..a345654 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,6 @@ libyaml.dylib libyaml.so bench/json docout +doc/rstPreproc +doc/tmp.rst yaml-dev-kit diff --git a/config.nims b/config.nims index 0d2610f..efa86f8 100644 --- a/config.nims +++ b/config.nims @@ -20,17 +20,21 @@ task serializationTests, "Run serialization tests": task documentation, "Generate documentation": exec "mkdir -p docout" + withDir "doc": + exec r"nim c rstPreproc" + exec r"./rstPreproc -o:tmp.rst index.txt" + exec r"nim rst2html -o:../docout/index.html tmp.rst" + exec r"./rstPreproc -o:tmp.rst api.txt" + exec r"nim rst2html -o:../docout/api.html tmp.rst" + exec r"./rstPreproc -o:tmp.rst serialization.txt" + exec r"nim rst2html -o:../docout/serialization.html tmp.rst" + exec "cp docutils.css style.css testing.html processing.svg ../docout" exec r"nim doc2 -o:docout/yaml.html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/`git log -n 1 --format=%H` yaml" - # bash! ah-ah \\ savior of the universe for file in listFiles("yaml"): let packageName = file[5..^5] exec r"nim doc2 -o:docout/yaml." & packageName & ".html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/yaml/`git log -n 1 --format=%H` " & file - exec r"nim rst2html -o:docout/index.html doc/index.txt" - exec r"nim rst2html -o:docout/api.html doc/api.txt" - exec r"nim rst2html -o:docout/serialization.html doc/serialization.txt" - exec "cp doc/docutils.css doc/style.css doc/testing.html doc/processing.svg docout" setCommand "nop" task bench, "Benchmarking": diff --git a/doc/examples/customtag.nim b/doc/examples/customtag.nim new file mode 100644 index 0000000..411fb58 --- /dev/null +++ b/doc/examples/customtag.nim @@ -0,0 +1,14 @@ +import yaml +type Mob = object + level, experience: int32 + drops: seq[string] + +setTagUri(Mob, "!Mob") +setTagUri(seq[string], "!Drops") + +var mob = Mob(level: 42, experience: 1800, drops: + @["Sword of Mob Slaying"]) +var s = newFileStream("out.yaml", fmWrite) +dump(mob, s, + options = defineOptions(tagStyle = tsAll)) +s.close() \ No newline at end of file diff --git a/doc/examples/customtag.out.yaml b/doc/examples/customtag.out.yaml new file mode 100644 index 0000000..cf6deba --- /dev/null +++ b/doc/examples/customtag.out.yaml @@ -0,0 +1,5 @@ +%YAML 1.2 +--- !Mob +!nim:field level: !nim:system:int32 42 +!nim:field experience: !nim:system:int32 1800 +!nim:field drops: !Drops [!!str Sword of Mob Slaying] \ No newline at end of file diff --git a/doc/examples/dump-json.nim b/doc/examples/dump-json.nim new file mode 100644 index 0000000..7b91553 --- /dev/null +++ b/doc/examples/dump-json.nim @@ -0,0 +1,13 @@ +import yaml +type Person = object + name : string + age : int32 + +var personList = newSeq[Person]() +personList.add(Person(name: "Karl Koch", age: 23)) +personList.add(Person(name: "Peter Pan", age: 12)) + +var s = newFileStream("out.yaml", fmWrite) +dump(personList, s, + options = defineOptions(style = psJson)) +s.close() \ No newline at end of file diff --git a/doc/examples/dump-json.out.yaml b/doc/examples/dump-json.out.yaml new file mode 100644 index 0000000..3be727c --- /dev/null +++ b/doc/examples/dump-json.out.yaml @@ -0,0 +1,10 @@ +[ + { + "name": "Karl Koch", + "age": 23 + }, + { + "name": "Peter Pan", + "age": 12 + } +] \ No newline at end of file diff --git a/doc/examples/dump-reftypes.nim b/doc/examples/dump-reftypes.nim new file mode 100644 index 0000000..0e97b6c --- /dev/null +++ b/doc/examples/dump-reftypes.nim @@ -0,0 +1,20 @@ +import yaml +type + Node = ref NodeObj + NodeObj = object + name: string + left, right: Node + +var node1, node2, node3: Node +new(node1); new(node2); new(node3) +node1.name = "Node 1" +node2.name = "Node 2" +node3.name = "Node 3" +node1.left = node2 +node1.right = node3 +node2.right = node3 +node3.left = node1 + +var s = newFileStream("out.yaml", fmWrite) +dump(node1, s) +s.close() \ No newline at end of file diff --git a/doc/examples/dump-reftypes.out.yaml b/doc/examples/dump-reftypes.out.yaml new file mode 100644 index 0000000..25e569e --- /dev/null +++ b/doc/examples/dump-reftypes.out.yaml @@ -0,0 +1,11 @@ +%YAML 1.2 +--- !nim:custom:NodeObj &a +name: Node 1 +left: + name: Node 2 + left: !!null ~ + right: &b + name: Node 3 + left: *a + right: !!null ~ +right: *b \ No newline at end of file diff --git a/doc/examples/dump-yaml.nim b/doc/examples/dump-yaml.nim new file mode 100644 index 0000000..b1bec26 --- /dev/null +++ b/doc/examples/dump-yaml.nim @@ -0,0 +1,12 @@ +import yaml +type Person = object + name : string + age : int32 + +var personList = newSeq[Person]() +personList.add(Person(name: "Karl Koch", age: 23)) +personList.add(Person(name: "Peter Pan", age: 12)) + +var s = newFileStream("out.yaml", fmWrite) +dump(personList, s) +s.close() \ No newline at end of file diff --git a/doc/examples/dump-yaml.out.yaml b/doc/examples/dump-yaml.out.yaml new file mode 100644 index 0000000..46d0583 --- /dev/null +++ b/doc/examples/dump-yaml.out.yaml @@ -0,0 +1,8 @@ +%YAML 1.2 +--- !nim:system:seq(nim:custom:Person) +- + name: Karl Koch + age: 23 +- + name: Peter Pan + age: 12 \ No newline at end of file diff --git a/doc/examples/implicit-variant.in.yaml b/doc/examples/implicit-variant.in.yaml new file mode 100644 index 0000000..aae04fc --- /dev/null +++ b/doc/examples/implicit-variant.in.yaml @@ -0,0 +1,8 @@ +%YAML 1.2 +--- +- this is a string +- 42 +- false +- !!str 23 +- !nim:demo:Person {name: Trillian} +- !!null \ No newline at end of file diff --git a/doc/examples/implicit-variant.nim b/doc/examples/implicit-variant.nim new file mode 100644 index 0000000..323c410 --- /dev/null +++ b/doc/examples/implicit-variant.nim @@ -0,0 +1,37 @@ +import yaml +type + Person = object + name: string + + ContainerKind = enum + ckString, ckInt, ckBool, ckPerson, ckNone + + Container = object + case kind: ContainerKind + of ckString: + strVal: string + of ckInt: + intVal: int + of ckBool: + boolVal: bool + of ckPerson: + personVal: Person + of ckNone: + discard + +setTagUri(Person, "!nim:demo:Person") + +# tell NimYAML to use Container as implicit type. +# only possible with variant object types where +# each branch contains at most one object. +markAsImplicit(Container) + +var list: seq[Container] + +var s = newFileStream("in.yaml") +load(s, list) +s.close() + +assert(list[0].kind == ckString) +assert(list[0].strVal == "this is a string") +# and so on \ No newline at end of file diff --git a/doc/examples/load-json.in.yaml b/doc/examples/load-json.in.yaml new file mode 100644 index 0000000..3be727c --- /dev/null +++ b/doc/examples/load-json.in.yaml @@ -0,0 +1,10 @@ +[ + { + "name": "Karl Koch", + "age": 23 + }, + { + "name": "Peter Pan", + "age": 12 + } +] \ No newline at end of file diff --git a/doc/examples/load-json.nim b/doc/examples/load-json.nim new file mode 100644 index 0000000..cf86f03 --- /dev/null +++ b/doc/examples/load-json.nim @@ -0,0 +1,10 @@ +import yaml +type Person = object + name : string + age : int32 + +var personList: seq[Person] + +var s = newFileStream("in.yaml") +load(s, personList) +s.close() \ No newline at end of file diff --git a/doc/examples/load-reftypes.in.yaml b/doc/examples/load-reftypes.in.yaml new file mode 100644 index 0000000..78d163b --- /dev/null +++ b/doc/examples/load-reftypes.in.yaml @@ -0,0 +1,11 @@ +%YAML 1.2 +--- !nim:custom:NodeObj &a +name: Node 1 +left: + name: Node 2 + left: ~ + right: &b + name: Node 3 + left: *a + right: ~ +right: *b \ No newline at end of file diff --git a/doc/examples/load-reftypes.nim b/doc/examples/load-reftypes.nim new file mode 100644 index 0000000..983ae94 --- /dev/null +++ b/doc/examples/load-reftypes.nim @@ -0,0 +1,12 @@ +import yaml +type + Node = ref NodeObj + NodeObj = object + name: string + left, right: Node + +var node1: Node + +var s = newFileStream("in.yaml") +load(s, node1) +s.close() \ No newline at end of file diff --git a/doc/examples/load-yaml.in.yaml b/doc/examples/load-yaml.in.yaml new file mode 100644 index 0000000..b918cbf --- /dev/null +++ b/doc/examples/load-yaml.in.yaml @@ -0,0 +1,4 @@ +%YAML 1.2 +--- +- { name: Karl Koch, age: 23 } +- { name: Peter Pan, age: 12 } \ No newline at end of file diff --git a/doc/examples/load-yaml.nim b/doc/examples/load-yaml.nim new file mode 100644 index 0000000..3ceb4ce --- /dev/null +++ b/doc/examples/load-yaml.nim @@ -0,0 +1,9 @@ +import yaml +type Person = object + name : string + age : int32 + +var personList: seq[Person] +var s = newFileStream("in.yaml") +load(s, personList) +s.close() \ No newline at end of file diff --git a/doc/examples/outputstyle.nim b/doc/examples/outputstyle.nim new file mode 100644 index 0000000..2e80785 --- /dev/null +++ b/doc/examples/outputstyle.nim @@ -0,0 +1,16 @@ +import yaml +type Person = object + name: string + age: int32 + +var personList: seq[Person] +personList.add(Person(name: "Karl Koch", age: 23)) +personList.add(Person(name: "Peter Pan", age: 12)) + +var s = newFileStream("out.yaml") +dump(personList, s, options = defineOptions( + style = psCanonical, + indentationStep = 3, + newlines = nlLF, + outputVersion = ov1_1)) +s.close() \ No newline at end of file diff --git a/doc/examples/outputstyle.out.yaml b/doc/examples/outputstyle.out.yaml new file mode 100644 index 0000000..76b4fc0 --- /dev/null +++ b/doc/examples/outputstyle.out.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +--- !nim:system:seq(nim:custom:Person) +[ + !nim:custom:Person { + ? !!str "name" + : !!str "Karl Koch", + ? !!str "age" + : !nim:system:int32 "23" + }, + !nim:custom:Person { + ? !!str "name" + : !!str "Peter Pan", + ? !!str "age" + : !nim:system:int32 "12" + } +] \ No newline at end of file diff --git a/doc/examples/quickstart.json b/doc/examples/quickstart.json new file mode 100644 index 0000000..b8efe1c --- /dev/null +++ b/doc/examples/quickstart.json @@ -0,0 +1,43 @@ +{ + "Dumping Nim objects as YAML": [ + "dump-yaml", "out" + ], + + "Loading Nim objects from YAML": [ + "load-yaml", "in" + ], + + "Customizing output style" : [ + "outputstyle", "out" + ], + + "Dumping reference types and cyclic structures": [ + "dump-reftypes", "out" + ], + + "Loading reference types and cyclic structures": [ + "load-reftypes", "in" + ], + + "Defining a custom tag uri for a type": [ + "customtag", "out" + ], + + "Dumping Nim objects as JSON": [ + "dump-json", "out" + ], + + "Loading Nim objects from JSON": [ + "load-json", "in" + ], + + "Processing a Sequence of Heterogeneous Items": { + "… With variant objects": [ + "implicit-variant", "in" + ], + + "… With the Sequential API": [ + "sequential-api", "in" + ] + } +} \ No newline at end of file diff --git a/doc/examples/sequential-api.in.yaml b/doc/examples/sequential-api.in.yaml new file mode 100644 index 0000000..8164e19 --- /dev/null +++ b/doc/examples/sequential-api.in.yaml @@ -0,0 +1,7 @@ +%YAML 1.2 +--- !!seq +- this is a string +- 42 +- false +- !!str 23 +- !nim:demo:Person {name: Trillian} \ No newline at end of file diff --git a/doc/examples/sequential-api.nim b/doc/examples/sequential-api.nim new file mode 100644 index 0000000..e1ada99 --- /dev/null +++ b/doc/examples/sequential-api.nim @@ -0,0 +1,51 @@ +import yaml +type Person = object + name: string + +setTagUri(Person, "!nim:demo:Person", yTagPerson) + +var + s = newFileStream("in.yaml", fmRead) + context = newConstructionContext() + parser = newYamlParser(serializationTagLibrary) + events = parser.parse(s) + +assert events.next().kind == yamlStartDoc +assert events.next().kind == yamlStartSeq +var nextEvent = events.peek() +while nextEvent.kind != yamlEndSeq: + var curTag = nextEvent.tag() + if curTag == yTagQuestionMark: + # we only support implicitly tagged scalars + assert nextEvent.kind == yamlScalar + case guessType(nextEvent.scalarContent) + of yTypeInteger: curTag = yTagInteger + of yTypeBoolTrue, yTypeBoolFalse: + curTag = yTagBoolean + of yTypeUnknown: curTag = yTagString + else: assert false, "Type not supported!" + elif curTag == yTagExclamationMark: + curTag = yTagString + case curTag + of yTagString: + var s: string + events.constructChild(context, s) + echo "got string: ", s + of yTagInteger: + var i: int32 + events.constructChild(context, i) + echo "got integer: ", i + of yTagBoolean: + var b: bool + events.constructChild(context, b) + echo "got boolean: ", b + of yTagPerson: + var p: Person + events.constructChild(context, p) + echo "got Person with name: ", p.name + else: assert false, "unsupported tag: " & $curTag + nextEvent = events.peek() +assert events.next().kind == yamlEndSeq +assert events.next().kind == yamlEndDoc +assert events.finished() +s.close() \ No newline at end of file diff --git a/doc/index.txt b/doc/index.txt index 57f6080..3bd71cd 100644 --- a/doc/index.txt +++ b/doc/index.txt @@ -19,465 +19,4 @@ install it with `Nimble `_: Quickstart ========== -Dumping Nim objects as YAML --------------------------- - -.. raw:: html - - -
code.nimout.yaml
- -.. code-block:: nim - import yaml - type Person = object - name : string - age : int32 - - var personList = newSeq[Person]() - personList.add(Person(name: "Karl Koch", age: 23)) - personList.add(Person(name: "Peter Pan", age: 12)) - - var s = newFileStream("out.yaml", fmWrite) - dump(personList, s) - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- !nim:system:seq(nim:custom:Person) - - - name: Karl Koch - age: 23 - - - name: Peter Pan - age: 12 - -.. raw:: html -
- -Loading Nim objects from YAML ----------------------------- - -.. raw:: html - - -
code.nimin.yaml
- -.. code-block:: nim - import yaml - type Person = object - name : string - age : int32 - - var personList: seq[Person] - var s = newFileStream("in.yaml") - load(s, personList) - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- - - { name: Karl Koch, age: 23 } - - { name: Peter Pan, age: 12 } - -.. raw:: html -
- -Customizing output style ----------------------- - -.. raw:: html - -
code.nimout.yaml
- -.. code-block:: nim - import yaml - type Person = object - name: string - age: int32 - - var personList: seq[Person] - personList.add(Person(name: "Karl Koch", age: 23)) - personList.add(Person(name: "Peter Pan", age: 12)) - - var s = newFileStream("out.yaml") - dump(personList, s, options = defineOptions( - style = psCanonical, - indentationStep = 3, - newlines = nlLF, - outputVersion = ov1_1)) - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.1 - --- !nim:system:seq(nim:custom:Person) - [ - !nim:custom:Person { - ? !!str "name" - : !!str "Karl Koch", - ? !!str "age" - : !nim:system:int32 "23" - }, - !nim:custom:Person { - ? !!str "name" - : !!str "Peter Pan", - ? !!str "age" - : !nim:system:int32 "12" - } - ] - -.. raw:: html -
- -Dumping reference types and cyclic structures ---------------------------------------------- - -.. raw:: html - -
code.nimout.yaml
- -.. code-block:: nim - import yaml - type - Node = ref NodeObj - NodeObj = object - name: string - left, right: Node - - var node1, node2, node3: Node - new(node1); new(node2); new(node3) - node1.name = "Node 1" - node2.name = "Node 2" - node3.name = "Node 3" - node1.left = node2 - node1.right = node3 - node2.right = node3 - node3.left = node1 - - var s = newFileStream("out.yaml", fmWrite) - dump(node1, s) - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- !nim:custom:NodeObj &a - name: Node 1 - left: - name: Node 2 - left: !!null ~ - right: &b - name: Node 3 - left: *a - right: !!null ~ - right: *b - -.. raw:: html -
- -Loading reference types and cyclic structures ---------------------------------------------- - -.. raw:: html - -
code.nimin.yaml
- -.. code-block:: nim - import yaml - type - Node = ref NodeObj - NodeObj = object - name: string - left, right: Node - - var node1: Node - - var s = newFileStream("in.yaml") - load(s, node1) - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- !nim:custom:NodeObj &a - name: Node 1 - left: - name: Node 2 - left: ~ - right: &b - name: Node 3 - left: *a - right: ~ - right: *b - -.. raw:: html -
- -Defining a custom tag uri for a type ------------------------------------- - -.. raw:: html - -
code.nimout.yaml
- -.. code-block:: nim - import yaml - type Mob = object - level, experience: int32 - drops: seq[string] - - setTagUri(Mob, "!Mob") - setTagUri(seq[string], "!Drops") - - var mob = Mob(level: 42, experience: 1800, drops: - @["Sword of Mob Slaying"]) - var s = newFileStream("out.yaml", fmWrite) - dump(mob, s, - options = defineOptions(tagStyle = tsAll)) - s.close() - -.. raw:: html - - -.. code-block:: yaml - YAML 1.2 - --- !Mob - !nim:field level: !nim:system:int32 42 - !nim:field experience: !nim:system:int32 1800 - !nim:field drops: !Drops [!!str Sword of Mob Slaying] - -.. raw:: html -
- -Dumping Nim objects as JSON ---------------------------- - -.. raw:: html - - -
code.nimout.yaml
- -.. code-block:: nim - import yaml - type Person = object - name : string - age : int32 - - var personList = newSeq[Person]() - personList.add(Person(name: "Karl Koch", age: 23)) - personList.add(Person(name: "Peter Pan", age: 12)) - - var s = newFileStream("out.yaml", fmWrite) - dump(personList, s, - options = defineOptions(style = psJson)) - s.close() - -.. raw:: html - - -.. code-block:: yaml - [ - { - "name": "Karl Koch", - "age": 23 - }, - { - "name": "Peter Pan", - "age": 12 - } - ] - -.. raw:: html -
- -Loading Nim objects from JSON ------------------------------ - -.. raw:: html - - -
code.nimin.yaml
- -.. code-block:: nim - import yaml - type Person = object - name : string - age : int32 - - var personList: seq[Person] - - var s = newFileStream("in.yaml") - load(s, personList) - s.close() - -.. raw:: html - - -.. code-block:: yaml - [ - { - "name": "Karl Koch", - "age": 23 - }, - { - "name": "Peter Pan", - "age": 12 - } - ] - -.. raw:: html -
- -Processing a Sequence of Heterogeneous Items --------------------------------------------- - -… With variant objects -...................... - -.. raw:: html - - -
code.nimin.yaml
- -.. code-block:: nim - import yaml - type - Person = object - name: string - - ContainerKind = enum - ckString, ckInt, ckBool, ckPerson, ckNone - - Container = object - case kind: ContainerKind - of ckString: - strVal: string - of ckInt: - intVal: int - of ckBool: - boolVal: bool - of ckPerson: - personVal: Person - of ckNone: - discard - - setTagUri(Person, "!nim:demo:Person") - - # tell NimYAML to use Container as implicit type. - # only possible with variant object types where - # each branch contains at most one object. - markAsImplicit(Container) - - var list: seq[Container] - - var s = newFileStream("in.yaml") - load(s, list) - s.close() - - assert(list[0].kind == ckString) - assert(list[0].strVal == "this is a string") - # and so on - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- - - this is a string - - 42 - - false - - !!str 23 - - !nim:demo:Person {name: Trillian} - - !!null - -.. raw:: html -
- -… With the Sequential API -......................... - -.. raw:: html - - -
code.nimin.yaml
- -.. code-block:: nim - import yaml - type Person = object - name: string - - setTagUri(Person, "!nim:demo:Person", yTagPerson) - - var - s = newFileStream("in.yaml", fmRead) - context = newConstructionContext() - parser = newYamlParser(serializationTagLibrary) - events = parser.parse(s) - - assert events.next().kind == yamlStartDoc - assert events.next().kind == yamlStartSeq - var nextEvent = events.peek() - while nextEvent.kind != yamlEndSeq: - var curTag = nextEvent.tag() - if curTag == yTagQuestionMark: - # we only support implicitly tagged scalars - assert nextEvent.kind == yamlScalar - case guessType(nextEvent.scalarContent) - of yTypeInteger: curTag = yTagInteger - of yTypeBoolTrue, yTypeBoolFalse: - curTag = yTagBoolean - of yTypeUnknown: curTag = yTagString - else: assert false, "Type not supported!" - elif curTag == yTagExclamationMark: - curTag = yTagString - case curTag - of yTagString: - var s: string - events.constructChild(context, s) - echo "got string: ", s - of yTagInteger: - var i: int32 - events.constructChild(context, i) - echo "got integer: ", i - of yTagBoolean: - var b: bool - events.constructChild(context, b) - echo "got boolean: ", b - of yTagPerson: - var p: Person - events.constructChild(context, p) - echo "got Person with name: ", p.name - else: assert false, "unsupported tag: " & $curTag - nextEvent = events.peek() - assert events.next().kind == yamlEndSeq - assert events.next().kind == yamlEndDoc - assert events.finished() - s.close() - -.. raw:: html - - -.. code-block:: yaml - %YAML 1.2 - --- !!seq - - this is a string - - 42 - - false - - !!str 23 - - !nim:demo:Person {name: Trillian} - -.. raw:: html -
\ No newline at end of file +%examples/quickstart.json%/ \ No newline at end of file diff --git a/doc/rstPreproc.nim b/doc/rstPreproc.nim new file mode 100644 index 0000000..6b92460 --- /dev/null +++ b/doc/rstPreproc.nim @@ -0,0 +1,127 @@ +## This is a tool for preprocessing rst files. Lines starting with ``%`` will +## get substituted by nicely layouted included nim and yaml code. +## +## The syntax of substituted lines is ``'%' jsonfile '%' jsonpath``. *jsonfile* +## shall be the path to a JSON file. *jsonpath* shall be a path to some node in +## that JSON file. +## +## Usage: +## +## rstPreproc -o:path +## +## *path* is the output path. If omitted, it will be equal to infile with its +## suffix substituted by ``.rst``. *infile* is the source rst file. + +import parseopt2, json, streams, tables, strutils, os + +var + infile = "" + path: string = nil +for kind, key, val in getopt(): + case kind + of cmdArgument: + if infile == "": + if key == "": + echo "invalid input file with empty name!" + quit 1 + infile = key + else: + echo "Only one input file is supported!" + quit 1 + of cmdLongOption, cmdShortOption: + case key + of "out", "o": + if isNil(path): path = val + else: + echo "Duplicate output path!" + quit 1 + else: + echo "Unknown option: ", key + quit 1 + of cmdEnd: assert(false) # cannot happen + +if infile == "": + echo "Missing input file!" + quit 1 + +if isNil(path): + for i in countdown(infile.len - 1, 0): + if infile[i] == '.': + if infile[i..^1] == ".rst": path = infile & ".rst" + else: path = infile[0..i] & "rst" + break + if isNil(path): path = infile & ".rst" + +var tmpOut = newFileStream(path, fmWrite) + +proc append(s: string) = + tmpOut.writeLine(s) + +proc gotoPath(root: JsonNode, path: string): JsonNode = + doAssert path[0] == '/' + if path.len == 1: return root + doAssert root.kind == JObject + for i in 1..= headingChars.len: headingChars[^1] else: + headingChars[level] + append(repeat(headingChar, key.len) & '\l') + outputExamples(value, prefix, level + 1) + of JArray: + let elems = node.getElems() + case elems.len + of 2: + append(".. raw:: html") + append(" ") + append(" \n
code.nim" & elems[1].getStr() & + ".yaml
\n") + append(".. code:: nim") + append(" :file: " & prefix & elems[0].getStr() & ".nim\n") + append(".. raw:: html") + append(" \n") + append(".. code:: yaml") + append(" :file: " & prefix & elems[0].getStr() & '.' & + elems[1].getStr() & ".yaml\n") + append(".. raw:: html") + append("
\n") + else: + echo "Unexpected number of elements in array: ", elems.len + quit 1 + else: + echo "Unexpected node kind: ", node.kind + quit 1 + +var lineNum = 0 +for line in infile.lines(): + if line.len > 0 and line[0] == '%': + var + jsonFile: string = nil + jsonPath: string = nil + for i in 1..