alejandra

This commit is contained in:
tristan 2024-01-02 10:53:45 +00:00
parent b1426fb1ca
commit dc33fdf093
14 changed files with 1029 additions and 976 deletions

View file

@ -37,11 +37,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1704187012,
"narHash": "sha256-td0PQa1cTvjurjBmLpCynAgDV425Mh8sRObRtbTGxiQ=",
"lastModified": 1704192724,
"narHash": "sha256-Cx9os5FQU4UTjxt/uE1trPHxegXyhvV/wSiIiBWTDt0=",
"ref": "refs/heads/master",
"rev": "249bd9cda4fe9b02f3c85b22179109794eb57256",
"revCount": 2,
"rev": "b800bb46955d69cf7693d7c788a4d624eff2717f",
"revCount": 3,
"type": "git",
"url": "https://git.tristans.cloud/tristan/tix"
},

View file

@ -3,12 +3,17 @@
inputs = {tix.url = "git+https://git.tristans.cloud/tristan/tix";};
outputs = { self, nixpkgs, tix }:
let
outputs = {
self,
nixpkgs,
tix,
}: let
system = "x86_64-linux";
pkgs = import nixpkgs {inherit system;};
nixite = import ./nixite/. {inherit pkgs;};
in nixite // {
in
nixite
// {
packages.${system} = {
raw = nixite.mkSite (let
readme = {
@ -16,8 +21,7 @@
content = nixite.md.mdToPage ./README.md;
};
markup = {
"index.html" = with nixite.elems;
let
"index.html" = with nixite.elems; let
blue = nixite.style.component span "blue" {
style = {color = "blue";};
};
@ -40,9 +44,11 @@
]);
blog = nixite.md.readDir ./testing/blog;
};
site = (nixite.site.prepare { favicon = ./testing/src/favicon.png; }
markup);
in site);
site =
nixite.site.prepare {favicon = ./testing/src/favicon.png;}
markup;
in
site);
default = nixite.serve self.packages.${system}.raw;
@ -54,7 +60,7 @@
./testing/style.test.nix
];
watch = tix.watch "nix run .#test --show-trace" "fx";
watch = tix.watch "nix run .#test | ${pkgs.fx}/bin/fx" "fx";
dev = tix.watch "nix run .# --show-trace" "caddy";
};

View file

@ -1,7 +1,6 @@
{pkgs, ...}: {
mkSite = import ./make-site.nix pkgs;
serve = site:
(pkgs.writeShellScriptBin "serve" ''
serve = site: (pkgs.writeShellScriptBin "serve" ''
${pkgs.caddy}/bin/caddy file-server --root ${site}
'');
md = import ./md.nix;

View file

@ -1,4 +1,5 @@
let html = import ./html.nix;
let
html = import ./html.nix;
in {
html = html.tag "html";
# Document metadata
@ -41,12 +42,14 @@ in {
main = html.tag "main";
div = html.tag "div";
# Text-level semantics
a = html.tag "a" // {
__functor = self: href:
(if builtins.isString href then
(self // html.baseTag) { inherit href; }
else
(self // html.baseTag) href);
a =
html.tag "a"
// {
__functor = self: href: (
if builtins.isString href
then (self // html.baseTag) {inherit href;}
else (self // html.baseTag) href
);
};
em = html.tag "em";
strong = html.tag "strong";
@ -130,12 +133,14 @@ in {
canvas = html.tag "canvas";
# custom
List = html.tag "ul" // {
__functor = self: children:
(if builtins.isList children then
(self // html.baseTag) (map (html.tag "li") children)
else
html.incorporateAttrs self children);
List =
html.tag "ul"
// {
__functor = self: children: (
if builtins.isList children
then (self // html.baseTag) (map (html.tag "li") children)
else html.incorporateAttrs self children
);
};
Doc = params: child:
@ -149,5 +154,10 @@ in {
Stylesheet = params:
html.tag "link" ({
rel = "stylesheet";
} // (if builtins.isString params then { href = params; } else params)) "";
}
// (
if builtins.isString params
then {href = params;}
else params
)) "";
}

View file

@ -1,70 +1,78 @@
let
keyvalue = key: value:
assert builtins.isString key;
if builtins.isAttrs value then
builtins.trace "Skipping ${key} as it is a set" ""
else if value == "" || value == [ ] || value == false then
""
else if value == true then
key
else
''${key}="${toString value}"'';
if builtins.isAttrs value
then builtins.trace "Skipping ${key} as it is a set" ""
else if value == "" || value == [] || value == false
then ""
else if value == true
then key
else ''${key}="${toString value}"'';
in rec {
toHTML = elem:
if builtins.isString elem then
elem
else if builtins.isList elem then
builtins.toString (map toHTML elem)
else
"<${elem.tag} ${writeAttrs elem.attrs or { }}>${
if builtins.isString elem
then elem
else if builtins.isList elem
then builtins.toString (map toHTML elem)
else "<${elem.tag} ${writeAttrs elem.attrs or {}}>${
toHTML elem.child or ""
}</${elem.tag}>";
writeAttrs = attrs:
toString (builtins.filter (value: value != "") (builtins.attrValues
(builtins.mapAttrs (key: value:
if (builtins.isPath value) then
keyvalue key (baseNameOf value)
else if (builtins.substring 0 2 key) == "__" then
""
else
keyvalue key value) attrs)));
if (builtins.isPath value)
then keyvalue key (baseNameOf value)
else if (builtins.substring 0 2 key) == "__"
then ""
else keyvalue key value)
attrs)));
tag = t:
({
tag = t: ({
tag = t;
attrs = {};
} // baseTag);
}
// baseTag);
baseTag = {
__toString = self: toString (self "");
__functor = self: child:
(if !(isTag child) then
(if isSet child then
incorporateAttrs self child
__functor = self: child: (
if !(isTag child)
then
(
if isSet child
then incorporateAttrs self child
else
throw "tag child must be tag, list, or string, got ${
builtins.typeOf child
}")
}"
)
else
self // {
self
// {
inherit child;
__toString = toHTML;
});
}
);
};
incorporateAttrs = self: attrs: self // ({ attrs = self.attrs // attrs; });
incorporateAttrs = self: attrs: self // {attrs = self.attrs // attrs;};
isSet = a: builtins.isAttrs a && !a ? __toString;
isTag = tag:
(builtins.isString tag || builtins.isList tag
isTag = tag: (builtins.isString tag
|| builtins.isList tag
|| (tag ? __toString && builtins.isFunction tag.__toString));
addToHead = page: heads:
page // {
child = map
(e: if e.tag == "head" then e // { child = e.child ++ heads; } else e)
page
// {
child =
map
(e:
if e.tag == "head"
then e // {child = e.child ++ heads;}
else e)
page.child;
};
}

View file

@ -1,7 +1,7 @@
{ stdenv, ... }:
raw:
let site = import ./site.nix;
in stdenv.mkDerivation {
{stdenv, ...}: raw: let
site = import ./site.nix;
in
stdenv.mkDerivation {
name = "site";
src = ./.;
buildPhase = ''

View file

@ -1,28 +1,31 @@
let elems = import ./elems.nix;
let
elems = import ./elems.nix;
in rec {
readMd = md:
if builtins.isPath md then
processMd (builtins.readFile md)
else
processMd md;
if builtins.isPath md
then processMd (builtins.readFile md)
else processMd md;
processMd = processStr;
recReadMd = root:
assert builtins.isPath root;
builtins.mapAttrs (path: type:
if type == "directory" then
recReadMd (root + (/. + path))
else if type == "regular" then
mdToPage (root + (/. + path))
else
throw "Cannot read ${path}, file type ${type}") (builtins.readDir root);
if type == "directory"
then recReadMd (root + (/. + path))
else if type == "regular"
then mdToPage (root + (/. + path))
else throw "Cannot read ${path}, file type ${type}") (builtins.readDir root);
recFixAppendix = site:
builtins.listToAttrs (builtins.attrValues (builtins.mapAttrs (name: value: {
name = fixAppendix name;
value = if builtins.isAttrs value then recFixAppendix value else value;
}) site));
value =
if builtins.isAttrs value
then recFixAppendix value
else value;
})
site));
fixAppendix = builtins.replaceStrings [".md"] [".html"];
@ -31,27 +34,22 @@ in rec {
mdToPage = md:
elems.Doc {} [[(elems.title {} "markdown file")] (readMd md)];
code = block:
matchThen "(```)(.*)(```)" block (m: elems.code (builtins.elemAt m 1));
list = block:
matchThen (''
(- .+
)*(- .+
?)'') block (m: elems.List (splitList block));
matchThen "(- .+\n)*(- .+\n?)"
block (m: elems.List (splitList block));
splitList = block:
map (listItem) (builtins.filter (s: builtins.isString s && s != "")
map listItem (builtins.filter (s: builtins.isString s && s != "")
(builtins.split "\n" block));
listItem = str:
let
listItem = str: let
li = builtins.match "- (.*)" str;
checkbox = builtins.match "- \\[(.)] (.*)" str;
checked = builtins.elemAt checkbox 0;
content = builtins.elemAt checkbox 1;
in if checkbox == null then
li
in
if checkbox == null
then li
else [
(elems.input {
type = "checkbox";
@ -61,28 +59,41 @@ in rec {
content
];
replace = regex: apply: block:
(let
replace = regex: apply: block: (let
m = builtins.match regex block;
before = let v = builtins.elemAt m 0; in if v == null then "" else v;
before = let
v = builtins.elemAt m 0;
in
if v == null
then ""
else v;
after = toString (builtins.elemAt m (matchCount - 1));
matchCount = builtins.length m;
in if m == null then
block
else
(replace regex apply before) + (apply m) + after);
in
if m == null
then block
else (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;
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;
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;
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));
@ -96,60 +107,27 @@ in rec {
(basicRule (wrap "~~") elems.del)
(basicRule (wrap "\\*\\*") elems.strong)
(basicRule (wrapBreak "__") elems.strong)
(rule (contains "\\[(.*)]\\((.*)\\)") (m:
let
(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:
(rule "(.*\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 2)]))
))
(basicRule (''
(.*
)?(.+)
(.*)?'') elems.p)
(basicRule (''
(.*
)?```(.*)```(.*)?'') (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 "(.*\n\n)?(.+)\n(.*)?" elems.p)
(basicRule "(.*\n\n)?```(.*)```(.*)?" (elems.textarea {readonly = true;}))
(basicRule (containsBreak "###### ([^\n]+)") (elems.h6))
(basicRule (containsBreak "##### ([^\n]+)") (elems.h5))
(basicRule (containsBreak "#### ([^\n]+)") (elems.h4))
(basicRule (containsBreak "### ([^\n]+)") (elems.h3))
(basicRule (containsBreak "## ([^\n]+)") (elems.h2))
(basicRule (containsBreak "# ([^\n]+)") (elems.h1))
(basicRule (containsBreak "<(${linkmatcher})>") (m: elems.a m m))
];
@ -160,10 +138,11 @@ in rec {
containsBreak = matcher: "(.*[[:space:]])?${matcher}(.*)";
wrapBreak = matcher: containsBreak "${matcher}([^${matcher}]+)${matcher}";
matchThen = matcher: block: func:
let m = builtins.match matcher block;
in if m == null then
dontMatch block
matchThen = matcher: block: func: let
m = builtins.match matcher block;
in
if m == null
then dontMatch block
else {
matched = true;
block = func m;
@ -173,5 +152,4 @@ in rec {
matched = false;
inherit block;
};
}

View file

@ -3,12 +3,16 @@ let
elems = import ./elems.nix;
style = import ./style.nix;
in rec {
prepare = { favicon ? null, styles ? { }, }:
site:
let
prepare = {
favicon ? null,
styles ? {},
}: site: let
nullFn = p: p;
allStyles = styles // getStyles site;
doFavicon = if favicon != null then (applyFavicon favicon) else nullFn;
doFavicon =
if favicon != null
then (applyFavicon favicon)
else nullFn;
in (extractPaths (extractLinks (applyStyle allStyles (doFavicon site))));
getStyles = site:
@ -17,12 +21,11 @@ in rec {
flatten = site:
map (page:
if builtins.isAttrs page && page ? "__toString" then
page
else if builtins.isAttrs page then
flatten page
else
page) (builtins.attrValues site);
if builtins.isAttrs page && page ? "__toString"
then page
else if builtins.isAttrs page
then flatten page
else page) (builtins.attrValues site);
applyStyle = style: site: ((linkStyle site) // {"style.css" = style;});
@ -30,14 +33,13 @@ in rec {
eachPage site
(content: html.addToHead content [(elems.Stylesheet "/style.css")]);
eachPage = site: callback:
(builtins.mapAttrs (name: content:
if builtins.isAttrs content && content ? "__toString" then
callback content
else if builtins.isAttrs content then
eachPage content callback
else
content) site);
eachPage = site: callback: (builtins.mapAttrs (name: content:
if builtins.isAttrs content && content ? "__toString"
then callback content
else if builtins.isAttrs content
then eachPage content callback
else content)
site);
applyFavicon = icon: site:
eachPage site (content:
@ -49,19 +51,21 @@ in rec {
]);
extractPaths = content:
switchPaths content // {
switchPaths content
// {
static = (content.static or {}) // getPaths content;
};
extractLinks = content:
switchLinks content // {
switchLinks content
// {
static = (content.static or {}) // getLinks content;
};
isLink = value:
builtins.isAttrs value && value ? type && value.type == "link";
switchLinks = runDeep (isLink) (value: "/static/" + value.name);
switchLinks = runDeep isLink (value: "/static/" + value.name);
getLinks = content: (builtins.listToAttrs (getLinksKV content));
@ -72,19 +76,30 @@ in rec {
};
runLink = f:
if !builtins.isFunction f then
null
if !builtins.isFunction f
then null
else
(let res = f { }; in (if !builtins.isAttrs res then null else res));
(let
res = f {};
in (
if !builtins.isAttrs res
then null
else res
));
runDeep = when: do: set:
(if builtins.isAttrs set then
runDeep = when: do: set: (
if builtins.isAttrs set
then
builtins.mapAttrs
(key: value: if when value then do value else runDeep when do value) set
else if builtins.isList set then
(map (runDeep when do) set)
else
set);
(key: value:
if when value
then do value
else runDeep when do value)
set
else if builtins.isList set
then (map (runDeep when do) set)
else set
);
switchPaths = runDeep builtins.isPath (value: "/static/" + baseNameOf value);
@ -96,35 +111,60 @@ in rec {
value = v: v;
};
getAllKV = { when, key, value }@params:
path:
(if when path then [{
getAllKV = {
when,
key,
value,
} @ params: path: (
if when path
then [
{
name = key path;
value = value path;
}] else if builtins.isAttrs path then
}
]
else if builtins.isAttrs path
then
builtins.concatMap (getAllKV params) (builtins.attrValues
(builtins.mapAttrs
(n: v: if (builtins.substring 0 2 n == "__") then null else v) path))
else if builtins.isList path then
builtins.concatMap (getAllKV params) path
else
[ ]);
(n: v:
if (builtins.substring 0 2 n == "__")
then null
else v)
path))
else if builtins.isList path
then builtins.concatMap (getAllKV params) path
else []
);
link = { name, content }@page: page // { type = "link"; };
link = {
name,
content,
} @ page:
page // {type = "link";};
copyTo = prefix: site:
builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content:
if builtins.isString content then ''
if builtins.isString content
then ''
cp ${builtins.toFile name content} ${prefix}/${name}
'' else if builtins.isPath content then ''
''
else if builtins.isPath content
then ''
cp -r ${content} ${prefix}/${name}
'' else if builtins.isAttrs content && content ? "__toString" then ''
''
else if builtins.isAttrs content && content ? "__toString"
then ''
cp ${builtins.toFile name (toString content)} ${prefix}/${name}
'' else if builtins.isAttrs content then ''
''
else if builtins.isAttrs content
then ''
mkdir -p ${prefix}/${name}
${copyTo "${prefix}/${name}" content}
'' else
''
else
throw "Site page must be string, path or attrset, but got ${
builtins.typeOf content
}: [${toString content}]") site));
}: [${toString content}]")
site));
}

View file

@ -1,10 +1,9 @@
let
styleToString = identifier: styles:
if !builtins.isAttrs styles then
""
else if styles == { } then
""
if !builtins.isAttrs styles
then ""
else if styles == {}
then ""
else
assert builtins.isString identifier; ''
${identifier} {
@ -16,24 +15,31 @@ let
'';
getStyle = element:
if builtins.isAttrs element && element.attrs ? __id then
if builtins.isAttrs element && element.attrs ? __id
then
({
${element.attrs.__id} = element.attrs.style or {};
} // (if element.attrs ? __extends then {
}
// (
if element.attrs ? __extends
then {
${element.attrs.__extends.attrs.__id or element.attrs.__extends.tag} =
element.attrs.__extends.attrs.style or {};
} else
{ }))
else
{ };
}
else {}
))
else {};
getStyles = element:
(getStyle element) // (if builtins.isList element then
getStylesFromList element
else if element ? child then
getStyles element.child
else
{ }) // {
(getStyle element)
// (
if builtins.isList element
then getStylesFromList element
else if element ? child
then getStyles element.child
else {}
)
// {
__toString = stylesToString;
};
@ -42,7 +48,8 @@ let
(map getStyles elements);
mkProps = tag: class: props:
props // {
props
// {
__id = "${tag.tag}.${class}";
__extends = tag;
class = (tag.attrs.class or []) ++ [class] ++ (props.class or []);
@ -50,8 +57,7 @@ let
stylesToString = styles:
builtins.concatStringsSep ""
(builtins.attrValues (builtins.mapAttrs (styleToString) styles));
(builtins.attrValues (builtins.mapAttrs styleToString styles));
in {
inherit getStyle getStyles stylesToString;

View file

@ -1,9 +1,9 @@
{ it, ... }:
let
{it, ...}: let
elems = import ../nixite/elems.nix;
style = import ../nixite/style.nix;
html = import ../nixite/html.nix;
in with elems; [
in
with elems; [
(it "makes a p tag" {
expected = html.tag "p" {} "foobar";
actual = p {} "foobar";
@ -49,8 +49,11 @@ in with elems; [
(it "lets you extend the a tag" {
expected = ["linky"];
actual = ((style.component a "linky" { }) "https://example.com"
"example").attrs.class;
actual =
((style.component a "linky" {}) "https://example.com"
"example")
.attrs
.class;
asString = true;
})

View file

@ -1,20 +1,23 @@
{ it, ... }:
let html = import ../nixite/html.nix;
in with html; [
(it "keeps info in the tag" (let p = tag "p";
{it, ...}: let
html = import ../nixite/html.nix;
in
with html; [
(it "keeps info in the tag" (let
p = tag "p";
in {
actual = p.tag;
expected = "p";
}))
(it "keeps attr info in the tag" (let p = tag "p" { class = ""; };
(it "keeps attr info in the tag" (let
p = tag "p" {class = "";};
in {
actual = p.attrs;
expected = {class = "";};
}))
(it "keeps tag after setting attrs" (let p = tag "p" { class = ""; };
(it "keeps tag after setting attrs" (let
p = tag "p" {class = "";};
in {
actual = p.tag;
expected = "p";
@ -30,7 +33,8 @@ in with html; [
removeDunders = true;
})
(it "makes element" (let para = (tag "p" { });
(it "makes element" (let
para = tag "p" {};
in {
expected = "p";
actual = para.tag;
@ -38,7 +42,7 @@ in with html; [
(it "keeps attrs on element" (let
attrs = {style = {foo = "bar";};};
para = (tag "p" attrs);
para = tag "p" attrs;
in {
expected = attrs;
actual = para.attrs;
@ -46,7 +50,7 @@ in with html; [
(it "makes renderable element" (let
attrs = {style = {foo = "bar";};};
para = (tag "p" attrs);
para = tag "p" attrs;
in {
expected = "<p ></p>";
actual = toString (para "");
@ -54,7 +58,7 @@ in with html; [
(it "keeps tag" (let
attrs = {style = {foo = "bar";};};
para = (tag "p" attrs);
para = tag "p" attrs;
in {
expected = "p";
actual = (para "").tag;
@ -62,25 +66,28 @@ in with html; [
(it "keeps style" (let
attrs = {style = {foo = "bar";};};
para = (tag "p" attrs);
para = tag "p" attrs;
in {
expected = {foo = "bar";};
actual = (para "").attrs.style;
}))
(it "needs no args to make string" (let p = tag "p";
(it "needs no args to make string" (let
p = tag "p";
in {
actual = toString p;
expected = "<p ></p>";
}))
(it "needs no content to make string" (let p = tag "p";
(it "needs no content to make string" (let
p = tag "p";
in {
actual = toString (p {class = "foobar";});
expected = ''<p class="foobar"></p>'';
}))
(it "can take many sets of props" (let p = tag "p";
(it "can take many sets of props" (let
p = tag "p";
in {
actual = toString (p {class = "foobar";} {style = "a style";});
expected = ''<p class="foobar" style="a style"></p>'';
@ -88,39 +95,40 @@ in with html; [
(it "works recursively" (let
attrs = {style = {foo = "bar";};};
para = (tag "p" attrs);
a = (tag "a" { });
para = tag "p" attrs;
a = tag "a" {};
in {
expected = "<p ><a >hello</a></p>";
actual = toString (para (a "hello"));
}))
(it "throws with function child" ({
(it "throws with function child" {
actual = toString (tag "p" (i: ""));
throws = true;
}))
})
(it "throws with a number" ({
(it "throws with a number" {
actual = toString (tag "p" 5);
throws = true;
}))
})
(it "throws with a bool" ({
(it "throws with a bool" {
actual = toString (tag "p" true);
throws = true;
}))
})
(it "throws with a null" ({
(it "throws with a null" {
actual = toString (tag "p" null);
throws = true;
}))
})
(it "concatinates classes" {
actual = toString (tag "p" {class = ["class1" "class2"];} "Hello");
expected = ''<p class="class1 class2">Hello</p>'';
})
(it "applies style" (let page = tag "html" { } [ (tag "head" { } [ "foo" ]) ];
(it "applies style" (let
page = tag "html" {} [(tag "head" {} ["foo"])];
in {
actual = addToHead page ["bar"];
expected = {
@ -131,12 +139,11 @@ in with html; [
removeDunders = true;
}))
(it "renders on / off attrs" ({
(it "renders on / off attrs" {
actual = toString (tag "p" {
on = true;
off = false;
});
expected = "<p on></p>";
}))
})
]

View file

@ -1,10 +1,9 @@
{ it, ... }:
let
{it, ...}: let
md = import ../nixite/md.nix;
elems = import ../nixite/elems.nix;
in with md; [
(it "matches a list of one element" ({
in
with md; [
(it "matches a list of one element" {
actual = list ''
- something
'';
@ -13,9 +12,9 @@ in with md; [
block = elems.List ["something"];
};
asJSON = true;
}))
})
(it "makes a list of many elements" ({
(it "makes a list of many elements" {
actual = list ''
- something
- something else
@ -25,9 +24,9 @@ in with md; [
block = elems.List ["something" "something else"];
};
asJSON = true;
}))
})
(it "makes a list of many checkboxes" ({
(it "makes a list of many checkboxes" {
actual = list ''
- [ ] something
- [X] something else
@ -54,9 +53,9 @@ in with md; [
];
};
asJSON = true;
}))
})
(it "matches a list with no whitespace around" ({
(it "matches a list with no whitespace around" {
actual = list ''
- something
- something else'';
@ -65,9 +64,10 @@ in with md; [
block = elems.List ["something" "something else"];
};
asJSON = true;
}))
})
(it "doesnt match not a list" (let str = "blah blah";
(it "doesnt match not a list" (let
str = "blah blah";
in {
actual = list str;
expected = {
@ -76,11 +76,11 @@ in with md; [
};
}))
(it "processes whole string with all rules" ({
(it "processes whole string with all rules" {
actual = processStr ''
this text **may** *or may not* contain **bold** words *inside* it.
'';
expected = (elems.p [
expected = elems.p [
"this text"
(elems.strong "may")
(elems.em "or may not")
@ -89,9 +89,9 @@ in with md; [
"words"
(elems.em "inside")
"it."
]);
];
asString = true;
}))
})
(it "makes paragraphs" {
actual = readMd ''

View file

@ -1,10 +1,10 @@
{ it, ... }:
let
{it, ...}: let
html = import ../nixite/html.nix;
elems = import ../nixite/elems.nix;
site = import ../nixite/site.nix;
style = import ../nixite/style.nix;
in with site; [
in
with site; [
(it "applies a style" {
expected = {
"index.html" = html.tag "html" {} [
@ -27,7 +27,8 @@ in with site; [
this is a stylesheet
'';
};
actual = applyStyle ''
actual =
applyStyle ''
this is a stylesheet
'' {
"index.html" = html.tag "html" {} [
@ -182,8 +183,7 @@ in with site; [
in {
actual = getLinks {
something = "yes";
a-list =
[ { thingy = coolPage; } [ (elems.img { src = otherPage; } "") ] ];
a-list = [{thingy = coolPage;} [(elems.img {src = otherPage;} "")]];
};
expected = {
"cool-page" = "cool content";
@ -202,7 +202,6 @@ in with site; [
name = "page2";
content = "stuff";
};
in {
actual = extractLinks {
something = "";
@ -220,7 +219,7 @@ in with site; [
};
}))
(it "copies all the files" ({
(it "copies all the files" {
actual = copyTo "." {
page = "this is a page";
subdir = {
@ -235,29 +234,29 @@ in with site; [
cp /nix/store/ic6fyy8wg8r4338a3m5kinmg11igxsyj-page ./subdir/page
'';
}))
})
(it "throws with a list for a page" ({
(it "throws with a list for a page" {
actual = copyTo "." {page = [];};
throws = true;
}))
})
(it "throws with null for a page" ({
(it "throws with null for a page" {
actual = copyTo "." {page = null;};
throws = true;
}))
})
(it "throws with a bool for a page" ({
(it "throws with a bool for a page" {
actual = copyTo "." {page = true;};
throws = true;
}))
})
(it "throws with a number for a page" ({
(it "throws with a number for a page" {
actual = copyTo "." {page = 5;};
throws = true;
}))
})
(it "prepares the site" ({
(it "prepares the site" {
actual = prepare {favicon = ./src/favicon.png;} {
"index.html" = elems.html {} [
(elems.head {} [(elems.title {} "foobar")])
@ -310,6 +309,5 @@ in with site; [
"style.css" = "";
};
asJSON = true;
}))
})
]

View file

@ -1,10 +1,9 @@
{ it, ... }:
let
{it, ...}: let
style = import ../nixite/style.nix;
elems = import ../nixite/elems.nix;
in [
(it "fetches empty style" (let para = (style.component elems.p "para" { });
(it "fetches empty style" (let
para = style.component elems.p "para" {};
in {
expected = {
"p" = {};
@ -15,7 +14,7 @@ in [
(it "fetches style" (let
attrs = {style = {foo = "bar";};};
para = (style.component elems.p "para" attrs);
para = style.component elems.p "para" attrs;
in {
expected = {
"p" = {};
@ -26,7 +25,7 @@ in [
(it "appliess class" (let
attrs = {style = {foo = "bar";};};
para = (style.component elems.p "para" attrs);
para = style.component elems.p "para" attrs;
in {
expected = ["para"];
actual = (para "").attrs.class;
@ -37,7 +36,7 @@ in [
style = {foo = "bar";};
class = ["other" "class"];
};
para = (style.component elems.p "para" attrs);
para = style.component elems.p "para" attrs;
in {
expected = ["para" "other" "class"];
actual = (para "").attrs.class;
@ -45,7 +44,7 @@ in [
(it "fetches style for class" (let
s = {foo = "bar";};
para = (style.component elems.p "para" { style = s; });
para = style.component elems.p "para" {style = s;};
in {
expected = {
"p" = {};
@ -61,8 +60,8 @@ in [
"p.para" = {foo = "bar";};
"div.link" = {this = "that";};
};
para = (style.component elems.p "para" { style = s."p.para"; });
div = (style.component elems.div "link" { style = s."div.link"; });
para = style.component elems.p "para" {style = s."p.para";};
div = style.component elems.div "link" {style = s."div.link";};
in {
expected = s;
actual = style.getStyles (para (div "hello"));
@ -76,8 +75,8 @@ in [
"p.para" = {foo = "bar";};
"div.link" = {this = "that";};
};
para = (style.component elems.p "para" { style = s."p.para"; });
a = (style.component elems.div "link" { style = s."div.link"; });
para = style.component elems.p "para" {style = s."p.para";};
a = style.component elems.div "link" {style = s."div.link";};
in {
expected = s;
actual = style.getStyles (para [(a "hello")]);
@ -91,8 +90,8 @@ in [
"p.para" = {foo = "bar";};
"div.link" = {this = "that";};
};
para = (style.component elems.p "para" { style = s."p.para"; });
a = (style.component elems.div "link" { style = s."div.link"; });
para = style.component elems.p "para" {style = s."p.para";};
a = style.component elems.div "link" {style = s."div.link";};
in {
expected = s;
actual = style.getStyles (para [(a "hello") (a "hello")]);
@ -122,8 +121,8 @@ in [
"p.para" = {foo = "bar";};
"p.oof" = {oof = "yes";};
};
para = (style.component elems.p "para" { style = s."p.para"; });
para2 = (style.component para "oof" { style = s."p.oof"; });
para = style.component elems.p "para" {style = s."p.para";};
para2 = style.component para "oof" {style = s."p.oof";};
in {
expected = s;
actual = style.getStyles (para2 "");
@ -137,11 +136,10 @@ in [
"p.para" = {foo = "bar";};
"p.para.oof" = {oof = "yes";};
};
para = (style.component elems.p "para" { style = s."p.para"; });
para2 = (style.component para "oof" { style = s."p.para.oof"; });
para = style.component elems.p "para" {style = s."p.para";};
para2 = style.component para "oof" {style = s."p.para.oof";};
in {
expected = ["para" "oof"];
actual = (para2 "").attrs.class;
}))
]