diff --git a/README.md b/README.md index ead6413..4a959c7 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ nix build .#raw - [ ] links - [X] codeblocks - [ ] subscript -- [ ] highlight -- [ ] italics -- [ ] bold +- [X] highlight +- [X] italics +- [X] bold + diff --git a/nixite/md.nix b/nixite/md.nix index 8278cc2..818021f 100644 --- a/nixite/md.nix +++ b/nixite/md.nix @@ -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; }; - - dontMatch = block: { matched = false; inherit block; }; + 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; + }; } diff --git a/testing/blog/index.md b/testing/blog/index.md index 45e6fa5..eae082f 100644 --- a/testing/blog/index.md +++ b/testing/blog/index.md @@ -1,9 +1,14 @@ # yeee -ye +I need some *emphasis*... -& +that's **bold**! -dir -home +==mark== the important parts. + +but ~~forget the rest~~. + +drink lot's of H ~2~O ^if you want^! + + diff --git a/testing/it.nix b/testing/it.nix index d33549d..5205845 100644 --- a/testing/it.nix +++ b/testing/it.nix @@ -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 '.' + '') diff --git a/testing/md.test.nix b/testing/md.test.nix index 6086f03..f16979f 100644 --- a/testing/md.test.nix +++ b/testing/md.test.nix @@ -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 = '' - markdown file

yeee

ye

&

dir - home

''; + actual = toString (mdToPage ./blog/index.md) + "\n"; + expected = builtins.readFile ./out/index.html; asString = true; }) diff --git a/testing/out/index.html b/testing/out/index.html new file mode 100644 index 0000000..f3f4d29 --- /dev/null +++ b/testing/out/index.html @@ -0,0 +1 @@ +markdown file

yeee

I need some emphasis...

that's bold!

mark the important parts.

but forget the rest.

drink lot's of H 2O if you want!

https://www.markdownguide.org/basic-syntax/

diff --git a/testing/site.test.nix b/testing/site.test.nix index 50770f8..15a00d4 100644 --- a/testing/site.test.nix +++ b/testing/site.test.nix @@ -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; }))