diff --git a/flake.nix b/flake.nix index cc95dbe..a3791cd 100644 --- a/flake.nix +++ b/flake.nix @@ -34,7 +34,7 @@ inherit (tix.packages.${system}) watch watchpipe results; test = tix.run [ - # ./testing/md.test.nix + ./testing/md.test.nix ./testing/html.test.nix ./testing/elems.test.nix ./testing/builder.test.nix diff --git a/nixite/md.nix b/nixite/md.nix index 7aa90af..680a1a8 100644 --- a/nixite/md.nix +++ b/nixite/md.nix @@ -1,19 +1,16 @@ -let - elems = import ./elems.nix; - html = import ./html.nix; -in rec { - processMd = md: +rec { + processMd = elems: md: if builtins.isPath md - then processStr (builtins.readFile md) - else processStr md; + then processStr elems (builtins.readFile md) + else processStr elems md; - recReadMd = root: + recReadMd = toPage: elems: root: assert builtins.isPath root; builtins.mapAttrs (path: type: if type == "directory" then recReadMd (root + (/. + path)) else if type == "regular" - then mdToPage (root + (/. + path)) + then toPage (processMd elems (root + (/. + path))) else throw "Cannot read ${path}, file type ${type}") (builtins.readDir root); recFixAppendix = site: @@ -28,19 +25,13 @@ in rec { fixAppendix = builtins.replaceStrings [".md"] [".html"]; - readDir = root: recFixAppendix (recReadMd root); + readDir = toPage: elems: root: recFixAppendix (recReadMd toPage elems root); - mdToPage = md: - html.document { - head = []; - body = elems.main (elems.article (processMd md)); - }; - - splitList = block: - map listItem (builtins.filter (s: builtins.isString s && s != "") + splitList = elems: block: + map listItem elems (builtins.filter (s: builtins.isString s && s != "") (builtins.split "\n" block)); - listItem = str: let + listItem = elems: str: let li = builtins.match "- (.*)" str; checkbox = builtins.match "- \\[(.)] (.*)" str; checked = builtins.elemAt checkbox 0; @@ -58,47 +49,48 @@ in rec { ]; replace = regex: apply: block: - assert builtins.isString block; (let - m = builtins.match regex block; - before = builtins.elemAt m 0; - after = toString (builtins.elemAt m (matchCount - 1)); - matchCount = builtins.length m; - in - if m == null - then block - else - ( - if before == null - then "" - else replace regex apply before - ) - + (apply m) - + after); + if toString block == "" + then "" + else + (let + match = builtins.match regex block; + before = builtins.elemAt match 0; + matchCount = builtins.length match; + after = builtins.elemAt match (matchCount - 1); + in + if match == null + then block + else + ( + replace regex apply before + ) + + (apply match) + + after); rule = matcher: apply: blocks: - map (block: - if builtins.isString block - then replace matcher apply block - else block) - blocks; + if builtins.isString blocks + then replace matcher apply blocks + else if builtins.isList blocks + then map (replace matcher apply) blocks + else throw "replace rule should be applied to string or list of strings"; - applyRules = i: rules: input: let + applyRules = index: rules: input: let group = if builtins.isString input then [input] else input; len = builtins.length rules; - rule = builtins.elemAt rules i; - next = i + 1; + rule = builtins.elemAt rules index; + next = index + 1; in - assert i < len; + assert index < len; if next < len then rule (applyRules next rules group) else rule group; basicRule = matcher: elem: rule matcher (m: elem (builtins.elemAt m 1)); - processStr = applyRules 0 [ + processStr = elems: applyRules 0 [ (basicRule (wrap "\\^") elems.sup) (basicRule (wrap "~") elems.sub) (basicRule (wrap "\\*") elems.em) @@ -111,8 +103,8 @@ in rec { (rule (contains "\\[(.*)]\\((.*)\\)") (m: let href = builtins.elemAt m 2; text = builtins.elemAt m 1; - in (elems.a href text))) - list + in (elems.a {inherit href;} text))) + (list elems) (basicRule "(.*\n\n)?(.+)\n(.*)?" elems.p) (basicRule "(.*\n\n)?```(.*)```(.*)?" (elems.textarea {readonly = true;})) (basicRule (containsBreak "###### ([^\n]+)") (elems.h6)) @@ -121,18 +113,25 @@ in rec { (basicRule (containsBreak "### ([^\n]+)") (elems.h3)) (basicRule (containsBreak "## ([^\n]+)") (elems.h2)) (basicRule (containsBreak "# ([^\n]+)") (elems.h1)) - (basicRule (containsBreak "<(${linkmatcher})>") (m: elems.a m m)) + (basicRule (containsBreak "<(${linkmatcher})>") (m: elems.a {href = m;} m)) ]; - list = rule "((.*)(\n([^-\n][^\n]+)?\n))?((- [^\n]+\n)+)(.*)" ( - l: (elems.ul (basicRule "(.*\n)?- ([^\n]+)\n(.*)" (m: - elems.li (basicRule "()\\[(.)] (.*)" (check: - elems.input { - type = "checkbox"; - checked = check != " "; - disabled = true; - }) [m])) [(builtins.elemAt l 4)])) - ); + list = elems: let + addCheckboxes = basicRule "()\\[(.)] (.*)" (check: + elems.input { + type = "checkbox"; + checked = check != " "; + disabled = true; + }); + + listitems = + basicRule "(.*\n)?- ([^\n]+)\n(.*)" (contents: + elems.li (addCheckboxes contents)); + in (rule "((.*)(\n([^-\n][^\n]+)?\n))?((- [^\n]+\n)+)(.*)" ( + match: let + listString = builtins.elemAt match 4; + in (elems.ul (listitems listString)) + )); linkmatcher = "[-[:alnum:].%?&#=:/]+"; contains = matcher: "(.*)?${matcher}(.*)";