80 lines
1.5 KiB
Nim
80 lines
1.5 KiB
Nim
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:")
|