diff --git a/src_v2/org/org_builder_heading.nim b/src_v2/org/org_builder_heading.nim new file mode 100644 index 0000000..a617618 --- /dev/null +++ b/src_v2/org/org_builder_heading.nim @@ -0,0 +1,218 @@ +import std/[ + collections/sequtils, + strformat, + strutils, + sugar, +] +import fp/[ + option, + resultM, +] +import fusion/matching +{.experimental: "caseStmtMacros".} +import ./org_types +import ./org_builder_api +import ../parser/parser +import ../utils/fp + +# -- Parsers + +let headingStarsParser* = following(@[ + ignore(optional(newline)), + manyUntil(ch('*'), ch(' ')), + ignore(space) +]) + +proc createTodoKeywordParser(xs: seq[string]): parserFnT = + choice(xs.map((x: string) => str(x) + ignore(space))) + +let todoKeywords = @["TODO"] +let doneKeywords = @["DONE"] + +let parseTodoKeyword = todoKeywords.createTodoKeywordParser() +let parseDoneKeyword = doneKeywords.createTodoKeywordParser() + +# let parseContentText = @[ +# anyUntil(choice(@[endOfStream, str("\n")])), +# ] + +# let parseHeadlineNewline = @[ +# choice(@[ +# ch(NewLines), +# endOfStream, +# ]) +# ] + +# let parseHeadingText = @[ +# anyUntil(newline), +# ] + +# -- Tokenizers + +let buildStars = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}= + 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.}= +# let headlineString = tokens.tokensToString() + +# let tokens = tryBuildInline(headlineString) +# .fold( +# x => newSeq[OrgInlineBuilderT](), +# (x: OrgInlineBuilder) => x.tree, +# ) + +# org.headlineContent = tokens +# org + +# let buildHeadlineChildren = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}= +# # let headlineString = tokens.tokensToString() + +# org + +# let buildHeadlineNewline = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}= +# org + +# proc tryBuildHeading(builder: OrgBuilderResult): OrgBuilderResult = +# # echo builder +# builder +# .applyParsersSeqToSingle( +# OrgBlock(kind: orgHeading), +# @[ +# (parseHeadingStars, buildStars, false), + +# (@[optional(parseTodoKeyword)], buildTodo, true), +# (@[optional(parseDoneKeyword)], buildTodo, true), + +# (parseHeadingText, buildHeadlineContent, false), + +# # (parseContentText, buildHeadlineChildren, true), + +# (parseHeadlineNewline, buildHeadlineNewline, false), +# ] +# ) + +# let headingParser = choice(@[ +# newline + ch('*'), +# endOfStream, +# ]) + + +# let contentEndParser = newline + +# let buildNewline = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.} = +# OrgBlock( +# kind: orgNewline +# ) + +# proc concatOrgBlock(xs: seq[OrgBlock], ys: seq[OrgBlock]): seq[OrgBlock] = xs & ys + +# let parseBlockText = @[ +# anyUntil(choice(@[endOfStream, str("\n")])), +# ] + +# let contentParsersSeq: seq[tuple[ +# parsers: seq[Parser -> ParserResult], +# tokenFoldFn: (seq[ParserToken], OrgBlock) -> OrgBlock, +# ignoreEmpty: bool, +# # concatFn: (seq[OrgBlock], seq[OrgBlock]) -> seq[OrgBlock], +# ]] = @[ +# (parseBlockText, buildNewline, true), +# (contentEndParser, buildNewline, true), +# ] + +# proc parseHeadlineChildren(builder: OrgBuilder): OrgBuilderResult = +# var headingBlock = builder.tree[0] + +# # echo "Builder " & $builder + +# # var builderAcc: OrgBuilderResult = OrgBuilderResult.ok(builder) +# var builderAcc: OrgBuilderResult = OrgBuilderResult.ok(OrgBuilder( +# ( +# parser: builder.parser, +# tree: @[], +# ) +# )) + +# echo "builderAcc before parse content ", builderAcc +# # echo builderAcc.tryParser(headingParser) +# while builderAcc.isOk() and builderAcc.tryParser(headingParser).isErr(): +# builderAcc = builderAcc +# .applyParsersSeqToSeq( +# contentParsersSeq +# ) +# echo "builderAcc after parse in while loop ", builderAcc +# # echo builderAcc + + +# let content = builderAcc.fold( +# (err) => 0, # newSeq[OrgBlock](), +# (builder: OrgBuilder) => len builder.tree, +# ) + +# # echo "builderAcc" & $builderAcc +# echo "content" & $content + +# # headingBlock.content = content + +# let res = builderAcc.fold( +# (err) => OrgBuilderResult.err((builder, "Could not parse content")), +# (builder: OrgBuilder) => OrgBuilderResult.ok(( +# parser: builder.parser.emptyTokens(), +# tree: @[headingBlock], +# )) +# ) + +# res + +# proc makeOrg*(x: string): OrgBuilderResult = +# var acc = initOrgBuilder(x) + +# while acc.isOk() and acc.tryParser(endOfStream).isErr(): +# let unsafeAcc = acc.unsafeGet() + +# let item = acc +# .tryBuildHeading() +# .flatMap( +# (x: OrgBuilder) => parseHeadlineChildren(x) +# ) +# .flatMap( +# (x: OrgBuilder) => OrgBuilderResult.ok(OrgBuilder(( +# parser: x.parser, +# tree: unsafeAcc.tree & x.tree, +# ))) +# ) + +# acc = item + +# acc + +# proc foldOrg*(x: OrgBuilderResult): string = +# x +# .fold( +# (err) => "Error" & $err, +# (builder: OrgBuilder) => $builder.tree, +# ) +# # echo acc.unsafeGet().tree[^1] + +# when isMainModule: +# let test1 = """* TODO Level 1""" + +# let test2 = """* TODO Level 1 +# Foo +# ** DONE Level 2 + +# Some more content +# """ + +# let test3 = """* TODO Level 1 +# Foo +# """ + +# let acc = makeOrg(test3).foldOrg() + +# discard acc diff --git a/src_v2/org/org_text_delimiter.nim b/src_v2/org/org_text_delimiter.nim new file mode 100644 index 0000000..e69de29 diff --git a/src_v2/org/test.nim b/src_v2/org/test.nim new file mode 100644 index 0000000..d99c9ee --- /dev/null +++ b/src_v2/org/test.nim @@ -0,0 +1,3 @@ +import experimental/diff + +echo diff(@[1,2,3], @[1,2,3]) diff --git a/src_v2/parser/parser_internals.nim b/src_v2/parser/parser_internals.nim new file mode 100644 index 0000000..e69de29