Headline parser setup
This commit is contained in:
@@ -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:")
|
||||
|
||||
20
src/utils/fp.nim
Normal file
20
src/utils/fp.nim
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user