component extending, add all html elems
also use nixfmt
This commit is contained in:
parent
ccc6b53b91
commit
cb6d9652f8
43
flake.nix
43
flake.nix
|
@ -1,46 +1,37 @@
|
||||||
{
|
{
|
||||||
description = "A site in nix?";
|
description = "A site in nix?";
|
||||||
|
|
||||||
outputs = {
|
outputs = { self, nixpkgs, }:
|
||||||
self,
|
let
|
||||||
nixpkgs,
|
|
||||||
}: let
|
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs { inherit system; };
|
||||||
inherit system;
|
|
||||||
};
|
|
||||||
nixite = import ./nixite/. { inherit pkgs; };
|
nixite = import ./nixite/. { inherit pkgs; };
|
||||||
in
|
in nixite // {
|
||||||
nixite
|
|
||||||
// {
|
|
||||||
packages.${system} = {
|
packages.${system} = {
|
||||||
default = nixite.mkSite (
|
default = nixite.mkSite (nixite.site.applyStyle ./testing/src/style.css
|
||||||
nixite.site.applyStyle ./testing/src/style.css
|
|
||||||
(nixite.site.extractPaths {
|
(nixite.site.extractPaths {
|
||||||
"index.html" = with nixite.elems; (doc [
|
"index.html" = with nixite.elems;
|
||||||
|
(Doc [
|
||||||
[
|
[
|
||||||
(title "Nixite")
|
(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 [
|
(main [
|
||||||
(link "/blog" "blog")
|
(a "/blog" "blog")
|
||||||
(list [
|
(list [ "item 1" "item 2" "item 3" ])
|
||||||
"item 1"
|
|
||||||
"item 2"
|
|
||||||
"item 3"
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
blog = nixite.md.readDir ./testing/blog;
|
blog = nixite.md.readDir ./testing/blog;
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
|
|
||||||
serve = nixite.serve self.packages.${system}.default;
|
serve = nixite.serve self.packages.${system}.default;
|
||||||
|
|
||||||
test = let
|
test = let test = import ./testing/import.nix;
|
||||||
test = import ./testing/import.nix;
|
in pkgs.writeShellScriptBin "test" ''
|
||||||
in
|
|
||||||
pkgs.writeShellScriptBin "test" ''
|
|
||||||
${test ./testing/md.test.nix}
|
${test ./testing/md.test.nix}
|
||||||
${test ./testing/html.test.nix}
|
${test ./testing/html.test.nix}
|
||||||
${test ./testing/elems.test.nix}
|
${test ./testing/elems.test.nix}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{ pkgs, ... }: {
|
{ pkgs, ... }: {
|
||||||
mkSite = import ./make-site.nix 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}
|
${pkgs.caddy}/bin/caddy file-server --root ${site}
|
||||||
'');
|
'');
|
||||||
md = import ./md.nix;
|
md = import ./md.nix;
|
||||||
|
|
|
@ -1,22 +1,37 @@
|
||||||
let
|
let
|
||||||
html = import ./html.nix;
|
html = import ./html.nix;
|
||||||
s = import ./style.nix;
|
s = import ./style.nix;
|
||||||
in
|
base = tag: (s.styled tag tag { class = [ ]; });
|
||||||
(s.styled "p" "p" {})
|
in (base "html") (base "head") (base "title") (base "base") (base "link")
|
||||||
(s.styled "div" "div" {})
|
(base "meta")
|
||||||
(s.styled "section" "section" {})
|
# (base "style" ) # borks styled coponents
|
||||||
(s.styled "span" "span" {})
|
(base "body") (base "article") (base "section") (base "nav") (base "aside")
|
||||||
(s.styled "main" "main" {})
|
(base "h1") (base "h2") (base "h3") (base "h4") (base "h5") (base "h6")
|
||||||
(s.styled "article" "article" {})
|
(base "hgroup") (base "header") (base "footer") (base "address") (base "p")
|
||||||
(s.styled "title" "title" {class = [];})
|
(base "hr") (base "pre") (base "blockquote") (base "ol") (base "ul")
|
||||||
(s.styled "h1" "h1" {})
|
(base "menu") (base "li") (base "dl") (base "dt") (base "dd") (base "figure")
|
||||||
(s.styled "h2" "h2" {})
|
(base "figcaption") (base "main") (base "div") (base "a") (base "em")
|
||||||
(s.styled "h3" "h3" {})
|
(base "strong") (base "small") (base "s") (base "cite") (base "q") (base "dfn")
|
||||||
(s.styled "list" "ul" {
|
(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:
|
__child = child:
|
||||||
assert builtins.isList child; (map (html.tag "li" {}) child);
|
assert builtins.isList child;
|
||||||
})
|
(map (html.tag "li" { }) child);
|
||||||
(s.styled "doc" "html" {
|
}) (s.styled "Doc" "html" {
|
||||||
__child = child:
|
__child = child:
|
||||||
assert builtins.isList child;
|
assert builtins.isList child;
|
||||||
assert builtins.length child == 2;
|
assert builtins.length child == 2;
|
||||||
|
@ -26,22 +41,20 @@ in
|
||||||
];
|
];
|
||||||
lang = "en";
|
lang = "en";
|
||||||
class = [ ];
|
class = [ ];
|
||||||
})
|
}) (s.styled "a" "a" {
|
||||||
(s.styled "link" "a" {
|
|
||||||
__self = self: attrs: child:
|
__self = self: attrs: child:
|
||||||
if builtins.isString attrs then
|
if builtins.isString attrs then
|
||||||
self {href = attrs;} child else
|
self { href = attrs; } child
|
||||||
|
else
|
||||||
self attrs child;
|
self attrs child;
|
||||||
})
|
}) (s.styled "Stylesheet" "link" {
|
||||||
(s.styled "stylesheet" "link" {
|
|
||||||
rel = "stylesheet";
|
rel = "stylesheet";
|
||||||
class = [ ];
|
class = [ ];
|
||||||
__self = self: attrs:
|
__self = self: attrs:
|
||||||
if builtins.isString attrs then
|
if builtins.isString attrs then
|
||||||
self {href = attrs;} "" else
|
self { href = attrs; } ""
|
||||||
|
else
|
||||||
self attrs "";
|
self attrs "";
|
||||||
})
|
}) // {
|
||||||
// {
|
H = v: child: html.tag "h${toString v}" { } child;
|
||||||
h = v: child:
|
|
||||||
html.tag "h${toString v}" {} child;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,30 @@
|
||||||
let
|
let
|
||||||
keyvalue = key: value:
|
keyvalue = key: value:
|
||||||
assert builtins.isString key;
|
assert builtins.isString key;
|
||||||
if value == "" || value == [] || value == {} then "" else
|
if value == "" || value == [ ] || value == { } then
|
||||||
|
""
|
||||||
|
else
|
||||||
''${key}="${toString value}"'';
|
''${key}="${toString value}"'';
|
||||||
in rec {
|
in rec {
|
||||||
toHTML = elem:
|
toHTML = elem:
|
||||||
if builtins.typeOf elem == "string"
|
if builtins.typeOf elem == "string" then
|
||||||
then elem
|
elem
|
||||||
else if builtins.typeOf elem == "list"
|
else if builtins.typeOf elem == "list" then
|
||||||
then builtins.toString (map toHTML elem)
|
builtins.toString (map toHTML elem)
|
||||||
else ''<${elem.tag} ${writeAttrs elem.attrs}>${toHTML elem.child}</${elem.tag}>'';
|
else
|
||||||
|
"<${elem.tag} ${writeAttrs elem.attrs}>${
|
||||||
|
toHTML elem.child
|
||||||
|
}</${elem.tag}>";
|
||||||
|
|
||||||
writeAttrs = attrs:
|
writeAttrs = attrs:
|
||||||
toString (builtins.filter (value: value != "") (builtins.attrValues (
|
toString (builtins.filter (value: value != "") (builtins.attrValues
|
||||||
builtins.mapAttrs (key: value:
|
(builtins.mapAttrs (key: value:
|
||||||
if (builtins.isPath value)
|
if (builtins.isPath value) then
|
||||||
then keyvalue key (baseNameOf value)
|
keyvalue key (baseNameOf value)
|
||||||
|
else if (builtins.substring 0 2 key) == "__" then
|
||||||
|
""
|
||||||
else
|
else
|
||||||
if (builtins.substring 0 2 key) == "__"
|
keyvalue key value) attrs)));
|
||||||
then ""
|
|
||||||
else keyvalue key value)
|
|
||||||
attrs
|
|
||||||
)));
|
|
||||||
|
|
||||||
tag = tag: attrs: child: {
|
tag = tag: attrs: child: {
|
||||||
inherit tag attrs child;
|
inherit tag attrs child;
|
||||||
|
@ -29,20 +32,9 @@ in rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
addToHead = page: heads:
|
addToHead = page: heads:
|
||||||
page
|
page // {
|
||||||
// {
|
child = map
|
||||||
child =
|
(e: if e.tag == "head" then e // { child = e.child ++ heads; } else e)
|
||||||
map
|
|
||||||
(
|
|
||||||
e:
|
|
||||||
if e.tag == "head"
|
|
||||||
then
|
|
||||||
e
|
|
||||||
// {
|
|
||||||
child = e.child ++ heads;
|
|
||||||
}
|
|
||||||
else e
|
|
||||||
)
|
|
||||||
page.child;
|
page.child;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{stdenv, ...}: raw: let
|
{ stdenv, ... }:
|
||||||
site = import ./site.nix;
|
raw:
|
||||||
in
|
let site = import ./site.nix;
|
||||||
stdenv.mkDerivation {
|
in stdenv.mkDerivation {
|
||||||
name = "site";
|
name = "site";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
|
|
|
@ -1,60 +1,42 @@
|
||||||
let
|
let elems = import ./elems.nix;
|
||||||
elems = import ./elems.nix;
|
|
||||||
in rec {
|
in rec {
|
||||||
readMd = md:
|
readMd = md:
|
||||||
if builtins.isPath md
|
if builtins.isPath md then
|
||||||
then processMd (builtins.readFile md)
|
processMd (builtins.readFile md)
|
||||||
else processMd md;
|
else
|
||||||
|
processMd md;
|
||||||
|
|
||||||
processMd = md: (map (c:
|
processMd = md:
|
||||||
if builtins.isString c
|
(map (c: if builtins.isString c then mdBlock c else "")
|
||||||
then mdBlock c
|
(builtins.split "\n\n" md));
|
||||||
else "") (builtins.split "\n\n" md));
|
|
||||||
|
|
||||||
recReadMd = root:
|
recReadMd = root:
|
||||||
assert builtins.isPath root;
|
assert builtins.isPath root;
|
||||||
builtins.mapAttrs
|
builtins.mapAttrs (path: type:
|
||||||
(path: type:
|
if type == "directory" then
|
||||||
if type == "directory"
|
recReadMd (root + (/. + path))
|
||||||
then recReadMd (root + (/. + path))
|
else if type == "regular" then
|
||||||
else if type == "regular"
|
mdToPage (root + (/. + path))
|
||||||
then mdToPage (root + (/. + path))
|
else
|
||||||
else throw "Cannot read ${path}, file type ${type}")
|
throw "Cannot read ${path}, file type ${type}") (builtins.readDir root);
|
||||||
(builtins.readDir root);
|
|
||||||
|
|
||||||
recFixAppendix = site:
|
recFixAppendix = site:
|
||||||
builtins.listToAttrs (
|
builtins.listToAttrs (builtins.attrValues (builtins.mapAttrs (name: value: {
|
||||||
builtins.attrValues (
|
|
||||||
builtins.mapAttrs (name: value: {
|
|
||||||
name = fixAppendix name;
|
name = fixAppendix name;
|
||||||
value =
|
value = if builtins.isAttrs value then recFixAppendix value else value;
|
||||||
if builtins.isAttrs value
|
}) site));
|
||||||
then recFixAppendix value
|
|
||||||
else value;
|
|
||||||
})
|
|
||||||
site
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
fixAppendix = builtins.replaceStrings [ ".md" ] [ ".html" ];
|
fixAppendix = builtins.replaceStrings [ ".md" ] [ ".html" ];
|
||||||
|
|
||||||
readDir = root: recFixAppendix (recReadMd root);
|
readDir = root: recFixAppendix (recReadMd root);
|
||||||
|
|
||||||
mdToPage = md: elems.doc [
|
mdToPage = md: elems.Doc [ [ (elems.title "markdown file") ] (readMd md) ];
|
||||||
[(elems.title "markdown file")]
|
|
||||||
(readMd md)
|
|
||||||
];
|
|
||||||
|
|
||||||
mdBlock = block: let
|
mdBlock = block:
|
||||||
|
let
|
||||||
m = heading block;
|
m = heading block;
|
||||||
h =
|
h = if m == null then 0 else builtins.stringLength (builtins.elemAt m 0);
|
||||||
if m == null
|
in if m == null then elems.p { } block else elems.H h (builtins.elemAt m 1);
|
||||||
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;
|
heading = block: builtins.match "(#+) (.*)" block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,74 +4,55 @@ let
|
||||||
in rec {
|
in rec {
|
||||||
applyStyle = style: site: (linkStyle site) // { "style.css" = style; };
|
applyStyle = style: site: (linkStyle site) // { "style.css" = style; };
|
||||||
|
|
||||||
linkStyle = site: (builtins.mapAttrs (
|
linkStyle = site:
|
||||||
name: content:
|
(builtins.mapAttrs (name: content:
|
||||||
if builtins.isAttrs content && content ? "__toString"
|
if builtins.isAttrs content && content ? "__toString" then
|
||||||
then html.addToHead content [(elems.stylesheet "/style.css")]
|
html.addToHead content [ (elems.Stylesheet "/style.css") ]
|
||||||
else if builtins.isAttrs content
|
else if builtins.isAttrs content then
|
||||||
then linkStyle content
|
linkStyle content
|
||||||
else content
|
else
|
||||||
)
|
content) site);
|
||||||
site);
|
|
||||||
|
|
||||||
extractPaths = content:
|
extractPaths = content: switchPaths content // { static = getPaths content; };
|
||||||
switchPaths content // {static = getPaths content;};
|
|
||||||
|
|
||||||
switchPaths = content: (
|
switchPaths = content:
|
||||||
if builtins.isAttrs content
|
(if builtins.isAttrs content then
|
||||||
then
|
|
||||||
builtins.mapAttrs (key: value:
|
builtins.mapAttrs (key: value:
|
||||||
if builtins.isPath value
|
if builtins.isPath value then
|
||||||
then ("/static/" + baseNameOf value)
|
("/static/" + baseNameOf value)
|
||||||
else switchPaths value)
|
else
|
||||||
content
|
switchPaths value) content
|
||||||
else if builtins.isList content
|
else if builtins.isList content then
|
||||||
then (map switchPaths content)
|
(map switchPaths content)
|
||||||
else content
|
else
|
||||||
);
|
content);
|
||||||
|
|
||||||
getPaths = content: (builtins.listToAttrs (getPathsKV content));
|
getPaths = content: (builtins.listToAttrs (getPathsKV content));
|
||||||
|
|
||||||
getPathsKV = path: (
|
getPathsKV = path:
|
||||||
if builtins.isPath path
|
(if builtins.isPath path then [{
|
||||||
then [
|
|
||||||
{
|
|
||||||
name = baseNameOf path;
|
name = baseNameOf path;
|
||||||
value = path;
|
value = path;
|
||||||
}
|
}] else if builtins.isAttrs path then
|
||||||
]
|
builtins.concatLists (map getPathsKV (builtins.attrValues path))
|
||||||
else if builtins.isAttrs path
|
else if builtins.isList path then
|
||||||
then builtins.concatLists (map getPathsKV (builtins.attrValues path))
|
builtins.concatLists (map getPathsKV path)
|
||||||
else if builtins.isList path
|
else
|
||||||
then builtins.concatLists (map getPathsKV path)
|
[ ]);
|
||||||
else []
|
|
||||||
);
|
|
||||||
|
|
||||||
copyTo = prefix: site:
|
copyTo = prefix: site:
|
||||||
builtins.toString (
|
builtins.toString (builtins.attrValues (builtins.mapAttrs (name: content:
|
||||||
builtins.attrValues (
|
if builtins.isString content then ''
|
||||||
builtins.mapAttrs (
|
|
||||||
name: content:
|
|
||||||
if builtins.isString content
|
|
||||||
then ''
|
|
||||||
cp ${builtins.toFile name content} ${prefix}/${name}
|
cp ${builtins.toFile name content} ${prefix}/${name}
|
||||||
''
|
'' else if builtins.isPath content then ''
|
||||||
else if builtins.isPath content
|
|
||||||
then ''
|
|
||||||
cp -r ${content} ${prefix}/${name}
|
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}
|
cp ${builtins.toFile name (toString content)} ${prefix}/${name}
|
||||||
''
|
'' else if builtins.isAttrs content then ''
|
||||||
else if builtins.isAttrs content
|
|
||||||
then ''
|
|
||||||
mkdir -p ${prefix}/${name}
|
mkdir -p ${prefix}/${name}
|
||||||
${copyTo "${prefix}/${name}" content}
|
${copyTo "${prefix}/${name}" content}
|
||||||
''
|
'' else
|
||||||
else throw "Site page must be string, path or attrset, but got ${builtins.typeOf content}: [${toString content}]"
|
throw "Site page must be string, path or attrset, but got ${
|
||||||
)
|
builtins.typeOf content
|
||||||
site
|
}: [${toString content}]") site));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,65 +2,63 @@ let
|
||||||
html = import ./html.nix;
|
html = import ./html.nix;
|
||||||
|
|
||||||
join = {
|
join = {
|
||||||
__functor = self: new:
|
__functor = self: new: self // new // { style = self.style + new.style; };
|
||||||
self
|
|
||||||
// new
|
|
||||||
// {style = self.style + new.style;};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mkStyle = identifier: styles:
|
mkStyle = identifier: styles:
|
||||||
if styles == {}
|
if styles == { } then
|
||||||
then ""
|
""
|
||||||
else ''
|
else ''
|
||||||
${identifier} {
|
${identifier} {
|
||||||
${toString (builtins.attrValues (
|
${
|
||||||
builtins.mapAttrs (
|
toString (builtins.attrValues
|
||||||
key: value: ''${key}: ${value};''
|
(builtins.mapAttrs (key: value: "${key}: ${value};") styles))
|
||||||
)
|
}
|
||||||
styles
|
|
||||||
))}
|
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
mkIdentifier = name: tag: {
|
mkIdentifier = name: tag:
|
||||||
class ? [name],
|
{ class ? [ name ], id ? "", ... }:
|
||||||
id ? "",
|
"${tag}" + builtins.concatStringsSep "" (map (c: "." + c) class)
|
||||||
...
|
+ (if id != "" then "#" else "") + id;
|
||||||
}:
|
|
||||||
"${tag}"
|
|
||||||
+ builtins.concatStringsSep "" (map (c: "." + c) class)
|
|
||||||
+ (
|
|
||||||
if id != ""
|
|
||||||
then "#"
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
+ id;
|
|
||||||
in {
|
in {
|
||||||
styled = name: tag: cprops: let
|
styled = name: tag: cprops:
|
||||||
|
assert builtins.isString name;
|
||||||
|
let
|
||||||
__child = cprops.__child or (child: child);
|
__child = cprops.__child or (child: child);
|
||||||
|
|
||||||
self = props:
|
joinProps = (cprops // {
|
||||||
html.tag tag (props // {class = [name];} // cprops // {style = "";});
|
__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:
|
__self = (cprops.__self or (self: props:
|
||||||
if builtins.isAttrs props
|
if builtins.isAttrs props then
|
||||||
then (child: ( self props (__child child) ))
|
(child: (self props (__child child)))
|
||||||
else if builtins.isString props || builtins.isList props
|
else if builtins.isString props || builtins.isList props then
|
||||||
then (self {} (__child props))
|
(self { } (__child props))
|
||||||
else throw "Call element with attributes and child."
|
else
|
||||||
)) self;
|
throw "Call element with attributes and child.")) self;
|
||||||
|
in {
|
||||||
in
|
|
||||||
{
|
|
||||||
${name} = __self;
|
${name} = __self;
|
||||||
|
|
||||||
style = mkStyle (mkIdentifier name tag cprops) (cprops.style or { });
|
style = mkStyle (mkIdentifier name tag cprops) (cprops.style or { });
|
||||||
}
|
} // join;
|
||||||
// join;
|
|
||||||
|
|
||||||
style = identifier: styles:
|
style = identifier: styles: { style = mkStyle identifier styles; } // join;
|
||||||
{
|
|
||||||
style = mkStyle identifier styles;
|
|
||||||
}
|
|
||||||
// join;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,51 +2,53 @@ let
|
||||||
elems = import ../nixite/elems.nix;
|
elems = import ../nixite/elems.nix;
|
||||||
html = import ../nixite/html.nix;
|
html = import ../nixite/html.nix;
|
||||||
it = import ./it.nix;
|
it = import ./it.nix;
|
||||||
in
|
in with elems; [
|
||||||
with elems; [
|
|
||||||
(it "makes a p tag" {
|
(it "makes a p tag" {
|
||||||
expected = html.tag "p" {class = ["p"];} "foobar";
|
expected = html.tag "p" { } "foobar";
|
||||||
actual = p { } "foobar";
|
actual = p { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a div tag" {
|
(it "makes a div tag" {
|
||||||
expected = html.tag "div" {class = ["div"];} "foobar";
|
expected = html.tag "div" { } "foobar";
|
||||||
actual = div { } "foobar";
|
actual = div { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a section tag" {
|
(it "makes a section tag" {
|
||||||
expected = html.tag "section" {class = ["section"];} "foobar";
|
expected = html.tag "section" { } "foobar";
|
||||||
actual = section { } "foobar";
|
actual = section { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a span tag" {
|
(it "makes a span tag" {
|
||||||
expected = html.tag "span" {class = ["span"];} "foobar";
|
expected = html.tag "span" { } "foobar";
|
||||||
actual = span { } "foobar";
|
actual = span { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a main tag" {
|
(it "makes a main tag" {
|
||||||
expected = html.tag "main" {class = ["main"];} ["yeet"];
|
expected = html.tag "main" { } [ "yeet" ];
|
||||||
actual = main { } [ "yeet" ];
|
actual = main { } [ "yeet" ];
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes an h1 tag" {
|
(it "makes an h1 tag" {
|
||||||
expected = html.tag "h1" { } "foobar";
|
expected = html.tag "h1" { } "foobar";
|
||||||
actual = h 1 "foobar";
|
actual = H 1 "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes an h2 tag" {
|
(it "makes an h2 tag" {
|
||||||
expected = html.tag "h2" { } "foobar";
|
expected = html.tag "h2" { } "foobar";
|
||||||
actual = h 2 "foobar";
|
actual = H 2 "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a title tag" {
|
(it "makes a title tag" {
|
||||||
expected = html.tag "title" {class = [];} "foobar";
|
expected = html.tag "title" { } "foobar";
|
||||||
actual = title { } "foobar";
|
actual = title { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes an a tag" {
|
(it "makes an a tag" {
|
||||||
expected = html.tag "a" {class = ["link"]; href = "https://example.com";} "example";
|
expected = html.tag "a" {
|
||||||
actual = link "https://example.com" "example";
|
class = [ "a" ];
|
||||||
|
href = "https://example.com";
|
||||||
|
} "example";
|
||||||
|
actual = a "https://example.com" "example";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a stylesheet link" {
|
(it "makes a stylesheet link" {
|
||||||
|
@ -54,31 +56,28 @@ in
|
||||||
href = "/style";
|
href = "/style";
|
||||||
rel = "stylesheet";
|
rel = "stylesheet";
|
||||||
} "";
|
} "";
|
||||||
actual = stylesheet {href = "/style"; };
|
actual = Stylesheet { href = "/style"; };
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a list" {
|
(it "makes a list" {
|
||||||
expected = (html.tag "ul" {
|
expected = html.tag "ul" {
|
||||||
__ = "";
|
__ = "";
|
||||||
class = ["list"];
|
class = [ "List" ];
|
||||||
} [
|
} [
|
||||||
(html.tag "li" { } "foo")
|
(html.tag "li" { } "foo")
|
||||||
(html.tag "li" { } "bar")
|
(html.tag "li" { } "bar")
|
||||||
(html.tag "li" { } "baz")
|
(html.tag "li" { } "baz")
|
||||||
]);
|
];
|
||||||
actual = (list {} ["foo" "bar" "baz"]);
|
actual = List { } [ "foo" "bar" "baz" ];
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes an html doc" {
|
(it "makes an html doc" {
|
||||||
expected = (html.tag "html" {
|
expected = html.tag "html" {
|
||||||
__child = "";
|
__child = "";
|
||||||
class = [ ];
|
class = [ ];
|
||||||
lang = "en";
|
lang = "en";
|
||||||
} [
|
} [ (html.tag "head" { } [ "foo" ]) (html.tag "body" { } "bar") ];
|
||||||
(html.tag "head" {} ["foo"])
|
actual = Doc { } [ [ "foo" ] "bar" ];
|
||||||
(html.tag "body" {} "bar")
|
|
||||||
]);
|
|
||||||
actual = (doc {} [["foo"] "bar"]);
|
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
let
|
let
|
||||||
html = import ../nixite/html.nix;
|
html = import ../nixite/html.nix;
|
||||||
it = import ./it.nix;
|
it = import ./it.nix;
|
||||||
in
|
in with html; [
|
||||||
with html; [
|
|
||||||
(it "makes a p tag" {
|
(it "makes a p tag" {
|
||||||
actual = tag "p" { } "Hello";
|
actual = tag "p" { } "Hello";
|
||||||
expected = {
|
expected = {
|
||||||
|
@ -18,8 +17,7 @@ in
|
||||||
expected = ''<p class="class1 class2">Hello</p>'';
|
expected = ''<p class="class1 class2">Hello</p>'';
|
||||||
})
|
})
|
||||||
|
|
||||||
(it "applies style" (let
|
(it "applies style" (let page = tag "html" { } [ (tag "head" { } [ "foo" ]) ];
|
||||||
page = tag "html" {} [(tag "head" {} ["foo"])];
|
|
||||||
in {
|
in {
|
||||||
actual = addToHead page [ "bar" ];
|
actual = addToHead page [ "bar" ];
|
||||||
expected = {
|
expected = {
|
||||||
|
|
|
@ -3,5 +3,4 @@ path:
|
||||||
echo
|
echo
|
||||||
echo 'TEST: ${builtins.baseNameOf path}'
|
echo 'TEST: ${builtins.baseNameOf path}'
|
||||||
echo
|
echo
|
||||||
''
|
'' + builtins.concatStringsSep "\n" (import path)
|
||||||
+ builtins.concatStringsSep "\n" (import path)
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
msg: {
|
msg:
|
||||||
actual,
|
{ actual, expected, asString ? false, asJSON ? false, }:
|
||||||
expected,
|
if (if asString then
|
||||||
asString ? false,
|
toString actual == toString expected
|
||||||
}:
|
else if asJSON then
|
||||||
if (
|
builtins.toJSON actual == builtins.toJSON expected
|
||||||
if asString then toString actual == toString expected
|
else
|
||||||
else actual == expected )
|
actual == expected) then ''
|
||||||
then ''
|
|
||||||
echo 'it ${msg}'
|
echo 'it ${msg}'
|
||||||
''
|
'' else ''
|
||||||
else ''
|
|
||||||
echo 'FAILED: ${msg}'
|
echo 'FAILED: ${msg}'
|
||||||
echo '${builtins.toJSON expected}'
|
echo '${builtins.toJSON expected}'
|
||||||
echo '${builtins.toJSON actual}'
|
echo '${builtins.toJSON actual}'
|
||||||
|
|
|
@ -2,15 +2,15 @@ let
|
||||||
md = import ../nixite/md.nix;
|
md = import ../nixite/md.nix;
|
||||||
elems = import ../nixite/elems.nix;
|
elems = import ../nixite/elems.nix;
|
||||||
it = import ./it.nix;
|
it = import ./it.nix;
|
||||||
in
|
in with md; [
|
||||||
with md; [
|
|
||||||
(assert heading "# heading 1" == [ "#" "heading 1" ]; "echo gets heading 1")
|
(assert heading "# heading 1" == [ "#" "heading 1" ]; "echo gets heading 1")
|
||||||
(assert heading "## subheading" == ["##" "subheading"]; "echo gets heading 2")
|
(assert heading "## subheading" == [ "##" "subheading" ];
|
||||||
|
"echo gets heading 2")
|
||||||
(assert heading "some paragraph" == null; "echo paragraph is heading 0")
|
(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 "# heading 1" == elems.h 1 "heading 1"; "echo makes h1 tag")
|
||||||
(assert mdBlock "## subheading" == elems.h 2 "subheading"; "echo makes h2 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 "some paragraph" == elems.p {} "some paragraph"; "echo makes p tag")
|
||||||
|
|
||||||
(it "processes md block" {
|
(it "processes md block" {
|
||||||
actual = readMd ''
|
actual = readMd ''
|
||||||
|
@ -19,10 +19,13 @@ in
|
||||||
lorem ipsum
|
lorem ipsum
|
||||||
'';
|
'';
|
||||||
expected = [
|
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" {
|
(it "can fix file appendixes" {
|
||||||
|
@ -34,24 +37,19 @@ in
|
||||||
actual = recReadMd ./blog;
|
actual = recReadMd ./blog;
|
||||||
expected = {
|
expected = {
|
||||||
"index.md" = mdToPage ./blog/index.md;
|
"index.md" = mdToPage ./blog/index.md;
|
||||||
"dir" = {
|
"dir" = { "index.md" = mdToPage ./blog/dir/index.md; };
|
||||||
"index.md" = mdToPage ./blog/dir/index.md;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
asJSON = true;
|
||||||
})
|
})
|
||||||
|
|
||||||
(it "recursively fixes filename" {
|
(it "recursively fixes filename" {
|
||||||
actual = recFixAppendix {
|
actual = recFixAppendix {
|
||||||
"index.md" = "something";
|
"index.md" = "something";
|
||||||
dir = {
|
dir = { "index.md" = "something else"; };
|
||||||
"index.md" = "something else";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
expected = {
|
expected = {
|
||||||
"index.html" = "something";
|
"index.html" = "something";
|
||||||
dir = {
|
dir = { "index.html" = "something else"; };
|
||||||
"index.html" = "something else";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -59,9 +57,7 @@ in
|
||||||
actual = builtins.toJSON (readDir ./blog);
|
actual = builtins.toJSON (readDir ./blog);
|
||||||
expected = builtins.toJSON {
|
expected = builtins.toJSON {
|
||||||
"index.html" = mdToPage ./blog/index.md;
|
"index.html" = mdToPage ./blog/index.md;
|
||||||
"dir" = {
|
"dir" = { "index.html" = mdToPage ./blog/dir/index.md; };
|
||||||
"index.html" = mdToPage ./blog/dir/index.md;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,17 +3,22 @@ let
|
||||||
elems = import ../nixite/elems.nix;
|
elems = import ../nixite/elems.nix;
|
||||||
site = import ../nixite/site.nix;
|
site = import ../nixite/site.nix;
|
||||||
it = import ./it.nix;
|
it = import ./it.nix;
|
||||||
in
|
in with site; [
|
||||||
with site; [
|
|
||||||
(it "applies a style" {
|
(it "applies a style" {
|
||||||
expected = {
|
expected = {
|
||||||
"index.html" = html.tag "html" { } [
|
"index.html" = html.tag "html" { } [
|
||||||
(html.tag "head" {} [(elems.title {} "foobar") (elems.stylesheet "/style.css")])
|
(html.tag "head" { } [
|
||||||
|
(elems.title { } "foobar")
|
||||||
|
(elems.Stylesheet "/style.css")
|
||||||
|
])
|
||||||
(elems.main { } "something")
|
(elems.main { } "something")
|
||||||
];
|
];
|
||||||
blog = {
|
blog = {
|
||||||
"index.html" = html.tag "html" { } [
|
"index.html" = html.tag "html" { } [
|
||||||
(html.tag "head" {} [(elems.title {} "foobar") (elems.stylesheet "/style.css")])
|
(html.tag "head" { } [
|
||||||
|
(elems.title { } "foobar")
|
||||||
|
(elems.Stylesheet "/style.css")
|
||||||
|
])
|
||||||
(elems.main { } "blogy blog")
|
(elems.main { } "blogy blog")
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -21,8 +26,7 @@ in
|
||||||
this is a stylesheet
|
this is a stylesheet
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
actual =
|
actual = applyStyle ''
|
||||||
applyStyle ''
|
|
||||||
this is a stylesheet
|
this is a stylesheet
|
||||||
'' {
|
'' {
|
||||||
"index.html" = html.tag "html" { } [
|
"index.html" = html.tag "html" { } [
|
||||||
|
@ -36,15 +40,14 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
asJSON = true;
|
||||||
})
|
})
|
||||||
(it "extracts top level paths" {
|
(it "extracts top level paths" {
|
||||||
actual = getPaths {
|
actual = getPaths {
|
||||||
something = "";
|
something = "";
|
||||||
src = ./src/index.md;
|
src = ./src/index.md;
|
||||||
};
|
};
|
||||||
expected = {
|
expected = { "index.md" = ./src/index.md; };
|
||||||
"index.md" = ./src/index.md;
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
(it "extracts lower level paths" {
|
(it "extracts lower level paths" {
|
||||||
actual = getPaths {
|
actual = getPaths {
|
||||||
|
@ -62,45 +65,27 @@ in
|
||||||
(it "switches paths" {
|
(it "switches paths" {
|
||||||
actual = switchPaths {
|
actual = switchPaths {
|
||||||
something = "";
|
something = "";
|
||||||
a-thing = {
|
a-thing = { src = ./src/index.md; };
|
||||||
src = ./src/index.md;
|
a-list = [{ thingy = ./src/index.md; }];
|
||||||
};
|
|
||||||
a-list = [
|
|
||||||
{thingy = ./src/index.md;}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
expected = {
|
expected = {
|
||||||
something = "";
|
something = "";
|
||||||
a-thing = {
|
a-thing = { src = "/static/index.md"; };
|
||||||
src = "/static/index.md";
|
a-list = [{ thingy = "/static/index.md"; }];
|
||||||
};
|
|
||||||
a-list = [
|
|
||||||
{thingy = "/static/index.md";}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
(it "extracts paths" {
|
(it "extracts paths" {
|
||||||
actual = extractPaths {
|
actual = extractPaths {
|
||||||
something = "";
|
something = "";
|
||||||
a-thing = {
|
a-thing = { src = ./src/index.md; };
|
||||||
src = ./src/index.md;
|
a-list = [{ thingy = ./src/index.md; }];
|
||||||
};
|
|
||||||
a-list = [
|
|
||||||
{thingy = ./src/index.md;}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
expected = {
|
expected = {
|
||||||
something = "";
|
something = "";
|
||||||
a-thing = {
|
a-thing = { src = "/static/index.md"; };
|
||||||
src = "/static/index.md";
|
a-list = [{ thingy = "/static/index.md"; }];
|
||||||
};
|
static = { "index.md" = ./src/index.md; };
|
||||||
a-list = [
|
|
||||||
{thingy = "/static/index.md";}
|
|
||||||
];
|
|
||||||
static = {
|
|
||||||
"index.md" = ./src/index.md;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,76 +3,87 @@ let
|
||||||
html = import ../nixite/html.nix;
|
html = import ../nixite/html.nix;
|
||||||
it = import ./it.nix;
|
it = import ./it.nix;
|
||||||
|
|
||||||
my =
|
p = style.styled "generic" "p" {
|
||||||
(style.styled "p" "p" {style = {
|
foo = "bar";
|
||||||
some-style = "some value";
|
forgetme = "nothing";
|
||||||
};})
|
};
|
||||||
(style.styled "div" "div" {class = ["something"]; style = {
|
|
||||||
this = "that";
|
my = (style.styled "p" "p" { style = { some-style = "some value"; }; })
|
||||||
};})
|
(style.styled "classless" "div" { class = [ ]; })
|
||||||
(style.styled "s" "div" {
|
(style.styled "quote" p.generic {
|
||||||
|
baz = "baz";
|
||||||
|
forgetme = "forgotten";
|
||||||
|
}) (style.styled "div" "div" {
|
||||||
|
class = [ "something" ];
|
||||||
|
style = { this = "that"; };
|
||||||
|
}) (style.styled "s" "div" {
|
||||||
id = "s";
|
id = "s";
|
||||||
class = [ "something" ];
|
class = [ "something" ];
|
||||||
style = {
|
style = { s = "yes"; };
|
||||||
s = "yes";
|
}) (style.styled "foobar" "div" {
|
||||||
};})
|
|
||||||
(style.styled "foobar" "div" {
|
|
||||||
class = [ "foo" "bar" ];
|
class = [ "foo" "bar" ];
|
||||||
style = {
|
style = { something = "something"; };
|
||||||
something = "something";
|
}) (style.style "body" { foo = "bar"; }) (style.styled "list" "ul" {
|
||||||
};
|
|
||||||
} )
|
|
||||||
(style.style "body" {
|
|
||||||
foo = "bar";
|
|
||||||
})
|
|
||||||
(style.styled "list" "ul" {
|
|
||||||
__child = child:
|
__child = child:
|
||||||
assert builtins.isList child; (map (html.tag "li" {}) child);
|
assert builtins.isList child;
|
||||||
|
(map (html.tag "li" { }) child);
|
||||||
});
|
});
|
||||||
in [
|
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" {
|
(it "makes a p component" {
|
||||||
expected = html.tag "p" { class = [ "p" ]; } "yes";
|
expected = html.tag "p" { class = [ "p" ]; } "yes";
|
||||||
actual = my.p { } "yes";
|
actual = my.p { } "yes";
|
||||||
asString = true;
|
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" {
|
(it "does not error without attrs" {
|
||||||
expected = html.tag "p" { class = [ "p" ]; } "yes";
|
expected = html.tag "p" { class = [ "p" ]; } "yes";
|
||||||
actual = my.p "yes";
|
actual = my.p "yes";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes a component" {
|
(it "makes a component" {
|
||||||
expected = html.tag "div" {class = ["something"];} "foobar";
|
expected = html.tag "div" { class = [ "div" "something" ]; } "foobar";
|
||||||
actual = my.div { } "foobar";
|
actual = my.div { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "makes special components" {
|
(it "makes special components" {
|
||||||
expected = html.tag "div" {
|
expected = html.tag "div" {
|
||||||
id = "s";
|
id = "s";
|
||||||
class = ["something"];
|
class = [ "s" "something" ];
|
||||||
} "foobar";
|
} "foobar";
|
||||||
actual = my.s { } "foobar";
|
actual = my.s { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "works on many classes" {
|
(it "works on many classes" {
|
||||||
expected = html.tag "div" {class = ["foo" "bar"];} "foobar";
|
expected = html.tag "div" { class = [ "foobar" "foo" "bar" ]; } "foobar";
|
||||||
actual = my.foobar { } "foobar";
|
actual = my.foobar { } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "does custom behavour" {
|
(it "does custom behavour" {
|
||||||
expected = (html.tag "ul" {
|
expected = html.tag "ul" {
|
||||||
__ = "";
|
__ = "";
|
||||||
class = [ "list" ];
|
class = [ "list" ];
|
||||||
} [
|
} [ (html.tag "li" { } "1") (html.tag "li" { } "2") ];
|
||||||
(html.tag "li" {} "1")
|
actual = my.list { } [ "1" "2" ];
|
||||||
(html.tag "li" {} "2")
|
|
||||||
]);
|
|
||||||
actual = (my.list {} ["1" "2"]);
|
|
||||||
asString = true;
|
asString = true;
|
||||||
})
|
})
|
||||||
(it "combines attrs" {
|
(it "combines attrs" {
|
||||||
expected = html.tag "div" {
|
expected = html.tag "div" {
|
||||||
id = "foo";
|
id = "foo";
|
||||||
class = ["something"];
|
class = [ "div" "something" ];
|
||||||
} "foobar";
|
} "foobar";
|
||||||
actual = my.div { id = "foo"; } "foobar";
|
actual = my.div { id = "foo"; } "foobar";
|
||||||
asString = true;
|
asString = true;
|
||||||
|
|
Loading…
Reference in a new issue