Add link tokenizer & stringifier

This commit is contained in:
Florian Schroedl
2022-01-20 17:00:00 +01:00
parent 64a5b587fe
commit 6fe5df066a
2 changed files with 63 additions and 4 deletions

View File

@@ -1,5 +1,11 @@
import std/strformat
import std/sugar
import std/collections/sequtils
import results
import fusion/matching
import fp/maybe
import ./org_types
import ./org_builder
import ../utils/fp
import ../parser/parser_internals
import ../parser/parser_types
@@ -30,6 +36,29 @@ let linkParser* = proc(parser: Parser): ParserResult {.closure.} =
else:
linkValue
func linkStringifier*(linkUrl: string, linkDescription: Maybe[string]): string =
case (linkUrl, linkDescription):
of (@linkUrl, Some(@linkDescription)):
return &"[[{linkUrl}][{linkDescription}]]"
of (@linkUrl, None()):
return &"[[{linkUrl}]]"
func linkTokenizer*(parserTokens: seq[ParserToken]): OrgBuilderT =
[@linkUrl, @linkDescription] := parserTokens.map(tokenStringValue)
let maybeLinkDescription = linkDescription.just().notEmpty()
OrgBuilderT(
kind: orgLink,
content: linkStringifier(linkUrl, maybeLinkDescription),
linkUrl: linkUrl,
linkDescription: maybeLinkDescription,
)
when isMainModule:
echo initParser("[[]]").linkParser()
echo initParser("[[Foo][Bar]]").linkParser()
# echo initParser("[[https://florianschroedl.com]]").linkParser()
echo initParser("[[https://florianschroedl.com][My blog]]")
.linkParser()
.foldTokens(
onError = (x) => nothing(OrgBuilderT),
onSuccess = xs => just(linkTokenizer(xs)),
)

View File

@@ -1,4 +1,7 @@
import std/strformat
import std/sugar
import std/strutils
import fp/maybe
type
orgElementKind* = enum
@@ -12,6 +15,9 @@ type
orgVerbatimText,
orgCodeText,
orgStrikeThroughText,
# Links
orgLink,
OrgElement* = ref object
children*: seq[OrgElement]
content*: string
@@ -28,6 +34,11 @@ type
of orgCodeText: discard
of orgStrikeThroughText: discard
# Links
of orgLink:
linkUrl*: string
linkDescription*: Maybe[string]
proc `$`*(x: orgElementKind): string =
case x:
of orgRawText: "Text (Raw)"
@@ -41,8 +52,27 @@ proc `$`*(x: orgElementKind): string =
of orgCodeText: "Text (Code)"
of orgStrikeThroughText: "Text (StrikeThrough)"
# Links
of orgLink: "Link"
func stringifySpecialFields(x: OrgElement): string =
let specialFields = case x.kind:
of orgLink:
&"""linkUrl: "{x.linkUrl}"""" &
x.linkDescription.map(y => &"\nlinkValue: \"{y}\"").getOrElse("")
else: ""
specialFields
.just()
.notEmpty()
.map(x => x.indent(2))
.map(x => "\n" & x & "\n")
.getOrElse("")
proc `$`*(x: OrgElement): string =
&"""OrgElement(
content: {x.content}
kind: {x.kind}
content: "{x.content}"
kind: {x.kind}""" &
stringifySpecialFields(x) &
"""
)"""