diff --git a/src_v2/org/org_builder_api.nim b/src_v2/org/org_builder_api.nim index 593df9c..b4b7810 100644 --- a/src_v2/org/org_builder_api.nim +++ b/src_v2/org/org_builder_api.nim @@ -41,6 +41,7 @@ func tokenizeRawText*(kind: orgInlineBlockKind): string -> OrgInlineBuilderT = # ## Blocks type OrgBuilderT* = OrgBlock type OrgBuilder* = Builder[OrgBuilderT] +type OrgBuilderError* = BuilderError[OrgBuilderT] type OrgBuilderResult* = BuilderResult[OrgBuilderT] func initOrgBuilder*(content: string): OrgBuilderResult = diff --git a/src_v2/org/org_builder_paragraph.nim b/src_v2/org/org_builder_paragraph.nim index e20d041..fe3488f 100644 --- a/src_v2/org/org_builder_paragraph.nim +++ b/src_v2/org/org_builder_paragraph.nim @@ -8,7 +8,8 @@ import fp/[ ] import ./org_types import ./org_builder_api -import ./org_builder_link.nim +import ./org_builder_link +import ./org_builder_inline_text import ../parser/parser import ../utils/fp @@ -44,12 +45,9 @@ let listStartParser = manyUntil(space, listTypesParser) let listTypeParser = listTypesParser + ignore(space) let listContentParser = anyUntil(newlineOrEol) + ignore(newlineOrEol) -proc buildListItem(builder: OrgBuilder): OrgBuilderResult = - +let buildListItem = proc(builder: OrgBuilder): OrgBuilderResult {.closure.} = let (parser, tree) = builder - # let initialParser = ParserResult.ok(parser) - let beforeSpaces = ParserResult.ok(parser) .flatMap(listStartParser) .map(flattenTokens) @@ -64,43 +62,62 @@ proc buildListItem(builder: OrgBuilder): OrgBuilderResult = .flatMap(listContentParser) .map(flattenTokens) - let y = case (beforeSpaces, listType, listContent): - of (Some(@a), Some(@b), Some(@c)): c.tokens.tokensToString() - else: "" - echo y + case (beforeSpaces, listType, listContent): + of (Some(@space), Some(@symbol), Some(@content)): + let treeResult = tree & + OrgBlock( + kind: orgList, + listIndentation: 1, + listBulletType: '-', + listContent: tryTokenizeInline(content.tokens.tokensToString()).unsafeGet().tree + ) + # echo treeResult - builder.ok() + OrgBuilderResult.ok(OrgBuilder(( + parser: content, + tree: treeResult, + ))) + else: OrgBuilderResult.err(OrgBuilderError( + kind: parserError, + parser: listContent.error, + tree: tree, + )) -discard initOrgBuilder(" 1. foo bar").map(buildListItem) +proc buildParagraph*( + builder: OrgBuilder, + builderFns: seq[proc (builder: OrgBuilder): OrgBuilderResult], + stopAtParserFn = endOfStream, +): OrgBuilderResult = + var builderAcc: OrgBuilderResult = OrgBuilderResult.ok(builder) -# proc buildParagraph*( -# builder: OrgBuilder, -# builderFns: seq[tuple[ -# builderFn: OrgBuilder -> OrgBuilderResult, -# concatFn: OrgBuilder -> OrgBuilder, -# ]], -# stopAtParserFn = endOfStream, -# ): OrgBuilderResult = + while builderAcc.isOk() and builderAcc.tryParserResult(stopAtParserFn).isErr(): + var found = false -# var builderAcc = OrgBuilderResult.ok(builder) + for builderFn in builderFns: + # let (builderFn) = fn + let builderResult: OrgBuilderResult = builderAcc.flatMap(builderFn) -# while builderAcc.isOk() and builderAcc.applyParser(stopAtParserFn).isErr(): -# var found = false + if builderResult.isOk(): + found = true -# for fn in builderFns: -# let builderResult = builderAcc.flatMap(fn) + builderAcc = builderResult + break -# if builderResult.isOk(): -# found = true + if not found: + builderAcc = OrgBuilderResult.err(OrgBuilderError( + kind: parserError, + tree: builder.tree, + )) + break -# builderAcc = builderAcc.map((x: OrgBuilder) => x.concat(builderResult.unsafeGet())) -# break + builderAcc -# when isMainModule: -# block testParsers: -# proc testParser(str: string, parser: parserFnT): string = -# initParserResult(str).flatMap(parser).tokensToString() +let paragraphBuilders: seq[proc (builder: OrgBuilder): OrgBuilderResult] = @[buildListItem] -# assert testParser("- List item", listItemParser) == "- List item" -# assert testParser(" - List item", listItemParser) == " - List item" +when isMainModule: + block testParsers: + let test = initOrgBuilder("""- List item +1. List item +random stuff""").flatMap((builder: OrgBuilder) => builder.buildParagraph(paragraphBuilders)) + echo test.isOk() diff --git a/src_v2/org/org_types.nim b/src_v2/org/org_types.nim index f155c5c..179c118 100644 --- a/src_v2/org/org_types.nim +++ b/src_v2/org/org_types.nim @@ -120,6 +120,7 @@ type orgBlockKind* = enum orgHeading orgParagraph + orgList orgNewline OrgBlock* = ref object children*: seq[OrgInlineBlock] @@ -132,6 +133,10 @@ type content*: seq[OrgBlock] of orgParagraph: paragraphContent: seq[OrgInlineBlock] + of orgList: + listIndentation*: int + listBulletType*: char + listContent*: seq[OrgInlineBlock] of orgNewline: discard ## -- OrgBlock.PrettyPrinters @@ -159,6 +164,13 @@ func pprint*(x: OrgBlock, indent = 0): string = ("kind", $x.kind, true), ("paragraphContent", $x.paragraphContent, x.paragraphContent.len != 0), ] + of orgList: + @[ + ("kind", $x.kind, true), + ("listContent", $x.listContent, x.listContent.len != 0), + ("listIndentation", $x.listIndentation, true), + ("listBulletType", $x.listBulletType, true), + ] else: @[ ("kind", $x.kind, true), diff --git a/src_v2/parser/builder_api.nim b/src_v2/parser/builder_api.nim index b7546e4..f97aaa6 100644 --- a/src_v2/parser/builder_api.nim +++ b/src_v2/parser/builder_api.nim @@ -14,30 +14,6 @@ import ./parser_api # -- Builder API -proc tryParser*[T]( - builder: Builder[T], - parser: Parser -> ParserResult, -): BuilderResult[T] = - ## Try out a `parser` on a `builder` - ## When succesful return the original builder, otherwise return an error - ParserResult.ok(Parser( - state: builder[0].state, - tokens: @[] - )) - .flatMap(parser) - .foldTokens( - (err: ParserError) => BuilderResult[T].err((builder, "Error")), - (newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder), - ) - -proc tryParser*[T]( - builder: BuilderResult[T], - parser: Parser -> ParserResult, -): BuilderResult[T] = - ## Try out a `parser` on a `builder` result - ## When succesful return the ok builder, otherwise return an error - builder.flatMap((x: Builder[T]) => tryParser(x, parser)) - proc tryTokenize*[T]( builder: Builder[T], builderFns: seq[tuple[ diff --git a/src_v2/parser/builder_types.nim b/src_v2/parser/builder_types.nim index eca8d1d..19a5b6c 100644 --- a/src_v2/parser/builder_types.nim +++ b/src_v2/parser/builder_types.nim @@ -65,6 +65,14 @@ proc tryParser*[T]( (newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder), ) +proc tryParserResult*[T]( + builder: BuilderResult[T], + parser: Parser -> ParserResult, +): BuilderResult[T] = + ## Try out a `parser` on a `builder` result + ## When succesful return the ok builder, otherwise return an error + builder.flatMap((x: Builder[T]) => tryParser(x, parser)) + when isMainModule: type TestStringBuilderT* = string type TestStringBuilder* = Builder[TestStringBuilderT]