rework markdown processor
This commit is contained in:
parent
9421a0a910
commit
d04a6cc679
4 changed files with 105 additions and 145 deletions
123
nixite/md.nix
123
nixite/md.nix
|
@ -1,17 +1,5 @@
|
|||
let
|
||||
elems = import ./elems.nix;
|
||||
html = import ./html.nix;
|
||||
H = n:
|
||||
let
|
||||
v = if n < 1 then
|
||||
builtins.trace "attempted to make heading size ${toString n} (min is 1)"
|
||||
1
|
||||
else if n > 6 then
|
||||
builtins.trace "attempted to make heading size ${toString n} (max is 6)"
|
||||
6
|
||||
else
|
||||
n;
|
||||
in html.tag "h${toString v}" { };
|
||||
in rec {
|
||||
readMd = md:
|
||||
if builtins.isPath md then
|
||||
|
@ -19,9 +7,7 @@ in rec {
|
|||
else
|
||||
processMd md;
|
||||
|
||||
processMd = md:
|
||||
(map (c: if builtins.isString c then mdBlock c else "")
|
||||
(builtins.split "\n\n" md));
|
||||
processMd = processStr;
|
||||
|
||||
recReadMd = root:
|
||||
assert builtins.isPath root;
|
||||
|
@ -46,25 +32,6 @@ in rec {
|
|||
mdToPage = md:
|
||||
elems.Doc { } [ [ (elems.title { } "markdown file") ] (readMd md) ];
|
||||
|
||||
mdBlock = block:
|
||||
(let
|
||||
h = heading block;
|
||||
c = code block;
|
||||
ul = list block;
|
||||
in (if h.matched then
|
||||
h.block
|
||||
else if c.matched then
|
||||
c.block
|
||||
else if ul.matched then
|
||||
ul.block
|
||||
else
|
||||
elems.p (processStr block)));
|
||||
|
||||
heading = block:
|
||||
matchThen "(#+) (.*)" block (m:
|
||||
let l = builtins.stringLength (builtins.elemAt m 0);
|
||||
in H l (builtins.elemAt m 1));
|
||||
|
||||
code = block:
|
||||
matchThen "(```)(.*)(```)" block (m: elems.code (builtins.elemAt m 1));
|
||||
|
||||
|
@ -95,16 +62,16 @@ in rec {
|
|||
content
|
||||
];
|
||||
|
||||
replace = matcher: apply: block:
|
||||
replace = regex: apply: block:
|
||||
(let
|
||||
m = builtins.match matcher block;
|
||||
m = builtins.match regex block;
|
||||
before = let v = builtins.elemAt m 0; in if v == null then "" else v;
|
||||
inner = builtins.elemAt m 1;
|
||||
after = builtins.elemAt m 2;
|
||||
after = toString( builtins.elemAt m (matchCount - 1));
|
||||
matchCount = builtins.length m;
|
||||
in if m == null then
|
||||
block
|
||||
else
|
||||
(replace matcher apply before) + (apply inner) + after);
|
||||
(replace regex apply before) + (apply m) + after);
|
||||
|
||||
rule = matcher: apply: blocks:
|
||||
map (b: if builtins.isString b then replace matcher apply b else b) blocks;
|
||||
|
@ -118,19 +85,77 @@ in rec {
|
|||
in assert i < 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 [
|
||||
(rule (wrap "\\^") elems.sup)
|
||||
(rule (wrap "~") elems.sub)
|
||||
(rule (wrap "\\*") elems.em)
|
||||
(rule (wrap "`") elems.code)
|
||||
(rule (wrap "==") elems.mark)
|
||||
(rule (wrap "~~") elems.del)
|
||||
(rule (wrap "\\*\\*") elems.strong)
|
||||
(rule (contains "<([-[:alnum:].%?&#=:/]+)>") (m: elems.a m m))
|
||||
(basicRule (wrap "\\^") elems.sup)
|
||||
(basicRule (wrap "~") elems.sub)
|
||||
(basicRule (wrap "\\*") elems.em)
|
||||
(basicRule (wrapBreak "_") elems.em)
|
||||
(basicRule (wrap "`") elems.code)
|
||||
(basicRule (wrap "==") elems.mark)
|
||||
(basicRule (wrap "~~") elems.del)
|
||||
(basicRule (wrap "\\*\\*") elems.strong)
|
||||
(basicRule (wrapBreak "__") elems.strong)
|
||||
(rule (contains "\\[(.*)]\\((.*)\\)") (
|
||||
m:
|
||||
let
|
||||
href = builtins.elemAt m 2;
|
||||
text = builtins.elemAt m 1;
|
||||
in
|
||||
(elems.a href text)
|
||||
))
|
||||
(rule (''
|
||||
(.*
|
||||
)([^-][^
|
||||
]+
|
||||
)((- [^
|
||||
]+
|
||||
)+)(.*)'') (
|
||||
|
||||
l:
|
||||
(elems.ul (basicRule (''
|
||||
(.*
|
||||
)?- ([^
|
||||
]+)
|
||||
(.*)'') (m:
|
||||
elems.li (basicRule ("()\\[(.)](.*)") (check:
|
||||
elems.input {
|
||||
type = "checkbox";
|
||||
checked = check != " ";
|
||||
disabled = true;
|
||||
}) [ m ])) [ (builtins.elemAt l 2) ]))
|
||||
|
||||
))
|
||||
(basicRule ( "(.*\n\n)?(.+)\n(.*)?" ) elems.p)
|
||||
(basicRule ("(.*\n\n)?```(.*)```(.*)?") (elems.textarea { readonly = true; }))
|
||||
(basicRule (containsBreak ''
|
||||
###### ([^
|
||||
]+)'') (elems.h6))
|
||||
(basicRule (containsBreak ''
|
||||
##### ([^
|
||||
]+)'') (elems.h5))
|
||||
(basicRule (containsBreak ''
|
||||
#### ([^
|
||||
]+)'') (elems.h4))
|
||||
(basicRule (containsBreak ''
|
||||
### ([^
|
||||
]+)'') (elems.h3))
|
||||
(basicRule (containsBreak ''
|
||||
## ([^
|
||||
]+)'') (elems.h2))
|
||||
(basicRule (containsBreak ''
|
||||
# ([^
|
||||
]+)'') (elems.h1))
|
||||
(basicRule (containsBreak "<(${linkmatcher})>") (m: elems.a m m))
|
||||
];
|
||||
|
||||
contains = matcher: "(.* )?${matcher}(.*)";
|
||||
wrap = matcher: contains "${matcher}(.+)${matcher}";
|
||||
linkmatcher = "[-[:alnum:].%?&#=:/]+";
|
||||
contains = matcher: "(.*)?${matcher}(.*)";
|
||||
wrap = matcher: contains "${matcher}([^${matcher}]+)${matcher}";
|
||||
|
||||
containsBreak = matcher: "(.*[[:space:]])?${matcher}(.*)";
|
||||
wrapBreak = matcher: containsBreak "${matcher}([^${matcher}]+)${matcher}";
|
||||
|
||||
matchThen = matcher: block: func:
|
||||
let m = builtins.match matcher block;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue