component extending, add all html elems

also use nixfmt
This commit is contained in:
tristan 2023-12-31 21:33:42 +00:00
parent ccc6b53b91
commit cb6d9652f8
15 changed files with 548 additions and 604 deletions

View file

@ -1,52 +1,43 @@
{
description = "A site in nix?";
outputs = {
self,
nixpkgs,
}: let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
};
nixite = import ./nixite/. {inherit pkgs;};
in
nixite
// {
outputs = { self, nixpkgs, }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
nixite = import ./nixite/. { inherit pkgs; };
in nixite // {
packages.${system} = {
default = nixite.mkSite (
nixite.site.applyStyle ./testing/src/style.css
default = nixite.mkSite (nixite.site.applyStyle ./testing/src/style.css
(nixite.site.extractPaths {
"index.html" = with nixite.elems; (doc [
[
(title "Nixite")
(nixite.html.tag "link" {rel = "shortcut icon"; type = "image/png"; href = ./testing/src/favicon.png;} "")
]
(main [
(link "/blog" "blog")
(list [
"item 1"
"item 2"
"item 3"
"index.html" = with nixite.elems;
(Doc [
[
(title "Nixite")
(nixite.html.tag "link" {
rel = "shortcut icon";
type = "image/png";
href = ./testing/src/favicon.png;
} "")
]
(main [
(a "/blog" "blog")
(list [ "item 1" "item 2" "item 3" ])
])
])
]);
]);
blog = nixite.md.readDir ./testing/blog;
})
);
}));
serve = nixite.serve self.packages.${system}.default;
test = let
test = import ./testing/import.nix;
in
pkgs.writeShellScriptBin "test" ''
${test ./testing/md.test.nix}
${test ./testing/html.test.nix}
${test ./testing/elems.test.nix}
${test ./testing/site.test.nix}
${test ./testing/style.test.nix}
'';
test = let test = import ./testing/import.nix;
in pkgs.writeShellScriptBin "test" ''
${test ./testing/md.test.nix}
${test ./testing/html.test.nix}
${test ./testing/elems.test.nix}
${test ./testing/site.test.nix}
${test ./testing/style.test.nix}
'';
};
};
}

View file

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

View file

@ -1,47 +1,60 @@
let
html = import ./html.nix;
s = import ./style.nix;
in
(s.styled "p" "p" {})
(s.styled "div" "div" {})
(s.styled "section" "section" {})
(s.styled "span" "span" {})
(s.styled "main" "main" {})
(s.styled "article" "article" {})
(s.styled "title" "title" {class = [];})
(s.styled "h1" "h1" {})
(s.styled "h2" "h2" {})
(s.styled "h3" "h3" {})
(s.styled "list" "ul" {
__child = child:
assert builtins.isList child; (map (html.tag "li" {}) child);
})
(s.styled "doc" "html" {
__child = child:
assert builtins.isList child;
assert builtins.length child == 2;
assert builtins.isList (builtins.elemAt child 0); [
(html.tag "head" {} (builtins.elemAt child 0))
(html.tag "body" {} (builtins.elemAt child 1))
];
lang = "en";
class = [];
})
(s.styled "link" "a" {
__self = self: attrs: child:
if builtins.isString attrs then
self {href = attrs;} child else
self attrs child;
})
(s.styled "stylesheet" "link" {
rel = "stylesheet";
class = [];
__self = self: attrs:
if builtins.isString attrs then
self {href = attrs;} "" else
self attrs "";
})
// {
h = v: child:
html.tag "h${toString v}" {} child;
}
base = tag: (s.styled tag tag { class = [ ]; });
in (base "html") (base "head") (base "title") (base "base") (base "link")
(base "meta")
# (base "style" ) # borks styled coponents
(base "body") (base "article") (base "section") (base "nav") (base "aside")
(base "h1") (base "h2") (base "h3") (base "h4") (base "h5") (base "h6")
(base "hgroup") (base "header") (base "footer") (base "address") (base "p")
(base "hr") (base "pre") (base "blockquote") (base "ol") (base "ul")
(base "menu") (base "li") (base "dl") (base "dt") (base "dd") (base "figure")
(base "figcaption") (base "main") (base "div") (base "a") (base "em")
(base "strong") (base "small") (base "s") (base "cite") (base "q") (base "dfn")
(base "abbr") (base "ruby") (base "rt") (base "rp") (base "data") (base "time")
(base "code") (base "var") (base "samp") (base "kbd") (base "sub") (base "sup")
(base "i") (base "b") (base "u") (base "mark") (base "bdi") (base "bdo")
(base "span") (base "br") (base "wbr") (base "ins") (base "del")
(base "picture") (base "source") (base "img") (base "iframe") (base "embed")
(base "object") (base "param") (base "video") (base "audio") (base "track")
(base "map") (base "area") (base "table") (base "caption") (base "colgroup")
(base "col") (base "tbody") (base "thead") (base "tfoot") (base "tr")
(base "td") (base "th") (base "form") (base "label") (base "input")
(base "button") (base "select") (base "datalist") (base "optgroup")
(base "option") (base "textarea") (base "output") (base "progress")
(base "meter") (base "fieldset") (base "legend") (base "details")
(base "summary") (base "dialog") (base "script") (base "noscript")
(base "template") (base "slot") (base "canvas")
(s.styled "List" "ul" {
__child = child:
assert builtins.isList child;
(map (html.tag "li" { }) child);
}) (s.styled "Doc" "html" {
__child = child:
assert builtins.isList child;
assert builtins.length child == 2;
assert builtins.isList (builtins.elemAt child 0); [
(html.tag "head" { } (builtins.elemAt child 0))
(html.tag "body" { } (builtins.elemAt child 1))
];
lang = "en";
class = [ ];
}) (s.styled "a" "a" {
__self = self: attrs: child:
if builtins.isString attrs then
self { href = attrs; } child
else
self attrs child;
}) (s.styled "Stylesheet" "link" {
rel = "stylesheet";
class = [ ];
__self = self: attrs:
if builtins.isString attrs then
self { href = attrs; } ""
else
self attrs "";
}) // {
H = v: child: html.tag "h${toString v}" { } child;
}

View file

@ -1,27 +1,30 @@
let
keyvalue = key: value:
keyvalue = key: value:
assert builtins.isString key;
if value == "" || value == [] || value == {} then "" else
''${key}="${toString value}"'';
if value == "" || value == [ ] || value == { } then
""
else
''${key}="${toString value}"'';
in rec {
toHTML = elem:
if builtins.typeOf elem == "string"
then elem
else if builtins.typeOf elem == "list"
then builtins.toString (map toHTML elem)
else ''<${elem.tag} ${writeAttrs elem.attrs}>${toHTML elem.child}</${elem.tag}>'';
if builtins.typeOf elem == "string" then
elem
else if builtins.typeOf elem == "list" then
builtins.toString (map toHTML elem)
else
"<${elem.tag} ${writeAttrs elem.attrs}>${
toHTML elem.child
}</${elem.tag}>";
writeAttrs = attrs:
toString (builtins.filter (value: value != "") (builtins.attrValues (
builtins.mapAttrs (key: value:
if (builtins.isPath value)
then keyvalue key (baseNameOf value)
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
if (builtins.substring 0 2 key) == "__"
then ""
else keyvalue key value)
attrs
)));
keyvalue key value) attrs)));
tag = tag: attrs: child: {
inherit tag attrs child;
@ -29,20 +32,9 @@ in rec {
};
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,16 +1,16 @@
{stdenv, ...}: raw: let
site = import ./site.nix;
in
stdenv.mkDerivation {
name = "site";
src = ./.;
buildPhase = ''
mkdir dist
{ stdenv, ... }:
raw:
let site = import ./site.nix;
in stdenv.mkDerivation {
name = "site";
src = ./.;
buildPhase = ''
mkdir dist
${site.copyTo "dist" raw}
${site.copyTo "dist" raw}
'';
installPhase = ''
cp -r dist $out
'';
}
'';
installPhase = ''
cp -r dist $out
'';
}

View file

@ -1,60 +1,42 @@
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 = md: (map (c:
if builtins.isString c
then mdBlock c
else "") (builtins.split "\n\n" md));
processMd = md:
(map (c: if builtins.isString c then mdBlock c else "")
(builtins.split "\n\n" md));
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);
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);
recFixAppendix = site:
builtins.listToAttrs (
builtins.attrValues (
builtins.mapAttrs (name: value: {
name = fixAppendix name;
value =
if builtins.isAttrs value
then recFixAppendix value
else value;
})
site
)
);
builtins.listToAttrs (builtins.attrValues (builtins.mapAttrs (name: value: {
name = fixAppendix name;
value = if builtins.isAttrs value then recFixAppendix value else value;
}) site));
fixAppendix = builtins.replaceStrings [".md"] [".html"];
fixAppendix = builtins.replaceStrings [ ".md" ] [ ".html" ];
readDir = root: recFixAppendix (recReadMd root);
mdToPage = md: elems.doc [
[(elems.title "markdown file")]
(readMd md)
];
mdToPage = md: elems.Doc [ [ (elems.title "markdown file") ] (readMd md) ];
mdBlock = block: let
m = heading block;
h =
if m == null
then 0
else builtins.stringLength (builtins.elemAt m 0);
in
if m == null
then elems.p {} block
else elems.h h (builtins.elemAt m 1);
mdBlock = block:
let
m = heading block;
h = if m == null then 0 else builtins.stringLength (builtins.elemAt m 0);
in if m == null then elems.p { } block else elems.H h (builtins.elemAt m 1);
heading = block: builtins.match "(#+) (.*)" block;
}

View file

@ -2,76 +2,57 @@ let
html = import ./html.nix;
elems = import ./elems.nix;
in rec {
applyStyle = style: site: (linkStyle site) // {"style.css" = style;};
applyStyle = style: site: (linkStyle site) // { "style.css" = style; };
linkStyle = site: (builtins.mapAttrs (
name: content:
if builtins.isAttrs content && content ? "__toString"
then html.addToHead content [(elems.stylesheet "/style.css")]
else if builtins.isAttrs content
then linkStyle content
else content
)
site);
linkStyle = site:
(builtins.mapAttrs (name: content:
if builtins.isAttrs content && content ? "__toString" then
html.addToHead content [ (elems.Stylesheet "/style.css") ]
else if builtins.isAttrs content then
linkStyle content
else
content) site);
extractPaths = content:
switchPaths content // {static = getPaths content;};
extractPaths = content: switchPaths content // { static = getPaths content; };
switchPaths = content: (
if builtins.isAttrs content
then
switchPaths = content:
(if builtins.isAttrs content then
builtins.mapAttrs (key: value:
if builtins.isPath value
then ("/static/" + baseNameOf value)
else switchPaths value)
content
else if builtins.isList content
then (map switchPaths content)
else content
);
if builtins.isPath value then
("/static/" + baseNameOf value)
else
switchPaths value) content
else if builtins.isList content then
(map switchPaths content)
else
content);
getPaths = content: (builtins.listToAttrs (getPathsKV content));
getPathsKV = path: (
if builtins.isPath path
then [
{
name = baseNameOf path;
value = path;
}
]
else if builtins.isAttrs path
then builtins.concatLists (map getPathsKV (builtins.attrValues path))
else if builtins.isList path
then builtins.concatLists (map getPathsKV path)
else []
);
getPathsKV = path:
(if builtins.isPath path then [{
name = baseNameOf path;
value = path;
}] else if builtins.isAttrs path then
builtins.concatLists (map getPathsKV (builtins.attrValues path))
else if builtins.isList path then
builtins.concatLists (map getPathsKV path)
else
[ ]);
copyTo = prefix: site:
builtins.toString (
builtins.attrValues (
builtins.mapAttrs (
name: content:
if builtins.isString content
then ''
cp ${builtins.toFile name content} ${prefix}/${name}
''
else if builtins.isPath content
then ''
cp -r ${content} ${prefix}/${name}
''
else if builtins.isAttrs content && content ? "__toString"
then ''
cp ${builtins.toFile name (toString content)} ${prefix}/${name}
''
else if builtins.isAttrs content
then ''
mkdir -p ${prefix}/${name}
${copyTo "${prefix}/${name}" content}
''
else throw "Site page must be string, path or attrset, but got ${builtins.typeOf content}: [${toString content}]"
)
site
)
);
builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content:
if builtins.isString content then ''
cp ${builtins.toFile name content} ${prefix}/${name}
'' else if builtins.isPath content then ''
cp -r ${content} ${prefix}/${name}
'' else if builtins.isAttrs content && content ? "__toString" then ''
cp ${builtins.toFile name (toString content)} ${prefix}/${name}
'' else if builtins.isAttrs content then ''
mkdir -p ${prefix}/${name}
${copyTo "${prefix}/${name}" content}
'' else
throw "Site page must be string, path or attrset, but got ${
builtins.typeOf content
}: [${toString content}]") site));
}

View file

@ -2,65 +2,63 @@ let
html = import ./html.nix;
join = {
__functor = self: new:
self
// new
// {style = self.style + new.style;};
__functor = self: new: self // new // { style = self.style + new.style; };
};
mkStyle = identifier: styles:
if styles == {}
then ""
if styles == { } then
""
else ''
${identifier} {
${toString (builtins.attrValues (
builtins.mapAttrs (
key: value: ''${key}: ${value};''
)
styles
))}
${
toString (builtins.attrValues
(builtins.mapAttrs (key: value: "${key}: ${value};") styles))
}
}
'';
mkIdentifier = name: tag: {
class ? [name],
id ? "",
...
}:
"${tag}"
+ builtins.concatStringsSep "" (map (c: "." + c) class)
+ (
if id != ""
then "#"
else ""
)
+ id;
mkIdentifier = name: tag:
{ class ? [ name ], id ? "", ... }:
"${tag}" + builtins.concatStringsSep "" (map (c: "." + c) class)
+ (if id != "" then "#" else "") + id;
in {
styled = name: tag: cprops: let
__child = cprops.__child or (child: child);
styled = name: tag: cprops:
assert builtins.isString name;
let
__child = cprops.__child or (child: child);
self = props:
html.tag tag (props // {class = [name];} // cprops // {style = "";});
joinProps = (cprops // {
__functor = prev: next:
prev // next // {
class = prev.class ++ next.class or [ ];
};
class = if cprops ? class then
if cprops.class == [ ] then [ ] else [ name ] ++ cprops.class
else
[ name ];
}) { style = ""; };
__self = (cprops.__self or (self: props:
if builtins.isAttrs props
then (child: ( self props (__child child) ))
else if builtins.isString props || builtins.isList props
then (self {} (__child props))
else throw "Call element with attributes and child."
)) self;
self = if builtins.isFunction tag then
props: tag (joinProps props)
else if builtins.isString tag then
props: html.tag tag (joinProps props)
else
throw "You may only style a tag (string) or element, got ${
builtins.typeOf tag
}";
in
{
__self = (cprops.__self or (self: props:
if builtins.isAttrs props then
(child: (self props (__child child)))
else if builtins.isString props || builtins.isList props then
(self { } (__child props))
else
throw "Call element with attributes and child.")) self;
in {
${name} = __self;
style = mkStyle (mkIdentifier name tag cprops) ( cprops.style or {} );
}
// join;
style = mkStyle (mkIdentifier name tag cprops) (cprops.style or { });
} // join;
style = identifier: styles:
{
style = mkStyle identifier styles;
}
// join;
style = identifier: styles: { style = mkStyle identifier styles; } // join;
}

View file

@ -2,83 +2,82 @@ let
elems = import ../nixite/elems.nix;
html = import ../nixite/html.nix;
it = import ./it.nix;
in
with elems; [
(it "makes a p tag" {
expected = html.tag "p" {class = ["p"];} "foobar";
actual = p {} "foobar";
asString = true;
})
(it "makes a div tag" {
expected = html.tag "div" {class = ["div"];} "foobar";
actual = div {} "foobar";
asString = true;
})
(it "makes a section tag" {
expected = html.tag "section" {class = ["section"];} "foobar";
actual = section {} "foobar";
asString = true;
})
(it "makes a span tag" {
expected = html.tag "span" {class = ["span"];} "foobar";
actual = span {} "foobar";
asString = true;
})
(it "makes a main tag" {
expected = html.tag "main" {class = ["main"];} ["yeet"];
actual = main {} ["yeet"];
asString = true;
})
(it "makes an h1 tag" {
expected = html.tag "h1" {} "foobar";
actual = h 1 "foobar";
asString = true;
})
(it "makes an h2 tag" {
expected = html.tag "h2" {} "foobar";
actual = h 2 "foobar";
asString = true;
})
(it "makes a title tag" {
expected = html.tag "title" {class = [];} "foobar";
actual = title {} "foobar";
asString = true;
})
(it "makes an a tag" {
expected = html.tag "a" {class = ["link"]; href = "https://example.com";} "example";
actual = link "https://example.com" "example";
asString = true;
})
(it "makes a stylesheet link" {
expected = html.tag "link" {
href = "/style";
rel = "stylesheet";
} "";
actual = stylesheet {href = "/style"; };
asString = true;
})
(it "makes a list" {
expected = (html.tag "ul" {
__ = "";
class = ["list"];
} [
(html.tag "li" {} "foo")
(html.tag "li" {} "bar")
(html.tag "li" {} "baz")
]);
actual = (list {} ["foo" "bar" "baz"]);
asString = true;
})
(it "makes an html doc" {
expected = (html.tag "html" {
__child = "";
class = [];
lang = "en";
} [
(html.tag "head" {} ["foo"])
(html.tag "body" {} "bar")
]);
actual = (doc {} [["foo"] "bar"]);
asString = true;
})
]
in with elems; [
(it "makes a p tag" {
expected = html.tag "p" { } "foobar";
actual = p { } "foobar";
asString = true;
})
(it "makes a div tag" {
expected = html.tag "div" { } "foobar";
actual = div { } "foobar";
asString = true;
})
(it "makes a section tag" {
expected = html.tag "section" { } "foobar";
actual = section { } "foobar";
asString = true;
})
(it "makes a span tag" {
expected = html.tag "span" { } "foobar";
actual = span { } "foobar";
asString = true;
})
(it "makes a main tag" {
expected = html.tag "main" { } [ "yeet" ];
actual = main { } [ "yeet" ];
asString = true;
})
(it "makes an h1 tag" {
expected = html.tag "h1" { } "foobar";
actual = H 1 "foobar";
asString = true;
})
(it "makes an h2 tag" {
expected = html.tag "h2" { } "foobar";
actual = H 2 "foobar";
asString = true;
})
(it "makes a title tag" {
expected = html.tag "title" { } "foobar";
actual = title { } "foobar";
asString = true;
})
(it "makes an a tag" {
expected = html.tag "a" {
class = [ "a" ];
href = "https://example.com";
} "example";
actual = a "https://example.com" "example";
asString = true;
})
(it "makes a stylesheet link" {
expected = html.tag "link" {
href = "/style";
rel = "stylesheet";
} "";
actual = Stylesheet { href = "/style"; };
asString = true;
})
(it "makes a list" {
expected = html.tag "ul" {
__ = "";
class = [ "List" ];
} [
(html.tag "li" { } "foo")
(html.tag "li" { } "bar")
(html.tag "li" { } "baz")
];
actual = List { } [ "foo" "bar" "baz" ];
asString = true;
})
(it "makes an html doc" {
expected = html.tag "html" {
__child = "";
class = [ ];
lang = "en";
} [ (html.tag "head" { } [ "foo" ]) (html.tag "body" { } "bar") ];
actual = Doc { } [ [ "foo" ] "bar" ];
asString = true;
})
]

View file

@ -1,32 +1,30 @@
let
html = import ../nixite/html.nix;
it = import ./it.nix;
in
with html; [
(it "makes a p tag" {
actual = tag "p" {} "Hello";
expected = {
tag = "p";
attrs = {};
child = "Hello";
__toString = toHTML;
};
})
in with html; [
(it "makes a p tag" {
actual = tag "p" { } "Hello";
expected = {
tag = "p";
attrs = { };
child = "Hello";
__toString = toHTML;
};
})
(it "concatinates classes" {
actual = toString (tag "p" {class = ["class1" "class2"];} "Hello");
expected = ''<p class="class1 class2">Hello</p>'';
})
(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"])];
in {
actual = addToHead page ["bar"];
expected = {
tag = "html";
attrs = {};
child = [(tag "head" {} ["foo" "bar"])];
__toString = toHTML;
};
}))
]
(it "applies style" (let page = tag "html" { } [ (tag "head" { } [ "foo" ]) ];
in {
actual = addToHead page [ "bar" ];
expected = {
tag = "html";
attrs = { };
child = [ (tag "head" { } [ "foo" "bar" ]) ];
__toString = toHTML;
};
}))
]

View file

@ -3,5 +3,4 @@ path:
echo
echo 'TEST: ${builtins.baseNameOf path}'
echo
''
+ builtins.concatStringsSep "\n" (import path)
'' + builtins.concatStringsSep "\n" (import path)

View file

@ -1,16 +1,14 @@
msg: {
actual,
expected,
asString ? false,
}:
if (
if asString then toString actual == toString expected
else actual == expected )
then ''
echo 'it ${msg}'
''
else ''
echo 'FAILED: ${msg}'
echo '${builtins.toJSON expected}'
echo '${builtins.toJSON actual}'
''
msg:
{ actual, expected, asString ? false, asJSON ? false, }:
if (if asString then
toString actual == toString expected
else if asJSON then
builtins.toJSON actual == builtins.toJSON expected
else
actual == expected) then ''
echo 'it ${msg}'
'' else ''
echo 'FAILED: ${msg}'
echo '${builtins.toJSON expected}'
echo '${builtins.toJSON actual}'
''

View file

@ -2,66 +2,62 @@ let
md = import ../nixite/md.nix;
elems = import ../nixite/elems.nix;
it = import ./it.nix;
in
with md; [
(assert heading "# heading 1" == ["#" "heading 1"]; "echo gets heading 1")
(assert heading "## subheading" == ["##" "subheading"]; "echo gets heading 2")
(assert heading "some paragraph" == null; "echo paragraph is heading 0")
in with md; [
(assert heading "# heading 1" == [ "#" "heading 1" ]; "echo gets heading 1")
(assert heading "## subheading" == [ "##" "subheading" ];
"echo gets heading 2")
(assert heading "some paragraph" == null; "echo paragraph is heading 0")
(assert mdBlock "# heading 1" == elems.h 1 "heading 1"; "echo makes h1 tag")
(assert mdBlock "## subheading" == elems.h 2 "subheading"; "echo makes h2 tag")
(assert mdBlock "some paragraph" == elems.p {} "some paragraph"; "echo makes p tag")
#(assert mdBlock "# heading 1" == elems.h 1 "heading 1"; "echo makes h1 tag")
#(assert mdBlock "## subheading" == elems.h 2 "subheading"; "echo makes h2 tag")
#(assert mdBlock "some paragraph" == elems.p {} "some paragraph"; "echo makes p tag")
(it "processes md block" {
actual = readMd ''
# foo bar
(it "processes md block" {
actual = readMd ''
# foo bar
lorem ipsum
'';
expected = [
(elems.H 1 "foo bar")
""
(elems.p { } ''
lorem ipsum
'';
expected = [
(elems.h 1 "foo bar")
""
(elems.p {} "lorem ipsum\n")
];
})
'')
];
asString = true;
})
(it "can fix file appendixes" {
actual = fixAppendix "index.md";
expected = "index.html";
})
(it "can fix file appendixes" {
actual = fixAppendix "index.md";
expected = "index.html";
})
(it "recursively reads dir" {
actual = recReadMd ./blog;
expected = {
"index.md" = mdToPage ./blog/index.md;
"dir" = {
"index.md" = mdToPage ./blog/dir/index.md;
};
};
})
(it "recursively reads dir" {
actual = recReadMd ./blog;
expected = {
"index.md" = mdToPage ./blog/index.md;
"dir" = { "index.md" = mdToPage ./blog/dir/index.md; };
};
asJSON = true;
})
(it "recursively fixes filename" {
actual = recFixAppendix {
"index.md" = "something";
dir = {
"index.md" = "something else";
};
};
expected = {
"index.html" = "something";
dir = {
"index.html" = "something else";
};
};
})
(it "recursively fixes filename" {
actual = recFixAppendix {
"index.md" = "something";
dir = { "index.md" = "something else"; };
};
expected = {
"index.html" = "something";
dir = { "index.html" = "something else"; };
};
})
(it "recursively translates md to html" {
actual = builtins.toJSON ( readDir ./blog );
expected = builtins.toJSON {
"index.html" = mdToPage ./blog/index.md;
"dir" = {
"index.html" = mdToPage ./blog/dir/index.md;
};
};
})
]
(it "recursively translates md to html" {
actual = builtins.toJSON (readDir ./blog);
expected = builtins.toJSON {
"index.html" = mdToPage ./blog/index.md;
"dir" = { "index.html" = mdToPage ./blog/dir/index.md; };
};
})
]

View file

@ -3,104 +3,89 @@ let
elems = import ../nixite/elems.nix;
site = import ../nixite/site.nix;
it = import ./it.nix;
in
with site; [
(it "applies a style" {
expected = {
"index.html" = html.tag "html" {} [
(html.tag "head" {} [(elems.title {} "foobar") (elems.stylesheet "/style.css")])
(elems.main {} "something")
];
blog = {
"index.html" = html.tag "html" {} [
(html.tag "head" {} [(elems.title {} "foobar") (elems.stylesheet "/style.css")])
(elems.main {} "blogy blog")
];
};
"style.css" = ''
this is a stylesheet
'';
};
actual =
applyStyle ''
this is a stylesheet
'' {
"index.html" = html.tag "html" {} [
(html.tag "head" {} [(elems.title {} "foobar")])
(elems.main {} "something")
];
blog = {
"index.html" = html.tag "html" {} [
(html.tag "head" {} [(elems.title {} "foobar")])
(elems.main {} "blogy blog")
];
};
};
})
(it "extracts top level paths" {
actual = getPaths {
something = "";
src = ./src/index.md;
};
expected = {
"index.md" = ./src/index.md;
};
})
(it "extracts lower level paths" {
actual = getPaths {
something = "yes";
a-list = [
{thingy = ./src/index.md;}
[(html.tag "img" {src = ./src/favicon.png;} "")]
in with site; [
(it "applies a style" {
expected = {
"index.html" = html.tag "html" { } [
(html.tag "head" { } [
(elems.title { } "foobar")
(elems.Stylesheet "/style.css")
])
(elems.main { } "something")
];
blog = {
"index.html" = html.tag "html" { } [
(html.tag "head" { } [
(elems.title { } "foobar")
(elems.Stylesheet "/style.css")
])
(elems.main { } "blogy blog")
];
};
expected = {
"index.md" = ./src/index.md;
"favicon.png" = ./src/favicon.png;
};
})
(it "switches paths" {
actual = switchPaths {
something = "";
a-thing = {
src = ./src/index.md;
};
a-list = [
{thingy = ./src/index.md;}
"style.css" = ''
this is a stylesheet
'';
};
actual = applyStyle ''
this is a stylesheet
'' {
"index.html" = html.tag "html" { } [
(html.tag "head" { } [ (elems.title { } "foobar") ])
(elems.main { } "something")
];
blog = {
"index.html" = html.tag "html" { } [
(html.tag "head" { } [ (elems.title { } "foobar") ])
(elems.main { } "blogy blog")
];
};
expected = {
something = "";
a-thing = {
src = "/static/index.md";
};
a-list = [
{thingy = "/static/index.md";}
];
};
})
};
asJSON = true;
})
(it "extracts top level paths" {
actual = getPaths {
something = "";
src = ./src/index.md;
};
expected = { "index.md" = ./src/index.md; };
})
(it "extracts lower level paths" {
actual = getPaths {
something = "yes";
a-list = [
{ thingy = ./src/index.md; }
[ (html.tag "img" { src = ./src/favicon.png; } "") ]
];
};
expected = {
"index.md" = ./src/index.md;
"favicon.png" = ./src/favicon.png;
};
})
(it "switches paths" {
actual = switchPaths {
something = "";
a-thing = { src = ./src/index.md; };
a-list = [{ thingy = ./src/index.md; }];
};
expected = {
something = "";
a-thing = { src = "/static/index.md"; };
a-list = [{ thingy = "/static/index.md"; }];
};
})
(it "extracts paths" {
actual = extractPaths {
something = "";
a-thing = {
src = ./src/index.md;
};
a-list = [
{thingy = ./src/index.md;}
];
};
expected = {
something = "";
a-thing = {
src = "/static/index.md";
};
a-list = [
{thingy = "/static/index.md";}
];
static = {
"index.md" = ./src/index.md;
};
};
})
]
(it "extracts paths" {
actual = extractPaths {
something = "";
a-thing = { src = ./src/index.md; };
a-list = [{ thingy = ./src/index.md; }];
};
expected = {
something = "";
a-thing = { src = "/static/index.md"; };
a-list = [{ thingy = "/static/index.md"; }];
static = { "index.md" = ./src/index.md; };
};
})
]

View file

@ -3,78 +3,89 @@ let
html = import ../nixite/html.nix;
it = import ./it.nix;
my =
(style.styled "p" "p" {style = {
some-style = "some value";
};})
(style.styled "div" "div" {class = ["something"]; style = {
this = "that";
};})
(style.styled "s" "div" {
id = "s";
class = ["something"];
style = {
s = "yes";
};})
(style.styled "foobar" "div" {
class = ["foo" "bar"];
style = {
something = "something";
};
} )
(style.style "body" {
foo = "bar";
})
(style.styled "list" "ul" {
p = style.styled "generic" "p" {
foo = "bar";
forgetme = "nothing";
};
my = (style.styled "p" "p" { style = { some-style = "some value"; }; })
(style.styled "classless" "div" { class = [ ]; })
(style.styled "quote" p.generic {
baz = "baz";
forgetme = "forgotten";
}) (style.styled "div" "div" {
class = [ "something" ];
style = { this = "that"; };
}) (style.styled "s" "div" {
id = "s";
class = [ "something" ];
style = { s = "yes"; };
}) (style.styled "foobar" "div" {
class = [ "foo" "bar" ];
style = { something = "something"; };
}) (style.style "body" { foo = "bar"; }) (style.styled "list" "ul" {
__child = child:
assert builtins.isList child; (map (html.tag "li" {}) child);
assert builtins.isList child;
(map (html.tag "li" { }) child);
});
in [
(it "extends existing components" {
expected = html.tag "p" {
forgetme = "forgotten";
baz = "baz";
foo = "bar";
class = [ "generic" "quote" ];
} "yes";
actual = my.quote { } "yes";
asString = true;
})
(it "makes a p component" {
expected = html.tag "p" {class = ["p"];} "yes";
actual = my.p {} "yes";
expected = html.tag "p" { class = [ "p" ]; } "yes";
actual = my.p { } "yes";
asString = true;
})
(it "makes a component with no class" {
expected = html.tag "div" { class = [ ]; } "yes";
actual = my.classless { } "yes";
asString = true;
})
(it "does not error without attrs" {
expected = html.tag "p" {class = ["p"];} "yes";
expected = html.tag "p" { class = [ "p" ]; } "yes";
actual = my.p "yes";
asString = true;
})
(it "makes a component" {
expected = html.tag "div" {class = ["something"];} "foobar";
actual = my.div {} "foobar";
expected = html.tag "div" { class = [ "div" "something" ]; } "foobar";
actual = my.div { } "foobar";
asString = true;
})
(it "makes special components" {
expected = html.tag "div" {
id = "s";
class = ["something"];
class = [ "s" "something" ];
} "foobar";
actual = my.s {} "foobar";
actual = my.s { } "foobar";
asString = true;
})
(it "works on many classes" {
expected = html.tag "div" {class = ["foo" "bar"];} "foobar";
actual = my.foobar {} "foobar";
expected = html.tag "div" { class = [ "foobar" "foo" "bar" ]; } "foobar";
actual = my.foobar { } "foobar";
asString = true;
})
(it "does custom behavour" {
expected = (html.tag "ul" {
__ = "";
class = ["list"];
} [
(html.tag "li" {} "1")
(html.tag "li" {} "2")
]);
actual = (my.list {} ["1" "2"]);
expected = html.tag "ul" {
__ = "";
class = [ "list" ];
} [ (html.tag "li" { } "1") (html.tag "li" { } "2") ];
actual = my.list { } [ "1" "2" ];
asString = true;
})
(it "combines attrs" {
expected = html.tag "div" {
id = "foo";
class = ["something"];
class = [ "div" "something" ];
} "foobar";
actual = my.div {id = "foo";} "foobar";
actual = my.div { id = "foo"; } "foobar";
asString = true;
})
(it "makes a style" {