a
This commit is contained in:
parent
d30b078411
commit
ea64bc70fc
52
css.nix
52
css.nix
@ -1,19 +1,43 @@
|
|||||||
{utils}: let
|
{lib, ...}: let
|
||||||
inherit (utils) mapAttrsToList concatStringsSep isList toString map;
|
l = lib // builtins;
|
||||||
|
t = l.types;
|
||||||
|
|
||||||
evalCssValue = value:
|
evalCssValue = value:
|
||||||
if isList value
|
if l.isList value
|
||||||
then concatStringsSep ", " (map toString value)
|
then l.concatStringsSep ", " (l.map toString value)
|
||||||
else toString value;
|
else l.toString value;
|
||||||
evalInner = inner: concatStringsSep " " (mapAttrsToList (name: value: "${name}: ${evalCssValue value};") inner);
|
evalInner = inner:
|
||||||
css = maybeAttrs:
|
l.concatStringsSep
|
||||||
if isList maybeAttrs
|
" "
|
||||||
then concatStringsSep " " maybeAttrs
|
(
|
||||||
else concatStringsSep " " (mapAttrsToList (name: inner: "${name} { ${evalInner inner} }") maybeAttrs);
|
l.mapAttrsToList
|
||||||
in {
|
(name: value: "${name}: ${evalCssValue value};")
|
||||||
inherit css;
|
inner
|
||||||
|
);
|
||||||
|
eval = maybeAttrs:
|
||||||
|
if l.isList maybeAttrs
|
||||||
|
then l.concatStringsSep " " maybeAttrs
|
||||||
|
else
|
||||||
|
l.concatStringsSep
|
||||||
|
" "
|
||||||
|
(
|
||||||
|
l.mapAttrsToList
|
||||||
|
(name: inner: "${name} { ${evalInner inner} }")
|
||||||
|
maybeAttrs
|
||||||
|
);
|
||||||
|
css = {
|
||||||
|
__functor = self: arg: eval arg;
|
||||||
media = rule: inner: ''
|
media = rule: inner: ''
|
||||||
@media (${rule}) { ${css inner} }
|
@media (${rule}) { ${eval inner} }
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
html-nix.lib.css = l.mkOption {
|
||||||
|
type = t.functionTo t.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
html-nix.lib.css = css;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
8
default.nix
Normal file
8
default.nix
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./html.nix
|
||||||
|
./css.nix
|
||||||
|
./pkgs-lib.nix
|
||||||
|
./templaters/default.nix
|
||||||
|
];
|
||||||
|
}
|
15
examples/flake.nix
Normal file
15
examples/flake.nix
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inp:
|
||||||
|
inp.parts.lib.mkFlake {inputs = inp;} {
|
||||||
|
systems = ["x86_64-linux"];
|
||||||
|
imports = [
|
||||||
|
../default.nix
|
||||||
|
./site.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
tags,
|
|
||||||
pkgs,
|
|
||||||
}:
|
|
||||||
with pkgs.htmlNix; let
|
|
||||||
index = with tags;
|
|
||||||
html [
|
|
||||||
(body [
|
|
||||||
(p "Hello world!")
|
|
||||||
(mkLink "./ex.html" "say bye")
|
|
||||||
])
|
|
||||||
];
|
|
||||||
|
|
||||||
ex = with tags;
|
|
||||||
html [
|
|
||||||
(body [
|
|
||||||
(p "Bye world!")
|
|
||||||
(mkLink "./index.html" "go back")
|
|
||||||
])
|
|
||||||
];
|
|
||||||
|
|
||||||
site = {
|
|
||||||
"index.html" = index;
|
|
||||||
"ex.html" = ex;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
mkServeFromSite site
|
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
pkgs,
|
perSystem = {config, ...}: let
|
||||||
lib,
|
html-nix = config.html-nix;
|
||||||
}: let
|
siteServe = html-nix.mkServeFromSite (html-nix.mkSiteFrom {
|
||||||
inherit (pkgs) htmlNix;
|
|
||||||
src = ./site;
|
src = ./site;
|
||||||
in
|
templater = html-nix.lib.templaters.basic;
|
||||||
htmlNix.mkServeFromSite (htmlNix.mkSiteFrom {
|
|
||||||
inherit src;
|
|
||||||
templater = lib.templaters.basic;
|
|
||||||
local = true;
|
local = true;
|
||||||
})
|
});
|
||||||
|
in {
|
||||||
|
apps.site.program = "${siteServe}/bin/serve";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
tags:
|
|
||||||
with tags;
|
|
||||||
html [
|
|
||||||
(body [
|
|
||||||
(p "Hello,")
|
|
||||||
(p "world!")
|
|
||||||
])
|
|
||||||
]
|
|
120
flake.lock
120
flake.lock
@ -1,27 +1,28 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"flakeUtils": {
|
"examples": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"parts": "parts"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1644229661,
|
"lastModified": 1,
|
||||||
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
|
"narHash": "sha256-agjsV0F6nVUimGUciKlOSF35XvTOQKKEez0xZ8X0JBI=",
|
||||||
"owner": "numtide",
|
"path": "./examples",
|
||||||
"repo": "flake-utils",
|
"type": "path"
|
||||||
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
|
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"path": "./examples",
|
||||||
"repo": "flake-utils",
|
"type": "path"
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1644972330,
|
"lastModified": 1680668850,
|
||||||
"narHash": "sha256-6V2JFpTUzB9G+KcqtUR1yl7f6rd9495YrFECslEmbGw=",
|
"narHash": "sha256-mQMg13yRsS0LXVzaeoSPwqgPO6yhkGzGewPgMSqXSv8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "19574af0af3ffaf7c9e359744ed32556f34536bd",
|
"rev": "4a65e9f64e53fdca6eed31adba836717a11247d2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -31,10 +32,99 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "lib",
|
||||||
|
"lastModified": 1680213900,
|
||||||
|
"narHash": "sha256-cIDr5WZIj3EkKyCgj/6j3HBH4Jj1W296z7HTcWj1aMA=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e3652e0735fbec227f342712f180f4f21f0594f2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "lib",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib_2": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "lib",
|
||||||
|
"lastModified": 1680213900,
|
||||||
|
"narHash": "sha256-cIDr5WZIj3EkKyCgj/6j3HBH4Jj1W296z7HTcWj1aMA=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e3652e0735fbec227f342712f180f4f21f0594f2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "lib",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1680668850,
|
||||||
|
"narHash": "sha256-mQMg13yRsS0LXVzaeoSPwqgPO6yhkGzGewPgMSqXSv8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "4a65e9f64e53fdca6eed31adba836717a11247d2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1680392223,
|
||||||
|
"narHash": "sha256-n3g7QFr85lDODKt250rkZj2IFS3i4/8HBU2yKHO3tqw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "dcc36e45d054d7bb554c9cdab69093debd91a0b5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parts_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1680392223,
|
||||||
|
"narHash": "sha256-n3g7QFr85lDODKt250rkZj2IFS3i4/8HBU2yKHO3tqw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "dcc36e45d054d7bb554c9cdab69093debd91a0b5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flakeUtils": "flakeUtils",
|
"examples": "examples",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"parts": "parts_2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
58
flake.nix
58
flake.nix
@ -1,57 +1,17 @@
|
|||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flakeUtils.url = "github:numtide/flake-utils";
|
parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
examples.url = "path:./examples";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = {
|
outputs = inp:
|
||||||
self,
|
inp.parts.lib.mkFlake {inputs = inp;} {
|
||||||
flakeUtils,
|
debug = true;
|
||||||
nixpkgs,
|
systems = ["x86_64-linux"];
|
||||||
}: let
|
flake = {
|
||||||
utils = import ./utils.nix;
|
flakeModule = ./default.nix;
|
||||||
|
inherit (inp.examples) apps;
|
||||||
lib = {
|
|
||||||
# Convert Nix expressions to HTML
|
|
||||||
tags = import ./tags.nix {inherit utils;};
|
|
||||||
# Convert Nix expressions to CSS
|
|
||||||
css = import ./css.nix {inherit utils;};
|
|
||||||
|
|
||||||
# Various site templaters
|
|
||||||
templaters = {
|
|
||||||
# Basic templater with purecss, mobile responsive layout and supports posts
|
|
||||||
basic = import ./templaters/basic.nix;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = flakeUtils.lib.eachDefaultSystem (system: let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
in {
|
|
||||||
lib = {
|
|
||||||
pkgsLib = import ./pkgs-lib.nix {
|
|
||||||
inherit pkgs;
|
|
||||||
utils = utils // {inherit (lib) tags css;};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
apps = with flakeUtils.lib; {
|
|
||||||
site = mkApp {
|
|
||||||
drv = import ./examples/site.nix {inherit lib pkgs;};
|
|
||||||
name = "serve";
|
|
||||||
};
|
|
||||||
basicServe = mkApp {
|
|
||||||
drv = import ./examples/serve.nix {
|
|
||||||
inherit (lib) tags;
|
|
||||||
inherit pkgs;
|
|
||||||
};
|
|
||||||
name = "serve";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
examples = {
|
|
||||||
tags = import ./examples/tags.nix lib.tags;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
in
|
|
||||||
outputs // {lib = outputs.lib // lib;};
|
|
||||||
}
|
}
|
||||||
|
49
html.nix
Normal file
49
html.nix
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{lib, ...}: let
|
||||||
|
l = lib // builtins;
|
||||||
|
|
||||||
|
evalAttrs = attrs:
|
||||||
|
l.concatStrings
|
||||||
|
(
|
||||||
|
l.mapAttrsToList
|
||||||
|
(name: value: " ${name}=\"${value}\"")
|
||||||
|
attrs
|
||||||
|
);
|
||||||
|
evalChildren = children:
|
||||||
|
if l.isList children
|
||||||
|
then l.concatStrings children
|
||||||
|
else children;
|
||||||
|
tag = name: maybeAttrs:
|
||||||
|
if l.isAttrs maybeAttrs
|
||||||
|
then (children: "<${name}${evalAttrs maybeAttrs}>${evalChildren children}</${name}>")
|
||||||
|
else tag name {} maybeAttrs;
|
||||||
|
noChildrenTag = name: attrs: "<${name} ${evalAttrs attrs}>";
|
||||||
|
|
||||||
|
tagsToGen =
|
||||||
|
(l.map (n: "h${toString n}") (l.range 1 6))
|
||||||
|
++ ["ul" "li" "html" "head" "body" "div" "p"]
|
||||||
|
++ ["a" "title" "code" "pre" "nav" "article" "script"];
|
||||||
|
tags = l.genAttrs tag tagsToGen;
|
||||||
|
|
||||||
|
noChildrenTagsToGen = ["link" "meta"];
|
||||||
|
noChildrenTags = l.genAttrs noChildrenTag noChildrenTagsToGen;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
html-nix.lib.html = l.mkOption {
|
||||||
|
type = l.types.raw;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
html-nix.lib.html =
|
||||||
|
tags
|
||||||
|
// noChildrenTags
|
||||||
|
// {
|
||||||
|
inherit tag;
|
||||||
|
mkLink = url: tags.a {href = url;};
|
||||||
|
mkStylesheet = url:
|
||||||
|
noChildrenTags.link {
|
||||||
|
rel = "stylesheet";
|
||||||
|
href = url;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
86
pkgs-lib.nix
86
pkgs-lib.nix
@ -1,7 +1,26 @@
|
|||||||
{
|
{
|
||||||
utils,
|
lib,
|
||||||
pkgs,
|
flake-parts-lib,
|
||||||
|
...
|
||||||
}: let
|
}: let
|
||||||
|
l = lib // builtins;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
perSystem =
|
||||||
|
flake-parts-lib.mkPerSystemOption
|
||||||
|
({...}: {
|
||||||
|
html-nix.lib = {
|
||||||
|
mkServeFromSite = l.mkOption {
|
||||||
|
type = with l.types; functionTo package;
|
||||||
|
};
|
||||||
|
mkSiteFrom = l.mkOption {
|
||||||
|
type = with l.types; functionTo attrs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
perSystem = {pkgs, ...}: let
|
||||||
pkgBin = name: "${pkgs.${name}}/bin/${name}";
|
pkgBin = name: "${pkgs.${name}}/bin/${name}";
|
||||||
|
|
||||||
mkServePathScript = path:
|
mkServePathScript = path:
|
||||||
@ -10,53 +29,51 @@
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
mkSitePath = site: let
|
mkSitePath = site: let
|
||||||
inherit (utils) recursiveAttrPaths concatStringsSep map;
|
|
||||||
inherit (pkgs.lib) mapAttrsRecursive init last getAttrFromPath;
|
|
||||||
|
|
||||||
convertToPath = path: value:
|
convertToPath = path: value:
|
||||||
if builtins.isPath value
|
if builtins.isPath value
|
||||||
then value
|
then value
|
||||||
else pkgs.writeText (concatStringsSep "-" path) value;
|
else pkgs.writeText (l.concatStringsSep "-" path) value;
|
||||||
fileAttrPaths = recursiveAttrPaths site;
|
fileAttrPaths = l.recursiveAttrPaths site;
|
||||||
texts = mapAttrsRecursive convertToPath site;
|
texts = l.mapAttrsRecursive convertToPath site;
|
||||||
mkCreateFileCmd = path: value: let p = concatStringsSep "/" (init path); in "mkdir -p \"$out/${p}\" && ln -s \"${value}\" \"$out/${p}/${last path}\"";
|
mkCreateFileCmd = path: value: let
|
||||||
createFileCmds = map (path: mkCreateFileCmd path (getAttrFromPath path texts)) fileAttrPaths;
|
p = l.concatStringsSep "/" (l.init path);
|
||||||
|
in "mkdir -p \"$out/${p}\" && ln -s \"${value}\" \"$out/${p}/${l.last path}\"";
|
||||||
|
createFileCmds =
|
||||||
|
l.map
|
||||||
|
(path: mkCreateFileCmd path (l.getAttrFromPath path texts))
|
||||||
|
fileAttrPaths;
|
||||||
in
|
in
|
||||||
pkgs.runCommandLocal "site-path" {} ''
|
pkgs.runCommandLocal "site-path" {} ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
${concatStringsSep "\n" createFileCmds}
|
${l.concatStringsSep "\n" createFileCmds}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
parseMarkdown = name: contents:
|
parseMarkdown = name: contents:
|
||||||
pkgs.runCommandLocal name {} ''
|
pkgs.runCommandLocal name {} ''
|
||||||
printf ${pkgs.lib.escapeShellArg contents} | ${pkgBin "pandoc"} -f gfm > $out
|
printf ${l.escapeShellArg contents} | ${pkgBin "pandoc"} -f gfm > $out
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
inherit mkServePathScript mkSitePath parseMarkdown;
|
html-nix.lib = {
|
||||||
|
|
||||||
mkServeFromSite = site: mkServePathScript (mkSitePath site);
|
mkServeFromSite = site: mkServePathScript (mkSitePath site);
|
||||||
mkSiteFrom = {
|
mkSiteFrom = {
|
||||||
src,
|
src,
|
||||||
templater,
|
templater,
|
||||||
local ? false,
|
local ? false,
|
||||||
}: let
|
}: let
|
||||||
inherit (utils) readDir readFile fromTOML mapAttrsToList sort elemAt;
|
|
||||||
inherit (pkgs.lib) nameValuePair head splitString pipe removeSuffix mapAttrs';
|
|
||||||
|
|
||||||
postsRendered = let
|
postsRendered = let
|
||||||
path = src + "/posts";
|
path = src + "/posts";
|
||||||
in
|
in
|
||||||
pipe (readDir path) [
|
l.pipe (l.readDir path) [
|
||||||
(mapAttrsToList (
|
(l.mapAttrsToList (
|
||||||
name: _:
|
name: _:
|
||||||
nameValuePair
|
l.nameValuePair
|
||||||
(head (splitString "." name))
|
(l.head (l.splitString "." name))
|
||||||
(readFile (parseMarkdown name (readFile (path + "/${name}"))))
|
(l.readFile (parseMarkdown name (l.readFile (path + "/${name}"))))
|
||||||
))
|
))
|
||||||
(sort (
|
(l.sort (
|
||||||
p: op: let
|
p: op: let
|
||||||
extractDate = name: splitString "-" (head (splitString "_" name));
|
extractDate = name: l.splitString "-" (l.head (l.splitString "_" name));
|
||||||
getPart = name: el: removeSuffix "0" (elemAt (extractDate name) el);
|
getPart = name: el: l.removeSuffix "0" (l.elemAt (extractDate name) el);
|
||||||
d = getPart p.name;
|
d = getPart p.name;
|
||||||
od = getPart op.name;
|
od = getPart op.name;
|
||||||
in
|
in
|
||||||
@ -66,22 +83,22 @@ in {
|
|||||||
pagesRendered = let
|
pagesRendered = let
|
||||||
path = src + "/pages";
|
path = src + "/pages";
|
||||||
in
|
in
|
||||||
mapAttrs'
|
l.mapAttrs'
|
||||||
(
|
(
|
||||||
name: _:
|
name: _:
|
||||||
nameValuePair
|
l.nameValuePair
|
||||||
(head (splitString "." name))
|
(l.head (l.splitString "." name))
|
||||||
(readFile (parseMarkdown name (readFile (path + "/${name}"))))
|
(l.readFile (parseMarkdown name (l.readFile (path + "/${name}"))))
|
||||||
)
|
)
|
||||||
(readDir path);
|
(l.readDir path);
|
||||||
siteConfig = fromTOML (readFile (src + "/config.toml"));
|
siteConfig = l.fromTOML (l.readFile (src + "/config.toml"));
|
||||||
baseurl =
|
baseurl =
|
||||||
if local
|
if local
|
||||||
then "http://localhost:8080"
|
then "http://localhost:8080"
|
||||||
else siteConfig.baseurl or (throw "Need baseurl");
|
else siteConfig.baseurl or (throw "Need baseurl");
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
inherit utils pkgs baseurl;
|
inherit lib baseurl;
|
||||||
config = siteConfig;
|
config = siteConfig;
|
||||||
posts = postsRendered;
|
posts = postsRendered;
|
||||||
pages = pagesRendered;
|
pages = pagesRendered;
|
||||||
@ -94,4 +111,7 @@ in {
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
(templater context).site;
|
(templater context).site;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
34
tags.nix
34
tags.nix
@ -1,34 +0,0 @@
|
|||||||
{utils}: let
|
|
||||||
inherit (utils) concatStrings mapAttrsToList genAttrs isAttrs isList range toString;
|
|
||||||
|
|
||||||
evalAttrs = attrs: concatStrings (mapAttrsToList (name: value: " ${name}=\"${value}\"") attrs);
|
|
||||||
evalChildren = children:
|
|
||||||
if isList children
|
|
||||||
then concatStrings children
|
|
||||||
else children;
|
|
||||||
tag = name: maybeAttrs:
|
|
||||||
if isAttrs maybeAttrs
|
|
||||||
then (children: "<${name}${evalAttrs maybeAttrs}>${evalChildren children}</${name}>")
|
|
||||||
else tag name {} maybeAttrs;
|
|
||||||
noChildrenTag = name: attrs: "<${name} ${evalAttrs attrs}>";
|
|
||||||
|
|
||||||
tagsToGen =
|
|
||||||
(map (n: "h${toString n}") (range 1 6))
|
|
||||||
++ ["ul" "li" "html" "head" "body" "div" "p"]
|
|
||||||
++ ["a" "title" "code" "pre" "nav" "article" "script"];
|
|
||||||
tags = genAttrs tag tagsToGen;
|
|
||||||
|
|
||||||
noChildrenTagsToGen = ["link" "meta"];
|
|
||||||
noChildrenTags = genAttrs noChildrenTag noChildrenTagsToGen;
|
|
||||||
in
|
|
||||||
tags
|
|
||||||
// noChildrenTags
|
|
||||||
// {
|
|
||||||
inherit tag;
|
|
||||||
mkLink = url: tags.a {href = url;};
|
|
||||||
mkStylesheet = url:
|
|
||||||
noChildrenTags.link {
|
|
||||||
rel = "stylesheet";
|
|
||||||
href = url;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,27 +1,23 @@
|
|||||||
{
|
{
|
||||||
utils,
|
|
||||||
posts,
|
|
||||||
pkgs,
|
|
||||||
config,
|
config,
|
||||||
pages,
|
lib,
|
||||||
site,
|
|
||||||
baseurl,
|
|
||||||
...
|
...
|
||||||
} @ context: let
|
}: let
|
||||||
inherit (utils) readFile mapAttrsToList mapAttrs tags fetchGit map elemAt foldl' concatStrings genAttrs toString;
|
l = lib // builtins;
|
||||||
inherit (pkgs.lib) optionalString optionalAttrs optional length splitString nameValuePair toInt range mapAttrs' singleton;
|
t = l.types;
|
||||||
inherit (builtins) listToAttrs;
|
inherit (config.html-nix.lib) html css;
|
||||||
|
|
||||||
stylesheets = map tags.mkStylesheet [
|
func = ctx: let
|
||||||
"https://unpkg.com/purecss@2.0.6/build/pure-min.css"
|
stylesheets = l.map html.mkStylesheet [
|
||||||
"https://unpkg.com/purecss@2.0.6/build/grids-responsive-min.css"
|
"https://unpkg.com/purecss@3.0.0/build/pure-min.css"
|
||||||
"${baseurl}/site.css"
|
"https://unpkg.com/purecss@3.0.0/build/grids-responsive-min.css"
|
||||||
|
"${ctx.baseurl}/site.css"
|
||||||
];
|
];
|
||||||
|
|
||||||
parsePostName = name: let
|
parsePostName = name: let
|
||||||
parts = splitString "_" name;
|
parts = l.splitString "_" name;
|
||||||
id = elemAt parts 1;
|
id = l.elemAt parts 1;
|
||||||
date = elemAt parts 0;
|
date = l.elemAt parts 0;
|
||||||
in {
|
in {
|
||||||
inherit id date;
|
inherit id date;
|
||||||
formatted = "${date} - ${id}";
|
formatted = "${date} - ${id}";
|
||||||
@ -34,7 +30,7 @@
|
|||||||
parsed = parsePostName name;
|
parsed = parsePostName name;
|
||||||
inherit (parsed) id date;
|
inherit (parsed) id date;
|
||||||
in
|
in
|
||||||
with tags;
|
with html;
|
||||||
article [
|
article [
|
||||||
(a {
|
(a {
|
||||||
href = "#${id}";
|
href = "#${id}";
|
||||||
@ -44,45 +40,43 @@
|
|||||||
value
|
value
|
||||||
];
|
];
|
||||||
|
|
||||||
pagesSection =
|
pagesSection = with html;
|
||||||
[
|
[
|
||||||
(tags.div {class = "pure-u-1";} (tags.a {
|
(div {class = "pure-u-1";} (a {
|
||||||
href = "${baseurl}/";
|
href = "${ctx.baseurl}/";
|
||||||
class = "pagelink";
|
class = "pagelink";
|
||||||
} "home"))
|
} "home"))
|
||||||
]
|
]
|
||||||
++ (map
|
++ (l.map
|
||||||
(name:
|
(name:
|
||||||
tags.div {class = "pure-u-1";} (tags.a {
|
div {class = "pure-u-1";} (a {
|
||||||
href = "${baseurl}/${name}/";
|
href = "${ctx.baseurl}/${name}/";
|
||||||
class = "pagelink";
|
class = "pagelink";
|
||||||
}
|
}
|
||||||
name))
|
name))
|
||||||
(mapAttrsToList (name: _: name) pages))
|
(l.mapAttrsToList (name: _: name) pages))
|
||||||
++ [
|
++ [
|
||||||
(tags.div {class = "pure-u-1";} (tags.a {
|
(div {class = "pure-u-1";} (a {
|
||||||
href = "${baseurl}/posts/";
|
href = "${ctx.baseurl}/posts/";
|
||||||
class = "pagelink";
|
class = "pagelink";
|
||||||
} "posts"))
|
} "posts"))
|
||||||
];
|
];
|
||||||
|
|
||||||
postsRendered = map renderPost posts;
|
postsLinks = with html;
|
||||||
|
|
||||||
postsLinks = with tags;
|
|
||||||
singleton
|
singleton
|
||||||
(ul (
|
(ul (
|
||||||
map
|
l.map
|
||||||
(
|
(
|
||||||
post:
|
post:
|
||||||
li (
|
li (
|
||||||
a {href = "${baseurl}/${post.name}";}
|
a {href = "${ctx.baseurl}/${post.name}";}
|
||||||
(parsePostName post.name).formatted
|
(parsePostName post.name).formatted
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
posts
|
posts
|
||||||
));
|
));
|
||||||
|
|
||||||
postsSectionContent = with tags;
|
postsSectionContent = with html;
|
||||||
[
|
[
|
||||||
(a {
|
(a {
|
||||||
href = "#posts";
|
href = "#posts";
|
||||||
@ -91,20 +85,20 @@
|
|||||||
]
|
]
|
||||||
++ postsLinks;
|
++ postsLinks;
|
||||||
|
|
||||||
sidebarSection = optionalString ((length pagesSection) > 0) (
|
sidebarSection = l.optionalString ((l.length pagesSection) > 0) (
|
||||||
with tags;
|
with html;
|
||||||
nav {class = "sidebar";} [
|
nav {class = "sidebar";} [
|
||||||
(div {class = "pure-g";} pagesSection)
|
(div {class = "pure-g";} pagesSection)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
mkPage = content:
|
mkPage = content:
|
||||||
with tags; ''
|
with html; ''
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
${html [
|
${html [
|
||||||
(head (stylesheets
|
(head (stylesheets
|
||||||
++ [
|
++ [
|
||||||
(title config.title)
|
(title ctx.config.title)
|
||||||
(meta {
|
(meta {
|
||||||
name = "viewport";
|
name = "viewport";
|
||||||
content = "width=device-width, initial-scale=1";
|
content = "width=device-width, initial-scale=1";
|
||||||
@ -118,15 +112,15 @@
|
|||||||
]}
|
]}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
indexPage = mkPage (context.indexContent or postsSectionContent);
|
indexPage = mkPage (ctx.indexContent or postsSectionContent);
|
||||||
|
|
||||||
pagesAndPosts =
|
pagesAndPosts =
|
||||||
pages
|
ctx.pages
|
||||||
// listToAttrs (
|
// l.listToAttrs (
|
||||||
map (post: nameValuePair post.name (renderPost post)) posts
|
map (post: l.nameValuePair post.name (renderPost post)) ctx.posts
|
||||||
);
|
);
|
||||||
|
|
||||||
stylesheet = with utils.css; let
|
stylesheet = let
|
||||||
marginMobile = {
|
marginMobile = {
|
||||||
margin-left = "3%";
|
margin-left = "3%";
|
||||||
margin-right = "3%";
|
margin-right = "3%";
|
||||||
@ -135,9 +129,20 @@
|
|||||||
css [
|
css [
|
||||||
(css (
|
(css (
|
||||||
(
|
(
|
||||||
mapAttrs'
|
l.mapAttrs'
|
||||||
(name: value: nameValuePair value {content = "\"${concatStrings (map (_: "#") (range 1 (toInt name)))} \"";})
|
(
|
||||||
(genAttrs (n: "h${toString n}:before") (map toString (range 1 6)))
|
name: value:
|
||||||
|
l.nameValuePair
|
||||||
|
value
|
||||||
|
{
|
||||||
|
content = "\"${l.concatStrings (l.map (_: "#") (l.range 1 (l.toInt name)))} \"";
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(
|
||||||
|
l.genAttrs
|
||||||
|
(n: "h${l.toString n}:before")
|
||||||
|
(l.map l.toString (l.range 1 6))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
// {
|
// {
|
||||||
body = {
|
body = {
|
||||||
@ -177,7 +182,7 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
(media "max-width: 48em" {
|
(css.media "max-width: 48em" {
|
||||||
"nav.sidebar" =
|
"nav.sidebar" =
|
||||||
{
|
{
|
||||||
position = "relative";
|
position = "relative";
|
||||||
@ -191,17 +196,27 @@
|
|||||||
// marginMobile;
|
// marginMobile;
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
inherit stylesheets sidebarSection mkPage stylesheet;
|
inherit stylesheets sidebarSection mkPage stylesheet;
|
||||||
|
|
||||||
site =
|
site =
|
||||||
site
|
ctx.site
|
||||||
// {
|
// {
|
||||||
"index.html" = indexPage;
|
"index.html" = indexPage;
|
||||||
"posts"."index.html" = mkPage postsSectionContent;
|
"posts"."index.html" = mkPage postsSectionContent;
|
||||||
"404.html" = mkPage (tags.h1 "No such page");
|
"404.html" = mkPage (html.h1 "No such page");
|
||||||
"site.css" = stylesheet;
|
"site.css" = stylesheet;
|
||||||
}
|
}
|
||||||
// (mapAttrs (name: value: {"index.html" = mkPage value;}) pagesAndPosts)
|
// (l.mapAttrs (name: value: {"index.html" = mkPage value;}) pagesAndPosts)
|
||||||
// optionalAttrs (context ? resources) {inherit (context) resources;};
|
// l.optionalAttrs (ctx ? resources) {inherit (ctx) resources;};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
html-nix.lib.templaters.basic = l.mkOption {
|
||||||
|
type = t.functionTo t.attrs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
html-nix.lib.templaters.basic = func;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
5
templaters/default.nix
Normal file
5
templaters/default.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./basic.nix
|
||||||
|
];
|
||||||
|
}
|
38
utils.nix
38
utils.nix
@ -1,38 +0,0 @@
|
|||||||
let
|
|
||||||
inherit (builtins) isAttrs isList map any concatMap concatStringsSep listToAttrs genList;
|
|
||||||
|
|
||||||
mapAttrsToList = f: attrs: map (name: f name attrs.${name}) (builtins.attrNames attrs);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit mapAttrsToList;
|
|
||||||
|
|
||||||
recursiveAttrPaths = set: let
|
|
||||||
flattenIfHasList = x:
|
|
||||||
if (isList x) && (any isList x)
|
|
||||||
then concatMap flattenIfHasList x
|
|
||||||
else [x];
|
|
||||||
|
|
||||||
recurse = path: set: let
|
|
||||||
g = name: value:
|
|
||||||
if isAttrs value
|
|
||||||
then recurse (path ++ [name]) value
|
|
||||||
else path ++ [name];
|
|
||||||
in
|
|
||||||
mapAttrsToList g set;
|
|
||||||
in
|
|
||||||
flattenIfHasList (recurse [] set);
|
|
||||||
|
|
||||||
concatStrings = concatStringsSep "";
|
|
||||||
genAttrs = f: names:
|
|
||||||
listToAttrs (map (n: {
|
|
||||||
name = n;
|
|
||||||
value = f n;
|
|
||||||
})
|
|
||||||
names);
|
|
||||||
|
|
||||||
range = first: last:
|
|
||||||
if first > last
|
|
||||||
then []
|
|
||||||
else genList (n: first + n) (last - first + 1);
|
|
||||||
}
|
|
||||||
// builtins
|
|
Loading…
Reference in New Issue
Block a user