From 87299069d00263b0cf317e22f1cb2bd5b4ee53d9 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 4 May 2022 17:00:00 +0200 Subject: [PATCH] Add stringifier --- src/org/org_stringifier.nim | 84 +++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/org/org_stringifier.nim diff --git a/src/org/org_stringifier.nim b/src/org/org_stringifier.nim new file mode 100644 index 0000000..17bcf06 --- /dev/null +++ b/src/org/org_stringifier.nim @@ -0,0 +1,84 @@ +import std/[ + options, + sequtils, + strformat, + strutils, + sugar, +] +import fusion/matching +import fp/[ + option, +] +import ./org_types as orgTypes + +{.experimental: "caseStmtMacros".} + +const HEADING_LEVEL_CHAR = "*" +const BOLD_DELIMITER = "*" +const ITALIC_DELIMITER = "/" +const UNDERLINE_DELIMITER = "_" +const VERBATIM_DELIMITER = "=" +const CODE_DELIMITER = "~" +const STRIKETHROUGH_DELIMITER = "+" + +type Env* = ref object + +func init(): Env = + Env() + +let defaultEnv = init() + +func wrap(x: string, delimiter: string): string = + &"{delimiter}{x}{delimiter}" + +func linkAsText*(url: string, description: Option[string]): string = + case description: + of (Some(@someDescription)): &"[[{url}][{someDescription}]]" + else: &"[[{url}]]" + +func asText*(x: OrgInlineBlock, env = defaultEnv): string = + case x.kind: + of orgRawText: x.content + of orgText: x.content + + # Formating + of orgBoldText: x.content.wrap(BOLD_DELIMITER) + of orgItalicText: x.content.wrap(ITALIC_DELIMITER) + of orgUnderlineText: x.content.wrap(UNDERLINE_DELIMITER) + of orgVerbatimText: x.content.wrap(VERBATIM_DELIMITER) + of orgCodeText: x.content.wrap(CODE_DELIMITER) + of orgStrikeThroughText: x.content.wrap(STRIKETHROUGH_DELIMITER) + + # Links + of orgLink: linkAsText(x.linkUrl, x.linkDescription) + +func asText*(o: OrgBlock, env = defaultEnv): string = + let stars = HEADING_LEVEL_CHAR.repeat(o.level) + + @[ + stars.some().notEmpty(), + o.todo, + o.headlineContent + .map((x: OrgInlineBlock) => x.asText()) + .some() + .map((xs: seq[string]) => xs.join(" ")), + ] + .filter(x => x.isSome()) + .map(x => x.get()) + .join(" ") + + +when isMainModule: + echo OrgBlock( + kind: orgHeading, + level: 1, + todo: "TODO".some, + headlineContent: @[ + OrgInlineBlock( + kind: orgLink, + linkUrl: "https://placeholder.com", + linkDescription: "Placeholder".some(), + ), + ], + ) + .asText()