diff --git a/src/org/org_block_heading.nim b/src/org/org_block_heading.nim index c08e58e..1cf77a5 100644 --- a/src/org/org_block_heading.nim +++ b/src/org/org_block_heading.nim @@ -18,6 +18,7 @@ import ./org_types {.experimental: "caseStmtMacros".} let parseHeadingStars = @[ + ignore(optional(newline)), manyUntil(ch('*'), ch(' ')), ignore(ch(' ')) ] @@ -100,19 +101,31 @@ let headingParser = choice(@[ endOfStream, ]) -proc parseHeadlineChildren(builder: OrgBuilder): OrgBuilder = - let headingBlock = builder.tree[0] +proc parseHeadlineChildren(builder: OrgBuilder): OrgBuilderResult = + var headingBlock = builder.tree[0] var parserAcc: ParserResult = ParserResult.ok(builder.parser) - echo parserAcc + # echo parserAcc while parserAcc.isOk() and parserAcc.flatMap(headingParser).isErr(): parserAcc = parserAcc.flatMap(anyCh) - # echo parserAcc.flatMap(flattenParserTokens) + let content = parserAcc.foldTokens( + (err) => "", + (xs: seq[ParserToken]) => xs.tokensToString(), + ) + headingBlock.content = content - builder + let res = parserAcc.fold( + (err) => OrgBuilderResult.err((builder, "Could not parse content")), + (parser: Parser) => OrgBuilderResult.ok(( + parser: parser.emptyTokens(), + tree: @[headingBlock], + )) + ) + + res proc makeOrg*(x: string): OrgBuilderResult = var acc = initOrgBuilder(x) @@ -122,7 +135,7 @@ proc makeOrg*(x: string): OrgBuilderResult = let item = acc .tryBuildHeading() - .map( + .flatMap( (x: OrgBuilder) => parseHeadlineChildren(x) ) .flatMap( @@ -139,7 +152,7 @@ proc makeOrg*(x: string): OrgBuilderResult = proc foldOrg*(x: OrgBuilderResult): string = x .fold( - (err) => "Error", + (err) => "Error" & $err, (builder: OrgBuilder) => $builder.tree, ) # echo acc.unsafeGet().tree[^1] @@ -149,7 +162,10 @@ when isMainModule: Some text inbetween -** DONE Level 2""" +** DONE Level 2 + +Some more content +""" let acc = makeOrg(test1).foldOrg() - # echo acc + echo acc diff --git a/src/org/org_types.nim b/src/org/org_types.nim index 94837fc..5dd4bf4 100644 --- a/src/org/org_types.nim +++ b/src/org/org_types.nim @@ -109,6 +109,7 @@ type level*: int todo*: Option[string] headlineContent*: seq[OrgInlineBlock] + content*: string ## OrgBlock.PrettyPrinters @@ -119,6 +120,7 @@ func pprint*(x: OrgBlock, indent = 0): string = ("todo", $x.todo, x.todo.isSome()), ("headlineContent", $x.headlineContent, x.headlineContent.len != 0), ("children", $x.children, x.children.len != 0), + ("content", $x.content, x.content != ""), ] .stringifyFields() @@ -175,4 +177,4 @@ when isMainModule: OrgBlock(kind: orgHeading), ] ) - + echo doc diff --git a/src/parser/parser_internals.nim b/src/parser/parser_internals.nim index cc54e92..4de84fa 100644 --- a/src/parser/parser_internals.nim +++ b/src/parser/parser_internals.nim @@ -14,6 +14,20 @@ import ../utils/str # -- Parsing Functions +func lookBack*(count: int): (Parser -> ParserResult) = + return func(parser: Parser): ParserResult = + let state = parser.state + let newIndex = state.position - 1 + + Parser( + state: ParserState( + stream: state.stream, + position: newIndex, + lastPosition: parser.state.position, + ), + tokens: parser.tokens, + ).ok() + func ch*(expectedChars: set[char]): (Parser -> ParserResult) {.inline.} = return func(parser: Parser): ParserResult = let state = parser.state diff --git a/src/parser/parser_types.nim b/src/parser/parser_types.nim index 797cec9..1f37d04 100644 --- a/src/parser/parser_types.nim +++ b/src/parser/parser_types.nim @@ -288,7 +288,7 @@ func highlightStreamPosition(stream: string, position: int): string = proc `$`*(x: ParserState): string = &"""ParserState( - stream: "{x.stream}", + stream: "{x.stream.highlightStreamPosition(x.position)}", position: {x.position}, lastPosition: {x.lastPosition}, )"""