process markdown files
This commit is contained in:
parent
496d3667de
commit
c29ff7b22e
|
@ -51,6 +51,7 @@ nix build .#raw
|
|||
- [ ] links
|
||||
- [X] codeblocks
|
||||
- [ ] subscript
|
||||
- [ ] highlight
|
||||
- [ ] italics
|
||||
- [ ] bold
|
||||
- [X] highlight
|
||||
- [X] italics
|
||||
- [X] bold
|
||||
|
||||
|
|
|
@ -4,9 +4,11 @@ let
|
|||
H = n:
|
||||
let
|
||||
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
|
||||
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
|
||||
n;
|
||||
in html.tag "h${toString v}" { };
|
||||
|
@ -49,29 +51,81 @@ in rec {
|
|||
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 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));
|
||||
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));
|
||||
code = block:
|
||||
matchThen "(```)(.*)(```)" block (m: elems.code (builtins.elemAt m 1));
|
||||
|
||||
list = block: matchThen (let item = "- .+"; in "(${item}\n)*(${item}\n?)") block (m:
|
||||
elems.List (builtins.filter ( s: builtins.isString s && s!="" ) (builtins.split "[:blank:]*- " block)));
|
||||
list = 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:
|
||||
let
|
||||
m = builtins.match matcher block;
|
||||
in
|
||||
if m == null then dontMatch block
|
||||
else { matched = true; block = func m; };
|
||||
let m = builtins.match matcher block;
|
||||
in if m == null then
|
||||
dontMatch block
|
||||
else {
|
||||
matched = true;
|
||||
block = func m;
|
||||
};
|
||||
|
||||
dontMatch = block: { matched = false; inherit block; };
|
||||
dontMatch = block: {
|
||||
matched = false;
|
||||
inherit block;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
# yeee
|
||||
|
||||
ye
|
||||
I need some *emphasis*...
|
||||
|
||||
&
|
||||
that's **bold**!
|
||||
|
||||
<a href="dir">dir</a>
|
||||
<a href="/">home</a>
|
||||
==mark== the important parts.
|
||||
|
||||
but ~~forget the rest~~.
|
||||
|
||||
drink lot's of H ~2~O ^if you want^!
|
||||
|
||||
<https://www.markdownguide.org/basic-syntax/>
|
||||
|
||||
|
|
|
@ -22,10 +22,13 @@ let
|
|||
v;
|
||||
|
||||
out = (if safeToPrint then
|
||||
builtins.toJSON
|
||||
(undunder (if throws then (builtins.tryEval actual).value else actual))
|
||||
builtins.toJSON (undunder (if throws then
|
||||
(builtins.tryEval actual).value
|
||||
else {
|
||||
inherit actual expected;
|
||||
}))
|
||||
else
|
||||
''{"msg": "refusing to print"}'');
|
||||
''{"msg": "cannot be stringified ):"}'');
|
||||
|
||||
success =
|
||||
if throws then (builtins.tryEval actual).success == false else (a == e);
|
||||
|
@ -33,7 +36,9 @@ let
|
|||
in if success then ''
|
||||
echo 'it ${msg}'
|
||||
'' else
|
||||
builtins.trace "FAILED ${msg}" ''
|
||||
builtins.trace "FAILED ${msg}" (let file = builtins.toFile "value" out;
|
||||
in ''
|
||||
echo FAILED ${msg}
|
||||
echo '${out}' | jq '.'
|
||||
''
|
||||
echo '${file}'
|
||||
cat '${file}' | jq '.'
|
||||
'')
|
||||
|
|
|
@ -19,55 +19,132 @@ in with md; [
|
|||
expected = elems.h6 "super ultra tiny heading";
|
||||
})
|
||||
|
||||
(it "makes a code block" (
|
||||
let code = ''
|
||||
this is my code
|
||||
''; in {
|
||||
actual = mdBlock ''
|
||||
```${code}```'';
|
||||
(it "makes a code block" (let
|
||||
code = ''
|
||||
this is my code
|
||||
'';
|
||||
in {
|
||||
actual = mdBlock "```${code}```";
|
||||
expected = elems.code code;
|
||||
}))
|
||||
|
||||
(it "matches a list of one element" (
|
||||
{
|
||||
(it "matches a list of one element" ({
|
||||
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 ''
|
||||
- something
|
||||
- something else
|
||||
- something
|
||||
- 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" (
|
||||
{
|
||||
actual = list
|
||||
"- something\n- something else";
|
||||
expected = { matched = true; block = elems.List ["something\n" "something else"];};
|
||||
(it "matches a list with no whitespace around" ({
|
||||
actual = list ''
|
||||
- something
|
||||
- something else'';
|
||||
expected = {
|
||||
matched = true;
|
||||
block = elems.List [
|
||||
''
|
||||
something
|
||||
''
|
||||
"something else"
|
||||
];
|
||||
};
|
||||
}))
|
||||
|
||||
|
||||
(it "doesnt match not a list" (
|
||||
let
|
||||
str = "blah blah";
|
||||
in
|
||||
{
|
||||
(it "doesnt match not a list" (let str = "blah blah";
|
||||
in {
|
||||
actual = list str;
|
||||
expected = { matched = false; block = str;};
|
||||
expected = {
|
||||
matched = false;
|
||||
block = str;
|
||||
};
|
||||
}))
|
||||
|
||||
(it "makes a list" (
|
||||
{
|
||||
(it "makes a list" ({
|
||||
actual = mdBlock ''
|
||||
- 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" {
|
||||
|
@ -92,10 +169,8 @@ in with md; [
|
|||
})
|
||||
|
||||
(it "converts markdown to a page" {
|
||||
actual = mdToPage ./blog/index.md;
|
||||
expected = ''
|
||||
<html lang="en"><head ><title >markdown file</title></head> <body ><h1 >yeee</h1> <p >ye</p> <p >&</p> <p ><a href="dir">dir</a>
|
||||
<a href="/">home</a></p> <p ></p></body></html>'';
|
||||
actual = toString (mdToPage ./blog/index.md) + "\n";
|
||||
expected = builtins.readFile ./out/index.html;
|
||||
asString = true;
|
||||
})
|
||||
|
||||
|
|
1
testing/out/index.html
Normal file
1
testing/out/index.html
Normal 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>
|
|
@ -238,30 +238,22 @@ in with site; [
|
|||
}))
|
||||
|
||||
(it "throws with a list for a page" ({
|
||||
actual = copyTo "." {
|
||||
page = [];
|
||||
};
|
||||
actual = copyTo "." { page = [ ]; };
|
||||
throws = true;
|
||||
}))
|
||||
|
||||
(it "throws with null for a page" ({
|
||||
actual = copyTo "." {
|
||||
page = null;
|
||||
};
|
||||
actual = copyTo "." { page = null; };
|
||||
throws = true;
|
||||
}))
|
||||
|
||||
(it "throws with a bool for a page" ({
|
||||
actual = copyTo "." {
|
||||
page = true;
|
||||
};
|
||||
actual = copyTo "." { page = true; };
|
||||
throws = true;
|
||||
}))
|
||||
|
||||
(it "throws with a number for a page" ({
|
||||
actual = copyTo "." {
|
||||
page = 5;
|
||||
};
|
||||
actual = copyTo "." { page = 5; };
|
||||
throws = true;
|
||||
}))
|
||||
|
||||
|
|
Loading…
Reference in a new issue