Restore delimiter parsers
This commit is contained in:
61
src_v2/org/org_builder.nim
Normal file
61
src_v2/org/org_builder.nim
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import std/[
|
||||||
|
collections/sequtils,
|
||||||
|
sugar,
|
||||||
|
]
|
||||||
|
import fp/[
|
||||||
|
resultM,
|
||||||
|
]
|
||||||
|
import ./org_types
|
||||||
|
import ../parser/parser
|
||||||
|
|
||||||
|
# -- OrgInlineBlock.Builder.Type
|
||||||
|
|
||||||
|
type OrgInlineBuilderT* = OrgInlineBlock
|
||||||
|
type OrgInlineBuilder* = Builder[OrgInlineBuilderT]
|
||||||
|
type OrgInlineBuilderResult* = BuilderResult[OrgInlineBuilderT]
|
||||||
|
|
||||||
|
# -- OrgInlineBlock.Builder.Initializers
|
||||||
|
|
||||||
|
func initOrgInlineBuilder*(content: string): OrgInlineBuilderResult =
|
||||||
|
return OrgInlineBuilderResult.ok(OrgInlineBuilder((
|
||||||
|
parser: initParser(content),
|
||||||
|
tree: newSeq[OrgInlineBuilderT](),
|
||||||
|
)))
|
||||||
|
|
||||||
|
func convertTokens*(kind: orgInlineBlockKind): seq[ParserToken] -> seq[OrgInlineBuilderT] =
|
||||||
|
return func(tokens: seq[ParserToken]): seq[OrgInlineBuilderT] =
|
||||||
|
return @[
|
||||||
|
OrgInlineBuilderT(
|
||||||
|
kind: kind,
|
||||||
|
content: tokens.tokensToString(),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
# func rawTextTokenizer*(kind: orgInlineBlockKind): string -> OrgInlineBuilderT =
|
||||||
|
# return func(content: string): OrgInlineBuilderT =
|
||||||
|
# return OrgInlineBuilderT(
|
||||||
|
# kind: kind,
|
||||||
|
# content: content,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# ## Blocks
|
||||||
|
# type OrgBuilderT* = OrgBlock
|
||||||
|
# type OrgBuilder* = Builder[OrgBuilderT]
|
||||||
|
# type OrgBuilderResult* = BuilderResult[OrgBuilderT]
|
||||||
|
|
||||||
|
# func initOrgBuilder*(content: string): OrgBuilderResult =
|
||||||
|
# return OrgBuilderResult.ok(OrgBuilder((
|
||||||
|
# parser: initParser(content),
|
||||||
|
# tree: newSeq[OrgBuilderT](),
|
||||||
|
# )))
|
||||||
|
|
||||||
|
# # proc orgBuilderConcat*(typeInfo: OrgBuilderT, concatFn: (ParserToken, OrgBuilderT) -> OrgBuilderT):
|
||||||
|
# # (seq[ParserToken], OrgBuilderT) -> OrgBuilderT =
|
||||||
|
# # return proc(xs: seq[ParserToken], builder: OrgBuilderT): OrgBuilderT =
|
||||||
|
# # return xs.foldl(concatFn(b, a), typeInfo)
|
||||||
|
|
||||||
|
|
||||||
|
# proc orgBuilderApply*(concatFn: (ParserToken, OrgBuilderT) -> OrgBuilderT):
|
||||||
|
# (seq[ParserToken], OrgBuilderT) -> OrgBuilderT =
|
||||||
|
# return proc(tokens: seq[ParserToken], builder: OrgBuilderT): OrgBuilderT =
|
||||||
|
# tokens.foldl(concatFn(b, a), builder)
|
||||||
80
src_v2/org/org_text_delimiter.nim
Normal file
80
src_v2/org/org_text_delimiter.nim
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import std/[
|
||||||
|
collections/sequtils,
|
||||||
|
strformat,
|
||||||
|
strutils,
|
||||||
|
sugar,
|
||||||
|
]
|
||||||
|
import fp/[
|
||||||
|
resultM,
|
||||||
|
]
|
||||||
|
import ./org_types
|
||||||
|
import ./org_builder
|
||||||
|
import ../parser/parser
|
||||||
|
# import ./org_text_link
|
||||||
|
# import ../utils/fp
|
||||||
|
# import ../parser/parser_internals
|
||||||
|
# import ../parser/parser_types
|
||||||
|
# import ../parser/builder_api
|
||||||
|
|
||||||
|
# -- Parsers
|
||||||
|
|
||||||
|
let boldParser* = anyBetweenPair(ch('*'))
|
||||||
|
let italicParser* = anyBetweenPair(ch('/'))
|
||||||
|
let underlineParser* = anyBetweenPair(ch('_'))
|
||||||
|
let verbatimParser* = anyBetweenPair(ch('='))
|
||||||
|
let codeParser* = anyBetweenPair(ch('~'))
|
||||||
|
let strikeThroughParser* = anyBetweenPair(ch('+'))
|
||||||
|
|
||||||
|
# let rawTokenizer* = rawTextTokenizer(orgRawText)
|
||||||
|
# let boldTokenizer* = textTokenizer(orgBoldText)
|
||||||
|
# let italicTokenizer* = textTokenizer(orgItalicText)
|
||||||
|
# let underlineTokenizer* = textTokenizer(orgUnderlineText)
|
||||||
|
# let verbatimTokenizer* = textTokenizer(orgVerbatimText)
|
||||||
|
# let codeTokenizer* = textTokenizer(orgCodeText)
|
||||||
|
# let strikeThroughTokenizer* = textTokenizer(orgStrikeThroughText)
|
||||||
|
|
||||||
|
# let tok = linkTokenizerSeq
|
||||||
|
|
||||||
|
# let orgStyledTextBuilders = @[
|
||||||
|
# (boldParser, boldTokenizer),
|
||||||
|
# (italicParser, italicTokenizer),
|
||||||
|
# (underlineParser, underlineTokenizer),
|
||||||
|
# (verbatimParser, verbatimTokenizer),
|
||||||
|
# (codeParser, codeTokenizer),
|
||||||
|
# (strikeThroughParser, strikeThroughTokenizer),
|
||||||
|
# (linkParser, linkTokenizerSeq),
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# proc makeRawTokenOrEmpty(tokens: seq[ParserToken]): seq[OrgInlineBuilderT] =
|
||||||
|
# ## Merge all parser `tokens` into a string to tokenize for the builder.
|
||||||
|
# ## Unless the string is empty, in this case return an empty list.
|
||||||
|
# let str = tokens.foldl(a & b.tokenStringValue(), "")
|
||||||
|
# if str.len == 0: @[]
|
||||||
|
# else: @[rawTokenizer(str)]
|
||||||
|
|
||||||
|
# proc tryBuildInline*(content: string): OrgInlineBuilderResult =
|
||||||
|
# initOrgInlineBuilder(content)
|
||||||
|
# .flatMap((builder: OrgInlineBuilder) => tryParseBuild(
|
||||||
|
# builder = builder,
|
||||||
|
# builderFns = orgStyledTextBuilders,
|
||||||
|
# defaultBuilderFn = makeRawTokenOrEmpty,
|
||||||
|
# ))
|
||||||
|
|
||||||
|
# when isMainModule:
|
||||||
|
# let test = tryBuildInline(
|
||||||
|
# "Regular *bold* [[placeholder.com]] /italic/ _underline_ =verbatim= ~code~ +strikethrough+ [[https://placeholder.com][title]]"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# echo test
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
block testParsers:
|
||||||
|
proc testParser(str: string, parser: parserFnT): string =
|
||||||
|
initParserResult(str).flatMap(parser).tokensToString()
|
||||||
|
|
||||||
|
assert testParser("*bold*", boldParser) == "bold"
|
||||||
|
assert testParser("/italic/", italicParser) == "italic"
|
||||||
|
assert testParser("_underline_", underlineParser) == "underline"
|
||||||
|
assert testParser("=verbatim=", verbatimParser) == "verbatim"
|
||||||
|
assert testParser("~code~", codeParser) == "code"
|
||||||
|
assert testParser("+strikeThrough+", strikeThroughParser) == "strikeThrough"
|
||||||
209
src_v2/org/org_types.nim
Normal file
209
src_v2/org/org_types.nim
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
import std/[
|
||||||
|
sequtils,
|
||||||
|
strutils,
|
||||||
|
sugar,
|
||||||
|
]
|
||||||
|
import fp/[
|
||||||
|
option,
|
||||||
|
]
|
||||||
|
import ../utils/printers
|
||||||
|
|
||||||
|
# -- OrgInlineBlock.Type
|
||||||
|
|
||||||
|
type
|
||||||
|
orgInlineBlockKind* = enum
|
||||||
|
orgRawText,
|
||||||
|
orgText,
|
||||||
|
|
||||||
|
# Formating
|
||||||
|
orgBoldText,
|
||||||
|
orgItalicText,
|
||||||
|
orgUnderlineText,
|
||||||
|
orgVerbatimText,
|
||||||
|
orgCodeText,
|
||||||
|
orgStrikeThroughText,
|
||||||
|
|
||||||
|
# Links
|
||||||
|
orgLink,
|
||||||
|
|
||||||
|
OrgInlineBlock* = ref object
|
||||||
|
children*: seq[OrgInlineBlock]
|
||||||
|
content*: string
|
||||||
|
|
||||||
|
case kind*: orgInlineBlockKind
|
||||||
|
of orgRawText: discard
|
||||||
|
of orgText: discard
|
||||||
|
|
||||||
|
# Formating
|
||||||
|
of orgBoldText: discard
|
||||||
|
of orgItalicText: discard
|
||||||
|
of orgUnderlineText: discard
|
||||||
|
of orgVerbatimText: discard
|
||||||
|
of orgCodeText: discard
|
||||||
|
of orgStrikeThroughText: discard
|
||||||
|
|
||||||
|
# Links
|
||||||
|
of orgLink:
|
||||||
|
linkUrl*: string
|
||||||
|
linkDescription*: Option[string]
|
||||||
|
|
||||||
|
# -- OrgInlineBlock.PrettyPrinters
|
||||||
|
|
||||||
|
proc `$`*(x: orgInlineBlockKind): string =
|
||||||
|
case x:
|
||||||
|
of orgRawText: "Text (Raw)"
|
||||||
|
of orgText: "Text"
|
||||||
|
|
||||||
|
# Formating
|
||||||
|
of orgBoldText: "Text (Bold)"
|
||||||
|
of orgItalicText: "Text (Italic)"
|
||||||
|
of orgUnderlineText: "Text (Underline)"
|
||||||
|
of orgVerbatimText: "Text (Verbatim)"
|
||||||
|
of orgCodeText: "Text (Code)"
|
||||||
|
of orgStrikeThroughText: "Text (StrikeThrough)"
|
||||||
|
|
||||||
|
# Links
|
||||||
|
of orgLink: "Link"
|
||||||
|
|
||||||
|
const PPRINT_INDENT_SIZE* = 2
|
||||||
|
|
||||||
|
func pprint*(x: OrgInlineBlock, indent = 0): string =
|
||||||
|
let specialFields = case x.kind:
|
||||||
|
of orgLink:
|
||||||
|
@[
|
||||||
|
("linkUrl", $x.linkUrl, true),
|
||||||
|
("linkDescription", x.linkDescription.getOrElse(""), x.linkDescription.isSome()),
|
||||||
|
]
|
||||||
|
else: @[]
|
||||||
|
|
||||||
|
let fields = @[
|
||||||
|
("kind", $x.kind, true),
|
||||||
|
("content", $x.content, x.content.len != 0),
|
||||||
|
]
|
||||||
|
.concat(specialFields)
|
||||||
|
.stringifyFields()
|
||||||
|
|
||||||
|
stringifyBlock(
|
||||||
|
"OrgInlineBlock",
|
||||||
|
indent,
|
||||||
|
fields,
|
||||||
|
)
|
||||||
|
|
||||||
|
func `$`*(x: OrgInlineBlock): string = pprint(x)
|
||||||
|
|
||||||
|
func pprint*(xs: seq[OrgInlineBlock], indent = 0): string =
|
||||||
|
stringifySeq(xs, (x: OrgInlineBlock) => pprint(x, indent), indent)
|
||||||
|
|
||||||
|
func `$`*(xs: seq[OrgInlineBlock]): string = pprint(xs)
|
||||||
|
|
||||||
|
## -- OrgBlock.Type
|
||||||
|
|
||||||
|
type
|
||||||
|
orgBlockKind* = enum
|
||||||
|
orgHeading
|
||||||
|
orgParagraph
|
||||||
|
orgNewline
|
||||||
|
OrgBlock* = ref object
|
||||||
|
children*: seq[OrgInlineBlock]
|
||||||
|
|
||||||
|
case kind*: orgBlockKind
|
||||||
|
of orgHeading:
|
||||||
|
level*: int
|
||||||
|
todo*: Option[string]
|
||||||
|
headlineContent*: seq[OrgInlineBlock]
|
||||||
|
content*: seq[OrgBlock]
|
||||||
|
of orgParagraph:
|
||||||
|
paragraphContent: seq[OrgInlineBlock]
|
||||||
|
of orgNewline: discard
|
||||||
|
|
||||||
|
## -- OrgBlock.PrettyPrinters
|
||||||
|
|
||||||
|
func pprint*(x: OrgBlock, indent = 0): string =
|
||||||
|
let fields = case x.kind:
|
||||||
|
of orgHeading:
|
||||||
|
@[
|
||||||
|
("kind", $x.kind, true),
|
||||||
|
("level", $x.level, true),
|
||||||
|
("todo", $x.todo, x.todo.isSome()),
|
||||||
|
("headlineContent", $x.headlineContent, x.headlineContent.len != 0),
|
||||||
|
("children", $x.children, x.children.len != 0),
|
||||||
|
(
|
||||||
|
"content",
|
||||||
|
("@[\n" &
|
||||||
|
x.content.map((x) => pprint(x)).join(",\n").indent(PPRINT_INDENT_SIZE) &
|
||||||
|
",\n],"
|
||||||
|
).indent(indent),
|
||||||
|
x.content.len != 0
|
||||||
|
),
|
||||||
|
]
|
||||||
|
of orgParagraph:
|
||||||
|
@[
|
||||||
|
("kind", $x.kind, true),
|
||||||
|
("paragraphContent", $x.paragraphContent, x.paragraphContent.len != 0),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
@[
|
||||||
|
("kind", $x.kind, true),
|
||||||
|
]
|
||||||
|
|
||||||
|
stringifyBlock(
|
||||||
|
"OrgBlock",
|
||||||
|
indent,
|
||||||
|
fields.stringifyFields(),
|
||||||
|
)
|
||||||
|
|
||||||
|
func `$`*(x: OrgBlock): string = pprint(x)
|
||||||
|
|
||||||
|
func pprint*(xs: seq[OrgBlock], indent = 0): string =
|
||||||
|
stringifySeq(xs, (x: OrgBlock) => pprint(x, indent), indent)
|
||||||
|
|
||||||
|
func `$`*(xs: seq[OrgBlock]): string = pprint(xs)
|
||||||
|
|
||||||
|
# -- OrgDocument.Type
|
||||||
|
|
||||||
|
type
|
||||||
|
OrgDocument* = ref object
|
||||||
|
children*: seq[OrgBlock]
|
||||||
|
|
||||||
|
# -- OrgDocument.PrettyPrinters
|
||||||
|
|
||||||
|
func pprint*(x: OrgDocument, indent = 0): string =
|
||||||
|
let fields = @[
|
||||||
|
("children", $x.children, true),
|
||||||
|
]
|
||||||
|
.stringifyFields()
|
||||||
|
|
||||||
|
stringifyBlock(
|
||||||
|
"OrgDocument",
|
||||||
|
indent,
|
||||||
|
fields,
|
||||||
|
)
|
||||||
|
|
||||||
|
func `$`*(xs: OrgDocument): string = pprint(xs)
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let doc = OrgDocument(
|
||||||
|
children: @[
|
||||||
|
OrgBlock(
|
||||||
|
kind: orgHeading,
|
||||||
|
children: @[
|
||||||
|
OrgInlineBlock(
|
||||||
|
kind: orgLink,
|
||||||
|
linkUrl: "https://placeholder.com",
|
||||||
|
linkDescription: "Placeholder".some(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
content: @[
|
||||||
|
OrgBlock(
|
||||||
|
kind: orgNewline,
|
||||||
|
),
|
||||||
|
OrgBlock(
|
||||||
|
kind: orgNewline,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
OrgBlock(kind: orgHeading, level: 1),
|
||||||
|
OrgBlock(kind: orgHeading),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
echo doc
|
||||||
@@ -143,6 +143,9 @@ func tokensToString*(parserResult: ParserResult, fallback = ""): string =
|
|||||||
xs => xs.toString(),
|
xs => xs.toString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func tokensToString*(tokens: seq[ParserToken]): string =
|
||||||
|
tokens.foldl(a & b.toString(), "")
|
||||||
|
|
||||||
func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
|
func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
|
||||||
ParserError(
|
ParserError(
|
||||||
kind: err.kind,
|
kind: err.kind,
|
||||||
@@ -329,3 +332,4 @@ when isMainModule:
|
|||||||
|
|
||||||
# tokensToString
|
# tokensToString
|
||||||
assert testTokensSeqParserResult.tokensToString() == testExpectedStr
|
assert testTokensSeqParserResult.tokensToString() == testExpectedStr
|
||||||
|
assert testTokensSeq.tokensToString() == testExpectedStr
|
||||||
|
|||||||
Reference in New Issue
Block a user