From a598092f7cb73a97eeb7b743b6ea6bfdd9e5ff75 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 4 May 2022 17:00:00 +0200 Subject: [PATCH] Abstract seq[T] printing --- src/org/org_types.nim | 82 ++++++++++++++++++++++++------------------ src/utils/printers.nim | 24 ++++++++++++- 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/org/org_types.nim b/src/org/org_types.nim index 97c67ab..ba8cf14 100644 --- a/src/org/org_types.nim +++ b/src/org/org_types.nim @@ -10,7 +10,8 @@ import fp/[ ] import ../utils/printers -## Inline Block +## OrgInlineBlock.Type + type orgInlineBlockKind* = enum orgRawText, @@ -26,6 +27,7 @@ type # Links orgLink, + OrgInlineBlock* = ref object children*: seq[OrgInlineBlock] content*: string @@ -47,6 +49,8 @@ type linkUrl*: string linkDescription*: Maybe[string] +## OrgInlineBlock.PrettyPrinters + proc `$`*(x: orgInlineBlockKind): string = case x: of orgRawText: "Text (Raw)" @@ -63,30 +67,36 @@ proc `$`*(x: orgInlineBlockKind): string = # Links of orgLink: "Link" -func stringifySpecialFields(x: OrgInlineBlock): string = +func pprint*(x: OrgInlineBlock, indent = 0): string = let specialFields = case x.kind: of orgLink: - &"""linkUrl: "{x.linkUrl}"""" & - x.linkDescription.map(y => &"\nlinkValue: \"{y}\"").getOrElse("") - else: "" + @[ + ("linkUrl", $x.linkUrl, true), + ("linkDescription", x.linkDescription.getOrElse(""), x.linkDescription.isSome()), + ] + else: @[] - specialFields - .just() - .notEmpty() - .map(x => x.indent(2)) - .map(x => "\n" & x & "\n") - .getOrElse("") + let fields = @[ + ("kind", $x.kind, true), + ("content", $x.content, x.content.len != 0), + ] + .concat(specialFields) + .stringifyFields() -proc `$`*(x: OrgInlineBlock): string = - &"""OrgInlineBlock( - content: "{x.content}" - kind: {x.kind}""" & - stringifySpecialFields(x) & - """ -)""" + stringifyBlock( + "OrgInlineBlock", + indent, + fields, + ) -## OrgBlock -## -------- +func `$`*(x: OrgInlineBlock): string = pprint(x) + +func pprint*(xs: seq[OrgInlineBlock], indent = 0): string = + stringifySeq(xs, (x: OrgInlineBlock) => pprint(x, indent), indent) + +func `$`*(xs: seq[OrgInlineBlock]): string = pprint(xs) + +## OrgBlock.Type type orgBlockKind* = enum @@ -102,6 +112,8 @@ type headlineContent*: seq[OrgInlineBlock] headlineChildrenText*: string +## OrgBlock.PrettyPrinters + func pprint*(x: OrgBlock, indent = 0): string = let fields = @[ ("kind", $x.kind, true), @@ -109,7 +121,7 @@ func pprint*(x: OrgBlock, indent = 0): string = ("todo", $x.todo, x.todo.isSome()), ("headlineContent", $x.headlineContent, x.headlineContent.len != 0), ("headlineChildrenText", $x.headlineChildrenText, x.headlineChildrenText.len != 0), - ("children", $x.children, true), + ("children", $x.children, x.children.len != 0), ] .stringifyFields() @@ -122,22 +134,11 @@ func pprint*(x: OrgBlock, indent = 0): string = func `$`*(x: OrgBlock): string = pprint(x) func pprint*(xs: seq[OrgBlock], indent = 0): string = - let fieldIndent = indent + INDENT_SIZE - @[ - "@[", - xs - .mapIt(it.pprint()) - .join(",\n") - .indent(fieldIndent), - "]", - ] - .join("\n") + stringifySeq(xs, (x: OrgBlock) => pprint(x, indent), indent) func `$`*(xs: seq[OrgBlock]): string = pprint(xs) - -## OrgDocuemnt -## ----------- +## OrgDocument.Type type OrgDocument* = ref object @@ -155,12 +156,23 @@ func pprint*(x: OrgDocument, indent = 0): string = fields, ) +## OrgDocument.PrettyPrinters + func `$`*(xs: OrgDocument): string = pprint(xs) when isMainModule: echo OrgDocument( children: @[ - OrgBlock(kind: orgHeading), + OrgBlock( + kind: orgHeading, + children: @[ + OrgInlineBlock( + kind: orgLink, + linkUrl: "Foo", + linkDescription: "Bar".just(), + ), + ], + ), OrgBlock(kind: orgHeading), OrgBlock(kind: orgHeading), ] diff --git a/src/utils/printers.nim b/src/utils/printers.nim index 92a02a4..db9cb0e 100644 --- a/src/utils/printers.nim +++ b/src/utils/printers.nim @@ -1,5 +1,5 @@ import std/[ - sequtils, + options, sequtils, strformat, strutils, @@ -20,3 +20,25 @@ func stringifyFields*( .filter(x => x.print) .map(x => x.field & ": " & $x.value) .join(",\n") + +func stringifyBlock*(blockName: string, indent = 0, xs: varargs[string]): string = + let fieldIndent = indent + INDENT_SIZE + + concat( + @[&"{blockName}("], + @xs.mapIt(it.indent(fieldIndent)), + @[")"], + ) + .join("\n") + +func stringifySeq*[T](xs: seq[T], stringifyFn: (T) -> string, indent = 0): string = + let fieldIndent = indent + INDENT_SIZE + @[ + "@[", + xs + .mapIt(it.stringifyFn()) + .join(",\n") + .indent(fieldIndent), + "]", + ] + .join("\n")