import std/[ collections/sequtils, sugar, ] import fp/[ option, resultM, ] import fusion/matching import ./org_builder_api import ../parser/parser import ../utils/fp # import std/strformat # import std/sugar # import std/collections/sequtils # import results # import fp/[ # maybe, # option, # ] # import ./org_builder_api # import ./org_types # import ../parser/parser_internals # import ../parser/parser_types {.experimental: "caseStmtMacros".} # -- Parsers let linkStartParser* = ignore(str("[[")) + anyUntil(choice(@[str("]["), str("]]")])) + optional(ignore(str("]["))) let linkEndParser* = anyUntil(str("]]")) + ignore(str("]]")) let linkParser* = proc(parser: Parser): ParserResult {.closure.} = # Parse an an org link in the `parser` state. # Return two tokens for a link with description: [[url][description]] # Return one token for a link without description : [[url]] let linkUrl = linkStartParser(parser) .map(flattenTokens) let linkValue = linkUrl .map(emptyTokens) .flatMap(linkEndParser) .map(flattenTokens) case (linkUrl, linkValue): of (Some(@key), Some(@value)): ParserResult.ok( Parser( state: value.state, tokens: @[ key.tokens[0], value.tokens[0], ], ) ) else: linkValue # proc linkStringifier*(linkUrl: string, linkDescription: Option[string]): string = # case (linkUrl, linkDescription): # of (@linkUrl, Some(@linkDescription)): # return &"[[{linkUrl}][{linkDescription}]]" # of (@linkUrl, None()): # return &"[[{linkUrl}]]" # func linkTokenizer*(parserTokens: seq[ParserToken]): OrgInlineBuilderT = # [@linkUrl, @linkDescription] := parserTokens.map(tokenStringValue) # let maybeLinkDescription = linkDescription.some().notEmpty() # return OrgInlineBuilderT( # kind: orgLink, # content: linkStringifier(linkUrl, maybeLinkDescription), # linkUrl: linkUrl, # linkDescription: maybeLinkDescription, # ) # let linkTokenizerSeq* = proc(parserTokens: seq[ParserToken]): seq[OrgInlineBuilderT] {.closure.} = # return @[linkTokenizer(parserTokens)] # when isMainModule: # # echo initParser("[[https://florianschroedl.com]]").linkParser() # echo initParser("[[https://florianschroedl.com][My blog]]") # .linkParser() # .foldTokens( # onError = (x) => newSeq[OrgInlineBuilderT](), # onSuccess = proc(xs: seq[ParserToken]): seq[OrgInlineBuilderT] = linkTokenizerSeq(xs), # )