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,46 +1,37 @@
{
description = "A site in nix?";
outputs = {
self,
nixpkgs,
}: let
outputs = { self, nixpkgs, }:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
};
nixite = import ./nixite/. {inherit pkgs;};
in
nixite
// {
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 [
"index.html" = with nixite.elems;
(Doc [
[
(title "Nixite")
(nixite.html.tag "link" {rel = "shortcut icon"; type = "image/png"; href = ./testing/src/favicon.png;} "")
(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"
])
(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 = 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}

View file

@ -1,6 +1,7 @@
{pkgs, ...}: {
{ 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,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" {
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" {
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))
(html.tag "head" { } (builtins.elemAt child 0))
(html.tag "body" { } (builtins.elemAt child 1))
];
lang = "en";
class = [];
})
(s.styled "link" "a" {
class = [ ];
}) (s.styled "a" "a" {
__self = self: attrs: child:
if builtins.isString attrs then
self {href = attrs;} child else
self { href = attrs; } child
else
self attrs child;
})
(s.styled "stylesheet" "link" {
}) (s.styled "Stylesheet" "link" {
rel = "stylesheet";
class = [];
class = [ ];
__self = self: attrs:
if builtins.isString attrs then
self {href = attrs;} "" else
self { href = attrs; } ""
else
self attrs "";
})
// {
h = v: child:
html.tag "h${toString v}" {} child;
}
}) // {
H = v: child: html.tag "h${toString v}" { } child;
}

View file

@ -1,27 +1,30 @@
let
keyvalue = key: value:
assert builtins.isString key;
if value == "" || value == [] || value == {} then "" else
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,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 = ''
@ -13,4 +13,4 @@ in
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: {
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"];
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
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);
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 [
{
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 []
);
}] 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 ''
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 ''
'' 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 throw "Site page must be string, path or attrset, but got ${builtins.typeOf content}: [${toString content}]"
)
site
)
);
'' 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
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 = 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
}";
__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
{
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,51 +2,53 @@ let
elems = import ../nixite/elems.nix;
html = import ../nixite/html.nix;
it = import ./it.nix;
in
with elems; [
in with elems; [
(it "makes a p tag" {
expected = html.tag "p" {class = ["p"];} "foobar";
actual = p {} "foobar";
expected = html.tag "p" { } "foobar";
actual = p { } "foobar";
asString = true;
})
(it "makes a div tag" {
expected = html.tag "div" {class = ["div"];} "foobar";
actual = div {} "foobar";
expected = html.tag "div" { } "foobar";
actual = div { } "foobar";
asString = true;
})
(it "makes a section tag" {
expected = html.tag "section" {class = ["section"];} "foobar";
actual = section {} "foobar";
expected = html.tag "section" { } "foobar";
actual = section { } "foobar";
asString = true;
})
(it "makes a span tag" {
expected = html.tag "span" {class = ["span"];} "foobar";
actual = span {} "foobar";
expected = html.tag "span" { } "foobar";
actual = span { } "foobar";
asString = true;
})
(it "makes a main tag" {
expected = html.tag "main" {class = ["main"];} ["yeet"];
actual = main {} ["yeet"];
expected = html.tag "main" { } [ "yeet" ];
actual = main { } [ "yeet" ];
asString = true;
})
(it "makes an h1 tag" {
expected = html.tag "h1" {} "foobar";
actual = h 1 "foobar";
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";
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";
expected = html.tag "title" { } "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";
expected = html.tag "a" {
class = [ "a" ];
href = "https://example.com";
} "example";
actual = a "https://example.com" "example";
asString = true;
})
(it "makes a stylesheet link" {
@ -54,31 +56,28 @@ in
href = "/style";
rel = "stylesheet";
} "";
actual = stylesheet {href = "/style"; };
actual = Stylesheet { href = "/style"; };
asString = true;
})
(it "makes a list" {
expected = (html.tag "ul" {
expected = html.tag "ul" {
__ = "";
class = ["list"];
class = [ "List" ];
} [
(html.tag "li" {} "foo")
(html.tag "li" {} "bar")
(html.tag "li" {} "baz")
]);
actual = (list {} ["foo" "bar" "baz"]);
(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" {
expected = html.tag "html" {
__child = "";
class = [];
class = [ ];
lang = "en";
} [
(html.tag "head" {} ["foo"])
(html.tag "body" {} "bar")
]);
actual = (doc {} [["foo"] "bar"]);
} [ (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; [
in with html; [
(it "makes a p tag" {
actual = tag "p" {} "Hello";
actual = tag "p" { } "Hello";
expected = {
tag = "p";
attrs = {};
attrs = { };
child = "Hello";
__toString = toHTML;
};
})
(it "concatinates classes" {
actual = toString (tag "p" {class = ["class1" "class2"];} "Hello");
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"];
actual = addToHead page [ "bar" ];
expected = {
tag = "html";
attrs = {};
child = [(tag "head" {} ["foo" "bar"])];
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 ''
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 ''
'' else ''
echo 'FAILED: ${msg}'
echo '${builtins.toJSON expected}'
echo '${builtins.toJSON actual}'
''
''

View file

@ -2,15 +2,15 @@ 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")
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 ''
@ -19,10 +19,13 @@ in
lorem ipsum
'';
expected = [
(elems.h 1 "foo bar")
(elems.H 1 "foo bar")
""
(elems.p {} "lorem ipsum\n")
(elems.p { } ''
lorem ipsum
'')
];
asString = true;
})
(it "can fix file appendixes" {
@ -34,34 +37,27 @@ in
actual = recReadMd ./blog;
expected = {
"index.md" = mdToPage ./blog/index.md;
"dir" = {
"index.md" = mdToPage ./blog/dir/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";
};
dir = { "index.md" = "something else"; };
};
expected = {
"index.html" = "something";
dir = {
"index.html" = "something else";
};
dir = { "index.html" = "something else"; };
};
})
(it "recursively translates md to html" {
actual = builtins.toJSON ( readDir ./blog );
actual = builtins.toJSON (readDir ./blog);
expected = builtins.toJSON {
"index.html" = mdToPage ./blog/index.md;
"dir" = {
"index.html" = mdToPage ./blog/dir/index.md;
};
"dir" = { "index.html" = mdToPage ./blog/dir/index.md; };
};
})
]
]

View file

@ -3,55 +3,58 @@ let
elems = import ../nixite/elems.nix;
site = import ../nixite/site.nix;
it = import ./it.nix;
in
with site; [
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")
"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")
"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 ''
actual = applyStyle ''
this is a stylesheet
'' {
"index.html" = html.tag "html" {} [
(html.tag "head" {} [(elems.title {} "foobar")])
(elems.main {} "something")
"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")
"index.html" = html.tag "html" { } [
(html.tag "head" { } [ (elems.title { } "foobar") ])
(elems.main { } "blogy blog")
];
};
};
asJSON = true;
})
(it "extracts top level paths" {
actual = getPaths {
something = "";
src = ./src/index.md;
};
expected = {
"index.md" = ./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;} "")]
{ thingy = ./src/index.md; }
[ (html.tag "img" { src = ./src/favicon.png; } "") ]
];
};
expected = {
@ -62,45 +65,27 @@ in
(it "switches paths" {
actual = switchPaths {
something = "";
a-thing = {
src = ./src/index.md;
};
a-list = [
{thingy = ./src/index.md;}
];
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";}
];
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;}
];
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;
};
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" {
p = style.styled "generic" "p" {
foo = "bar";
})
(style.styled "list" "ul" {
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" {
expected = html.tag "ul" {
__ = "";
class = ["list"];
} [
(html.tag "li" {} "1")
(html.tag "li" {} "2")
]);
actual = (my.list {} ["1" "2"]);
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" {