Basic headline
This commit is contained in:
@@ -40,19 +40,38 @@ let parseHeadingText = @[
|
||||
# token
|
||||
|
||||
let buildStars = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
|
||||
org.level = tokens[0].tokenStringValue().len
|
||||
org.level = tokens.len
|
||||
org
|
||||
|
||||
let buildTodo = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
|
||||
org.todo = tokens.tokensToString().some()
|
||||
org
|
||||
|
||||
let buildHeadlineContent = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
|
||||
org.headlineContent = tokens.tokensToString()
|
||||
org
|
||||
|
||||
proc tryBuildHeading(builder: OrgBuilderResult): OrgBuilderResult =
|
||||
builder
|
||||
.applyParsersSeqToSingle(
|
||||
OrgBlock(kind: orgHeading),
|
||||
@[(parseHeadingStars, buildStars)]
|
||||
@[
|
||||
(parseHeadingStars, buildStars, false),
|
||||
|
||||
(@[optional(parseTodoKeyword)], buildTodo, true),
|
||||
(@[optional(parseDoneKeyword)], buildTodo, true),
|
||||
|
||||
(parseHeadingText, buildHeadlineContent, false),
|
||||
]
|
||||
)
|
||||
|
||||
when isMainModule:
|
||||
echo initOrgBuilder("**** TODO Some stars")
|
||||
echo initOrgBuilder("*** Some stars")
|
||||
.tryBuildHeading()
|
||||
.fold(
|
||||
x => "Nothing",
|
||||
x => $x.tree
|
||||
)
|
||||
|
||||
|
||||
# let sampleBuilder = StringBuilderResult
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import std/options
|
||||
import std/strformat
|
||||
import std/sugar
|
||||
import std/strutils
|
||||
@@ -89,11 +90,15 @@ type
|
||||
case kind*: orgBlockKind
|
||||
of orgHeading:
|
||||
level*: int
|
||||
todo*: Option[string]
|
||||
headlineContent*: string
|
||||
|
||||
func stringifySpecialFields(x: OrgBlock): string =
|
||||
let specialFields = case x.kind:
|
||||
of orgHeading:
|
||||
&"""level: {x.level}"""
|
||||
&"""level: {x.level}
|
||||
todo: {x.todo}
|
||||
headlineContent: {x.headlineContent}"""
|
||||
else: ""
|
||||
|
||||
specialFields
|
||||
|
||||
@@ -166,6 +166,7 @@ proc applyParsersToSingle*[T](
|
||||
builder: Builder[T],
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||
optional = false,
|
||||
initT: T,
|
||||
): BuilderResult[T] =
|
||||
# Apply the current parsing functions and convert to text tokens wrapped in ParserResult
|
||||
@@ -178,15 +179,20 @@ proc applyParsersToSingle*[T](
|
||||
newParser
|
||||
.foldTokens(
|
||||
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
|
||||
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(
|
||||
builder.initBuilder(
|
||||
newParser.unsafeGet(),
|
||||
builder.tree
|
||||
.last()
|
||||
.orElse(just(initT))
|
||||
.map((x: T) => @[tokenFoldFn(newTokens, x)])
|
||||
.getOrElse(newSeq[T]())
|
||||
)
|
||||
(newTokens: seq[ParserToken]) => (
|
||||
if optional and newTokens.len == 0:
|
||||
BuilderResult[T].ok(builder)
|
||||
else:
|
||||
BuilderResult[T].ok(
|
||||
builder.initBuilder(
|
||||
newParser.unsafeGet(),
|
||||
builder.tree
|
||||
.last()
|
||||
.orElse(just(initT))
|
||||
.map((x: T) => @[tokenFoldFn(newTokens, x)])
|
||||
.getOrElse(newSeq[T]())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -196,10 +202,17 @@ proc applyParsersSeqToSingle*[T](
|
||||
xs: seq[tuple[
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||
ignoreEmpty: bool,
|
||||
]],
|
||||
): BuilderResult[T] =
|
||||
xs.foldl(
|
||||
a.flatMap((builder: Builder[T]) => applyParsersToSingle(builder, b[0], b[1], initT)),
|
||||
a.flatMap((builder: Builder[T]) => applyParsersToSingle(
|
||||
builder,
|
||||
b.parsers,
|
||||
b.tokenFoldFn,
|
||||
b.ignoreEmpty,
|
||||
initT
|
||||
)),
|
||||
builderResult
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user