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(),
|
||||
)
|
||||
|
||||
func tokensToString*(tokens: seq[ParserToken]): string =
|
||||
tokens.foldl(a & b.toString(), "")
|
||||
|
||||
func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
|
||||
ParserError(
|
||||
kind: err.kind,
|
||||
@@ -329,3 +332,4 @@ when isMainModule:
|
||||
|
||||
# tokensToString
|
||||
assert testTokensSeqParserResult.tokensToString() == testExpectedStr
|
||||
assert testTokensSeq.tokensToString() == testExpectedStr
|
||||
|
||||
Reference in New Issue
Block a user