import std/[ options, sequtils, strformat, strutils, sugar, ] import fusion/matching import fp/[ option, ] import ./org_types as orgTypes {.experimental: "caseStmtMacros".} const HEADING_LEVEL_CHAR = "*" const BOLD_DELIMITER = "*" const ITALIC_DELIMITER = "/" const UNDERLINE_DELIMITER = "_" const VERBATIM_DELIMITER = "=" const CODE_DELIMITER = "~" const STRIKETHROUGH_DELIMITER = "+" type Env* = ref object func init(): Env = Env() let defaultEnv = init() func wrap(x: string, delimiter: string): string = &"{delimiter}{x}{delimiter}" func linkAsText*(url: string, description: Option[string]): string = case description: of (Some(@someDescription)): &"[[{url}][{someDescription}]]" else: &"[[{url}]]" func asText*(x: OrgInlineBlock, env = defaultEnv): string = case x.kind: of orgRawText: x.content of orgText: x.content # Formating of orgBoldText: x.content.wrap(BOLD_DELIMITER) of orgItalicText: x.content.wrap(ITALIC_DELIMITER) of orgUnderlineText: x.content.wrap(UNDERLINE_DELIMITER) of orgVerbatimText: x.content.wrap(VERBATIM_DELIMITER) of orgCodeText: x.content.wrap(CODE_DELIMITER) of orgStrikeThroughText: x.content.wrap(STRIKETHROUGH_DELIMITER) # Links of orgLink: linkAsText(x.linkUrl, x.linkDescription) func asText*(o: OrgBlock, env = defaultEnv): string = let stars = HEADING_LEVEL_CHAR.repeat(o.level) @[ stars.some().notEmpty(), o.todo, o.headlineContent .map((x: OrgInlineBlock) => x.asText()) .some() .map((xs: seq[string]) => xs.join(" ")), ] .filter(x => x.isSome()) .map(x => x.get()) .join(" ") when isMainModule: echo OrgBlock( kind: orgHeading, level: 1, todo: "TODO".some, headlineContent: @[ OrgInlineBlock( kind: orgLink, linkUrl: "https://placeholder.com", linkDescription: "Placeholder".some(), ), ], ) .asText()