process markdown files

This commit is contained in:
tristan 2024-01-01 17:31:04 +00:00
parent 496d3667de
commit c29ff7b22e
7 changed files with 213 additions and 80 deletions

View file

@ -51,6 +51,7 @@ nix build .#raw
- [ ] links - [ ] links
- [X] codeblocks - [X] codeblocks
- [ ] subscript - [ ] subscript
- [ ] highlight - [X] highlight
- [ ] italics - [X] italics
- [ ] bold - [X] bold

View file

@ -4,9 +4,11 @@ let
H = n: H = n:
let let
v = if n < 1 then v = if n < 1 then
builtins.trace "attempted to make heading size ${toString n} (min is 1)" 1 builtins.trace "attempted to make heading size ${toString n} (min is 1)"
1
else if n > 6 then else if n > 6 then
builtins.trace "attempted to make heading size ${toString n} (max is 6)" 6 builtins.trace "attempted to make heading size ${toString n} (max is 6)"
6
else else
n; n;
in html.tag "h${toString v}" { }; in html.tag "h${toString v}" { };
@ -49,29 +51,81 @@ in rec {
h = heading block; h = heading block;
c = code block; c = code block;
ul = list block; ul = list block;
in (if h.matched then h.block else in (if h.matched then
if c.matched then c.block else h.block
if ul.matched then ul.block else else if c.matched then
elems.p block)); c.block
else if ul.matched then
ul.block
else
elems.p (processStr block)));
heading = block: matchThen "(#+) (.*)" block (m: heading = block:
let matchThen "(#+) (.*)" block (m:
l = builtins.stringLength (builtins.elemAt m 0); let l = builtins.stringLength (builtins.elemAt m 0);
in H l (builtins.elemAt m 1)); in H l (builtins.elemAt m 1));
code = block: matchThen "(```)(.*)(```)" block (m: code = block:
elems.code (builtins.elemAt m 1)); matchThen "(```)(.*)(```)" block (m: elems.code (builtins.elemAt m 1));
list = block: matchThen (let item = "- .+"; in "(${item}\n)*(${item}\n?)") block (m: list = block:
elems.List (builtins.filter ( s: builtins.isString s && s!="" ) (builtins.split "[:blank:]*- " block))); matchThen (let item = "- .+";
in ''
(${item}
)*(${item}
?)'') block (m:
elems.List (builtins.filter (s: builtins.isString s && s != "")
(builtins.split "[:blank:]*- " block)));
replace = matcher: apply: block:
(let
m = builtins.match matcher 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;
in if m == null then
block
else
(replace matcher apply before) + (apply inner) + after);
rule = matcher: apply: blocks:
map (b: if builtins.isString b then replace matcher apply b else b) blocks;
applyRules = i: rules: input:
let
group = if builtins.isString input then [ input ] else input;
len = builtins.length rules;
rule = builtins.elemAt rules i;
next = i + 1;
in assert i < len;
if next < len then rule (applyRules next rules group) else rule group;
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))
];
contains = matcher: "(.* )?${matcher}(.*)";
wrap = matcher: contains "${matcher}(.+)${matcher}";
matchThen = matcher: block: func: matchThen = matcher: block: func:
let let m = builtins.match matcher block;
m = builtins.match matcher block; in if m == null then
in dontMatch block
if m == null then dontMatch block else {
else { matched = true; block = func m; }; matched = true;
block = func m;
dontMatch = block: { matched = false; inherit block; }; };
dontMatch = block: {
matched = false;
inherit block;
};
} }

View file

@ -1,9 +1,14 @@
# yeee # yeee
ye I need some *emphasis*...
&amp; that's **bold**!
<a href="dir">dir</a> ==mark== the important parts.
<a href="/">home</a>
but ~~forget the rest~~.
drink lot's of H ~2~O ^if you want^!
<https://www.markdownguide.org/basic-syntax/>

View file

@ -22,10 +22,13 @@ let
v; v;
out = (if safeToPrint then out = (if safeToPrint then
builtins.toJSON builtins.toJSON (undunder (if throws then
(undunder (if throws then (builtins.tryEval actual).value else actual)) (builtins.tryEval actual).value
else {
inherit actual expected;
}))
else else
''{"msg": "refusing to print"}''); ''{"msg": "cannot be stringified ):"}'');
success = success =
if throws then (builtins.tryEval actual).success == false else (a == e); if throws then (builtins.tryEval actual).success == false else (a == e);
@ -33,7 +36,9 @@ let
in if success then '' in if success then ''
echo 'it ${msg}' echo 'it ${msg}'
'' else '' else
builtins.trace "FAILED ${msg}" '' builtins.trace "FAILED ${msg}" (let file = builtins.toFile "value" out;
in ''
echo FAILED ${msg} echo FAILED ${msg}
echo '${out}' | jq '.' echo '${file}'
'' cat '${file}' | jq '.'
'')

View file

@ -19,55 +19,132 @@ in with md; [
expected = elems.h6 "super ultra tiny heading"; expected = elems.h6 "super ultra tiny heading";
}) })
(it "makes a code block" ( (it "makes a code block" (let
let code = '' code = ''
this is my code this is my code
''; in { '';
actual = mdBlock '' in {
```${code}```''; actual = mdBlock "```${code}```";
expected = elems.code code; expected = elems.code code;
})) }))
(it "matches a list of one element" ( (it "matches a list of one element" ({
{
actual = list '' actual = list ''
- something - something
''; '';
expected = { matched = true; block = elems.List ["something\n"];}; expected = {
matched = true;
block = elems.List [''
something
''];
};
})) }))
(it "matches a list of many elements" ( (it "matches a list of many elements" ({
{
actual = list '' actual = list ''
- something - something
- something else - something else
''; '';
expected = { matched = true; block = elems.List ["something\n" "something else\n"];}; expected = {
matched = true;
block = elems.List [
''
something
''
''
something else
''
];
};
})) }))
(it "matches a list with no whitespace around" ( (it "matches a list with no whitespace around" ({
{ actual = list ''
actual = list - something
"- something\n- something else"; - something else'';
expected = { matched = true; block = elems.List ["something\n" "something else"];}; expected = {
matched = true;
block = elems.List [
''
something
''
"something else"
];
};
})) }))
(it "doesnt match not a list" (let str = "blah blah";
(it "doesnt match not a list" ( in {
let
str = "blah blah";
in
{
actual = list str; actual = list str;
expected = { matched = false; block = str;}; expected = {
matched = false;
block = str;
};
})) }))
(it "makes a list" ( (it "makes a list" ({
{
actual = mdBlock '' actual = mdBlock ''
- something - something
''; '';
expected = elems.List ["something\n"]; expected = elems.List [''
something
''];
}))
(it "finds surrounded parts" ({
actual = replace (wrap "\\*\\*") elems.strong ''
this text **may** contain **bold** words inside it.
'';
expected = [
"this text"
(elems.strong "may")
"contain"
(elems.strong "bold")
''
words inside it.
''
];
asString = true;
}))
(it "surrounds in list of elems" ({
actual = rule (wrap "\\*") elems.em [
"this text"
(elems.strong "may")
"*or may not* contain"
(elems.strong "bold")
"words *inside* it."
];
expected = [
"this text"
(elems.strong "may")
(elems.em "or may not")
"contain"
(elems.strong "bold")
"words"
(elems.em "inside")
"it."
];
asString = true;
}))
(it "processes whole string with all rules" ({
actual = processStr ''
this text **may** *or may not* contain **bold** words *inside* it.
'';
expected = [
"this text"
(elems.strong "may")
(elems.em "or may not")
"contain"
(elems.strong "bold")
"words"
(elems.em "inside")
''
it.
''
];
asString = true;
})) }))
(it "processes md block" { (it "processes md block" {
@ -92,10 +169,8 @@ in with md; [
}) })
(it "converts markdown to a page" { (it "converts markdown to a page" {
actual = mdToPage ./blog/index.md; actual = toString (mdToPage ./blog/index.md) + "\n";
expected = '' expected = builtins.readFile ./out/index.html;
<html lang="en"><head ><title >markdown file</title></head> <body ><h1 >yeee</h1> <p >ye</p> <p >&amp;</p> <p ><a href="dir">dir</a>
<a href="/">home</a></p> <p ></p></body></html>'';
asString = true; asString = true;
}) })

1
testing/out/index.html Normal file
View file

@ -0,0 +1 @@
<html lang="en"><head ><title >markdown file</title></head> <body ><h1 >yeee</h1> <p >I need some <em >emphasis</em>...</p> <p >that's <strong >bold</strong>!</p> <p ><mark >mark</mark> the important parts.</p> <p >but <del >forget the rest</del>.</p> <p >drink lot's of H <sub >2</sub>O <sup >if you want</sup>!</p> <p ><a href="https://www.markdownguide.org/basic-syntax/">https://www.markdownguide.org/basic-syntax/</a></p> <p ></p></body></html>

View file

@ -238,30 +238,22 @@ in with site; [
})) }))
(it "throws with a list for a page" ({ (it "throws with a list for a page" ({
actual = copyTo "." { actual = copyTo "." { page = [ ]; };
page = [];
};
throws = true; throws = true;
})) }))
(it "throws with null for a page" ({ (it "throws with null for a page" ({
actual = copyTo "." { actual = copyTo "." { page = null; };
page = null;
};
throws = true; throws = true;
})) }))
(it "throws with a bool for a page" ({ (it "throws with a bool for a page" ({
actual = copyTo "." { actual = copyTo "." { page = true; };
page = true;
};
throws = true; throws = true;
})) }))
(it "throws with a number for a page" ({ (it "throws with a number for a page" ({
actual = copyTo "." { actual = copyTo "." { page = 5; };
page = 5;
};
throws = true; throws = true;
})) }))