From 0d19b846f2174139960772f3b08cc2fa00e95220 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 20 Jan 2022 17:00:00 +0100 Subject: [PATCH] Headline parser setup --- src/nim_org_parse.nim | 80 ++++++++++++++++++++++++++++++++++++++++++- src/utils/fp.nim | 20 +++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/utils/fp.nim diff --git a/src/nim_org_parse.nim b/src/nim_org_parse.nim index b5b6a5a..57f56b4 100644 --- a/src/nim_org_parse.nim +++ b/src/nim_org_parse.nim @@ -1 +1,79 @@ -echo "Hello World" +import std/strutils +import std/re +import std/parseutils +import std/strformat +import std/sugar +import fusion/matching +import fp/maybe +import fp/list +import utils/fp + +{.experimental: "caseStmtMacros".} + +type contentT = string +type headlingLevelT = int + +type lineNumberT = int +type lineCharT = int +type posT = (lineNumberT, lineCharT) + +type + OrgBlockKind* = enum + Document, + Heading, + NotImplemented + OrgBlock* = ref object + # position: posT + case kind*: OrgBlockKind + of Heading: + content*: contentT + level*: headlingLevelT + else: str: string + +proc `$`*(x: OrgBlock): string = + case x: + of Document(): + return &"""OrgBlock( + kind: Document, +)""" + of Heading(content: @content, level: @level): + return &"""OrgBlock( + kind: Heading, + content: {content}, + level: {level}, +)""" + of NotImplemented(str: @str): + return &"""OrgBlock( + kind: NotImplemented, + str: {str}, +)""" + +proc parseHeadline(line: string): Maybe[OrgBlock] = + if line.startsWith("*"): + var token: string + let idx = line.parseWhile(token, validChars = { '*' }) + # Eat the first space character + let content = line[idx + 1 .. ^1] + + Just(OrgBlock( + kind: Heading, + level: idx, + content: content, + )) + else: + Nothing[OrgBlock]() + +let parsers = @[ + parseHeadline, +] + +proc parseLine(line: string): any = + parsers + .findMaybeFn(line) + # .fold( + # () => OrgBlock(kind: NotImplemented, str: line), + # x => x.get(), + # ) + + +echo parseLine("**** foo :bar:") diff --git a/src/utils/fp.nim b/src/utils/fp.nim new file mode 100644 index 0000000..7962040 --- /dev/null +++ b/src/utils/fp.nim @@ -0,0 +1,20 @@ +import std/sugar +import fp/maybe + +proc findMaybe*[T](xs: seq[T], fn: T -> bool): Maybe[T] = + for x in xs: + if fn(x): + return Just(x) + return Nothing[T]() + +proc findMaybeFn*[T, B](fns: seq[T {.nimcall.} -> Maybe[B]], val: T): Maybe[B] = + for fn in fns: + let res = fn(val) + if res.isDefined(): + return res + return Nothing[B]() + +when isMainModule: + echo @[ + (x: int) => (if x == 2: Just("foo") else: Nothing[string]()), + ].findMaybeFn(2)