diff --git a/src/org_parser.nim b/src/org_parser.nim index 158e1c5..76f0640 100644 --- a/src/org_parser.nim +++ b/src/org_parser.nim @@ -4,6 +4,10 @@ import std/collections/sequtils import std/strutils import parser/parser import results +import utils/fp +import fusion/matching + +{.experimental: "caseStmtMacros".} type StringBuilderT = string type StringBuilder = Builder[StringBuilderT] @@ -14,6 +18,14 @@ proc stringConcat(typeInfo: StringBuilderT): return proc(xs: seq[ParserToken], ys: seq[StringBuilderT]): seq[StringBuilderT] = return ys & xs.foldl(a & b.tokenStringValue(), typeInfo) + +proc initStringBuilder(str: string): StringBuilderResult = + StringBuilderResult + .ok(StringBuilder(( + parser: initParser(str), + tree: newSeq[StringBuilderT](), + ))) + when isMainModule: let parseHeadingStars = @[ manyUntil(ch('*'), ch(' ')), @@ -29,18 +41,51 @@ when isMainModule: let parseTodoKeyword = todoKeywords.createTodoKeywordParser() let parseDoneKeyword = doneKeywords.createTodoKeywordParser() - let propertiesKeyValueParser = anyUntil(ch(Newlines)) + ignore(ch(NewLines)) - let propertiesEndParser = str(":PROPERTIES_END:") + ch(Newlines) + let propertiesKeyParser = ignore(ch(':')) + anyUntil(choice(@[str(": "), newline])) + let propertiesValueParser = ignore(str(": ")) + anyUntil(newline) + ignore(newline) + let propertiesParser = proc(parser: Parser): ParserResult {.closure.} = + let keyTokenParser = parser + .propertiesKeyParser() + .flatMap(flattenParserTokens) + + + let valueTokenParser = keyTokenParser + .map(emptyTokens) + .flatMap(propertiesValueParser) + .flatMap(flattenParserTokens) + + case (keyTokenParser, valueTokenParser): + of (Some(@key), Some(@value)): + ok(Parser( + state: value.state, + tokens: @[ + key.tokens[0], + value.tokens[0], + ] + )) + else: valueTokenParser + + let propertiesStartParser = str(":PROPERTIES_START:") + newline + let propertiesEndParser = str(":PROPERTIES_END:") + newline let parseProperties = @[ - ignore(str(":PROPERTIES:") + ch(Newlines)), + ignore(propertiesStartParser), manyUntil( - propertiesKeyValueParser, + propertiesParser, propertiesEndParser, ), ignore(propertiesEndParser), ] + + echo initParserResult(""":PROPERTIES: +:PROP_NAME: Value +:PROP_NAME: Value +:PROP_NAME: Value +:PROP_NAME: Value +:PROPERTIES_END: +""").parseSeq(parseProperties) + let parseHeadingText = @[ anyUntil(newline), ignore(newline), @@ -65,7 +110,7 @@ when isMainModule: (@[optional(parseDoneKeyword)], stringConcat("DONE: ")), (parseHeadingText, stringConcat("Text: ")), - (parseProperties, stringConcat("Properties: ")), + # (parseProperties, stringConcat("Properties: ")), # (@[optional(choice(parseProperties))], stringConcat("Properties: ")), ]) .foldBuilder( @@ -73,4 +118,4 @@ when isMainModule: xs => "Parser Succesfull:\n" & xs.join("\n"), ) - echo sampleBuilder + # echo sampleBuilder