diff --git a/css.nix b/css.nix index 149bc0c..1026ce3 100644 --- a/css.nix +++ b/css.nix @@ -1,15 +1,16 @@ -{ utils }: -let +{utils}: let inherit (utils) mapAttrsToList concatStringsSep isList toString map; - evalCssValue = value: if isList value then concatStringsSep ", " (map toString value) else toString value; + evalCssValue = value: + if isList value + then concatStringsSep ", " (map toString value) + else toString value; evalInner = inner: concatStringsSep " " (mapAttrsToList (name: value: "${name}: ${evalCssValue value};") inner); css = maybeAttrs: if isList maybeAttrs then concatStringsSep " " maybeAttrs else concatStringsSep " " (mapAttrsToList (name: inner: "${name} { ${evalInner inner} }") maybeAttrs); -in -{ +in { inherit css; media = rule: inner: '' diff --git a/examples/serve.nix b/examples/serve.nix index ba309c0..c04ff72 100644 --- a/examples/serve.nix +++ b/examples/serve.nix @@ -1,6 +1,8 @@ -{ tags, pkgs }: -with pkgs.htmlNix; -let +{ + tags, + pkgs, +}: +with pkgs.htmlNix; let index = with tags; html [ (body [ @@ -17,6 +19,9 @@ let ]) ]; - site = { "index.html" = index; "ex.html" = ex; }; + site = { + "index.html" = index; + "ex.html" = ex; + }; in -mkServeFromSite site + mkServeFromSite site diff --git a/examples/site.nix b/examples/site.nix index 5b6e34a..332b0cd 100644 --- a/examples/site.nix +++ b/examples/site.nix @@ -1,10 +1,12 @@ -{ pkgs, lib }: -let +{ + pkgs, + lib, +}: let inherit (pkgs) htmlNix; src = ./site; in -htmlNix.mkServeFromSite (htmlNix.mkSiteFrom { - inherit src; - templater = lib.templaters.basic; - local = true; -}) + htmlNix.mkServeFromSite (htmlNix.mkSiteFrom { + inherit src; + templater = lib.templaters.basic; + local = true; + }) diff --git a/examples/tags.nix b/examples/tags.nix index 868a1e9..2909c09 100644 --- a/examples/tags.nix +++ b/examples/tags.nix @@ -1,7 +1,8 @@ -tags: with tags; -html [ - (body [ - (p "Hello,") - (p "world!") - ]) -] +tags: +with tags; + html [ + (body [ + (p "Hello,") + (p "world!") + ]) + ] diff --git a/flake.nix b/flake.nix index f65389b..ae5dd4e 100644 --- a/flake.nix +++ b/flake.nix @@ -4,50 +4,54 @@ flakeUtils.url = "github:numtide/flake-utils"; }; - outputs = { self, flakeUtils, nixpkgs }: - let - utils = import ./utils.nix; + outputs = { + self, + flakeUtils, + nixpkgs, + }: let + utils = import ./utils.nix; + 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.legacyPackagse.${system}; + in { 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; + pkgsLib = import ./pkgs-lib.nix { + inherit pkgs; + utils = utils // {inherit (lib) tags css;}; }; }; - overlay = final: prev: { - htmlNix = (import ./pkgs-lib.nix { pkgs = prev; utils = utils // { inherit (lib) tags css; }; }) // lib; + 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"; + }; }; - in - { inherit overlay; } // - (flakeUtils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; }; - in - { - lib = 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; - }; - })); + examples = { + tags = import ./examples/tags.nix lib.tags; + }; + }); + in + outputs // {lib = outputs.lib // lib;}; } diff --git a/pkgs-lib.nix b/pkgs-lib.nix index 1471e32..da17bd2 100644 --- a/pkgs-lib.nix +++ b/pkgs-lib.nix @@ -1,93 +1,104 @@ -{ utils, pkgs }: -let +{ + utils, + pkgs, +}: let pkgBin = name: "${pkgs.${name}}/bin/${name}"; - mkServePathScript = path: pkgs.writeScriptBin "serve" '' - #!${pkgs.stdenv.shell} - cd ${path} - ${pkgBin "caddy"} run --config Caddyfile - ''; + mkServePathScript = path: + pkgs.writeScriptBin "serve" '' + #!${pkgs.stdenv.shell} + cd ${path} + ${pkgBin "caddy"} run --config Caddyfile + ''; - mkSitePath = site: - let - inherit (utils) recursiveAttrPaths concatStringsSep map; - inherit (pkgs.lib) mapAttrsRecursive init last getAttrFromPath; + mkSitePath = site: let + inherit (utils) recursiveAttrPaths concatStringsSep map; + inherit (pkgs.lib) mapAttrsRecursive init last getAttrFromPath; - fileAttrPaths = recursiveAttrPaths site; - texts = mapAttrsRecursive (path: value: pkgs.writeText (concatStringsSep "-" path) value) site; - mkCreateFileCmd = path: value: let p = concatStringsSep "/" (init path); in "mkdir -p \"$out/${p}\" && ln -s \"${value}\" \"$out/${p}/${last path}\""; - createFileCmds = map (path: mkCreateFileCmd path (getAttrFromPath path texts)) fileAttrPaths; - in - pkgs.runCommandLocal "site-path" { } '' + fileAttrPaths = recursiveAttrPaths site; + texts = mapAttrsRecursive (path: value: pkgs.writeText (concatStringsSep "-" path) value) site; + mkCreateFileCmd = path: value: let p = concatStringsSep "/" (init path); in "mkdir -p \"$out/${p}\" && ln -s \"${value}\" \"$out/${p}/${last path}\""; + createFileCmds = map (path: mkCreateFileCmd path (getAttrFromPath path texts)) fileAttrPaths; + in + pkgs.runCommandLocal "site-path" {} '' mkdir -p $out ${concatStringsSep "\n" createFileCmds} ''; parseMarkdown = name: contents: - pkgs.runCommandLocal name { } '' + pkgs.runCommandLocal name {} '' printf ${pkgs.lib.escapeShellArg contents} | ${pkgBin "pandoc"} -f gfm > $out ''; -in -{ +in { inherit mkServePathScript mkSitePath parseMarkdown; mkServeFromSite = site: mkServePathScript (mkSitePath site); - mkSiteFrom = { src, templater, local ? false }: - let - inherit (utils) readDir readFile fromTOML mapAttrsToList sort elemAt; - inherit (pkgs.lib) nameValuePair head splitString pipe removeSuffix mapAttrs'; + mkSiteFrom = { + src, + templater, + local ? false, + }: let + inherit (utils) readDir readFile fromTOML mapAttrsToList sort elemAt; + inherit (pkgs.lib) nameValuePair head splitString pipe removeSuffix mapAttrs'; - postsRendered = - let path = src + "/posts"; in - pipe (readDir path) [ - (mapAttrsToList (name: _: - nameValuePair - (head (splitString "." name)) - (readFile (parseMarkdown name (readFile (path + "/${name}")))) - )) - (sort (p: op: - let - extractDate = name: splitString "-" (head (splitString "_" name)); - getPart = name: el: removeSuffix "0" (elemAt (extractDate name) el); - d = getPart p.name; - od = getPart op.name; - in - !(((d 0) > (od 0)) && ((d 1) > (od 1)) && ((d 2) > (od 2))) - )) - ]; - pagesRendered = - let path = src + "/pages"; in - mapAttrs' - (name: _: - nameValuePair - (head (splitString "." name)) - (readFile (parseMarkdown name (readFile (path + "/${name}")))) - ) - (readDir path); - siteConfig = fromTOML (readFile (src + "/config.toml")); - baseurl = if local then "http://localhost:8080" else siteConfig.baseurl or (throw "Need baseurl"); - - context = { - inherit utils pkgs baseurl; - config = siteConfig; - posts = postsRendered; - pages = pagesRendered; - site = { - "robots.txt" = '' - User-agent: * - Allow: / - ''; - "Caddyfile" = '' - ${baseurl} - - handle_errors { - rewrite * /{http.error.status_code}.html - file_server - } - file_server - ''; - }; - }; + postsRendered = let + path = src + "/posts"; in + pipe (readDir path) [ + (mapAttrsToList ( + name: _: + nameValuePair + (head (splitString "." name)) + (readFile (parseMarkdown name (readFile (path + "/${name}")))) + )) + (sort ( + p: op: let + extractDate = name: splitString "-" (head (splitString "_" name)); + getPart = name: el: removeSuffix "0" (elemAt (extractDate name) el); + d = getPart p.name; + od = getPart op.name; + in + !(((d 0) > (od 0)) && ((d 1) > (od 1)) && ((d 2) > (od 2))) + )) + ]; + pagesRendered = let + path = src + "/pages"; + in + mapAttrs' + ( + name: _: + nameValuePair + (head (splitString "." name)) + (readFile (parseMarkdown name (readFile (path + "/${name}")))) + ) + (readDir path); + siteConfig = fromTOML (readFile (src + "/config.toml")); + baseurl = + if local + then "http://localhost:8080" + else siteConfig.baseurl or (throw "Need baseurl"); + + context = { + inherit utils pkgs baseurl; + config = siteConfig; + posts = postsRendered; + pages = pagesRendered; + site = { + "robots.txt" = '' + User-agent: * + Allow: / + ''; + "Caddyfile" = '' + ${baseurl} + + handle_errors { + rewrite * /{http.error.status_code}.html + file_server + } + file_server + ''; + }; + }; + in (templater context).site; } diff --git a/tags.nix b/tags.nix index 1df9111..7c5a3a3 100644 --- a/tags.nix +++ b/tags.nix @@ -1,23 +1,31 @@ -{ utils }: -let +{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; + evalChildren = children: + if isList children + then concatStrings children + else children; tag = name: maybeAttrs: if isAttrs maybeAttrs then (children: "<${name}${evalAttrs maybeAttrs}>${evalChildren children}") - else tag name { } maybeAttrs; + else tag name {} maybeAttrs; noChildrenTag = name: attrs: "<${name} ${evalAttrs attrs}>"; - tagsToGen = [ "html" "head" "body" "div" "p" "a" "title" "code" "pre" "nav" "article" ] ++ (map (n: "h${toString n}") (range 1 6)); + tagsToGen = ["html" "head" "body" "div" "p" "a" "title" "code" "pre" "nav" "article"] ++ (map (n: "h${toString n}") (range 1 6)); tags = genAttrs tag tagsToGen; - noChildrenTagsToGen = [ "link" "meta" ]; + 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; }; -} + tags + // noChildrenTags + // { + inherit tag; + mkLink = url: tags.a {href = url;}; + mkStylesheet = url: + noChildrenTags.link { + rel = "stylesheet"; + href = url; + }; + } diff --git a/templaters/basic.nix b/templaters/basic.nix index cc16384..07e4527 100644 --- a/templaters/basic.nix +++ b/templaters/basic.nix @@ -1,5 +1,13 @@ -{ utils, posts, pkgs, config, pages, site, baseurl, ... }@context: -let +{ + utils, + posts, + pkgs, + config, + pages, + site, + baseurl, + ... +} @ context: let inherit (utils) readFile mapAttrsToList mapAttrs tags fetchGit map elemAt foldl' concatStrings genAttrs toString; inherit (pkgs.lib) optional length splitString nameValuePair toInt range mapAttrs'; @@ -9,67 +17,96 @@ let "${baseurl}/site.css" ]; - renderPost = { name, value }: - let - parts = splitString "_" name; - id = elemAt parts 1; - in - with tags; article [ - (a { href = "#${id}"; class = "postheader"; } (h2 { inherit id; } id)) - (h3 ("date: " + (elemAt parts 0))) - value - ]; + renderPost = { + name, + value, + }: let + parts = splitString "_" name; + id = elemAt parts 1; + in + with tags; + article [ + (a { + href = "#${id}"; + class = "postheader"; + } (h2 {inherit id;} id)) + (h3 ("date: " + (elemAt parts 0))) + value + ]; pagesSection = (map - (name: tags.div { class = "pure-u-1"; } (tags.a { href = "${baseurl}/${name}/"; class = "pagelink"; } name)) - (mapAttrsToList (name: _: name) pages)) ++ [ (tags.div { class = "pure-u-1"; } (tags.a { href = "${baseurl}/"; class = "pagelink"; } "posts")) ]; + (name: + tags.div {class = "pure-u-1";} (tags.a { + href = "${baseurl}/${name}/"; + class = "pagelink"; + } + name)) + (mapAttrsToList (name: _: name) pages)) + ++ [ + (tags.div {class = "pure-u-1";} (tags.a { + href = "${baseurl}/"; + class = "pagelink"; + } "posts")) + ]; - postsSectionContent = with tags; [ - (a { href = "#posts"; class = "postheader"; } (h1 "posts")) - ] ++ (map renderPost posts); + postsSectionContent = with tags; + [ + (a { + href = "#posts"; + class = "postheader"; + } (h1 "posts")) + ] + ++ (map renderPost posts); sidebarSection = optional ((length pagesSection) > 0) ( - with tags; nav { class = "sidebar"; } ([ - (a { href = "#pages"; class = "postheader"; } (h1 "pages")) - (div { class = "pure-g"; } pagesSection) - ]) + with tags; + nav {class = "sidebar";} [ + (a { + href = "#pages"; + class = "postheader"; + } (h1 "pages")) + (div {class = "pure-g";} pagesSection) + ] ); - mkPage = content: with tags; - '' + mkPage = content: + with tags; '' ${html [ - (head (stylesheets ++ [ - (title config.title) - (meta { name = "viewport"; content = "width=device-width, initial-scale=1"; }) - ])) - (body (sidebarSection ++ [ (div { class = "content"; } content) ])) + (head (stylesheets + ++ [ + (title config.title) + (meta { + name = "viewport"; + content = "width=device-width, initial-scale=1"; + }) + ])) + (body (sidebarSection ++ [(div {class = "content";} content)])) ]} ''; - stylesheet = - with utils.css; - let - marginMobile = { - margin-left = "3%"; - margin-right = "3%"; - }; - in + stylesheet = with utils.css; let + marginMobile = { + margin-left = "3%"; + margin-right = "3%"; + }; + in css [ (css ( ( 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: nameValuePair value {content = "\"${concatStrings (map (_: "#") (range 1 (toInt name)))} \"";}) + (genAttrs (n: "h${toString n}:before") (map toString (range 1 6))) + ) + // { body = { - font-family = [ "Raleway" "Helvetica" "Arial" "sans-serif" ]; + font-family = ["Raleway" "Helvetica" "Arial" "sans-serif"]; background = "#111111"; color = "#eeeeee"; }; pre = { - font-family = [ "Iosevka Term" "Iosevka" "monospace" ]; + font-family = ["Iosevka Term" "Iosevka" "monospace"]; background = "#171A21"; color = "#eeeeee"; }; @@ -101,22 +138,28 @@ let } )) (media "max-width: 48em" { - "nav.sidebar" = { - position = "relative"; - margin-top = "5%"; - } // marginMobile; - "div.content" = { - margin-top = 0; - } // marginMobile; + "nav.sidebar" = + { + position = "relative"; + margin-top = "5%"; + } + // marginMobile; + "div.content" = + { + margin-top = 0; + } + // marginMobile; }) ]; -in -{ +in { inherit stylesheets sidebarSection mkPage stylesheet; - site = site // { - "index.html" = mkPage postsSectionContent; - "404.html" = mkPage (tags.h1 "No such page"); - "site.css" = stylesheet; - } // (mapAttrs (name: value: { "index.html" = mkPage value; }) pages); + site = + site + // { + "index.html" = mkPage postsSectionContent; + "404.html" = mkPage (tags.h1 "No such page"); + "site.css" = stylesheet; + } + // (mapAttrs (name: value: {"index.html" = mkPage value;}) pages); } diff --git a/utils.nix b/utils.nix index 1a95d2a..2b8af61 100644 --- a/utils.nix +++ b/utils.nix @@ -3,34 +3,36 @@ let mapAttrsToList = f: attrs: map (name: f name attrs.${name}) (builtins.attrNames attrs); in -{ - inherit mapAttrsToList; + { + inherit mapAttrsToList; - recursiveAttrPaths = set: - let + recursiveAttrPaths = set: let flattenIfHasList = x: if (isList x) && (any isList x) then concatMap flattenIfHasList x - else [ x ]; + else [x]; - recurse = path: set: - let - g = - name: value: - if isAttrs value - then recurse (path ++ [ name ]) value - else path ++ [ name ]; - in + 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); + flattenIfHasList (recurse [] set); - concatStrings = concatStringsSep ""; - genAttrs = f: names: listToAttrs (map (n: { name = n; value = (f n); }) names); + 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 + range = first: last: + if first > last + then [] + else genList (n: first + n) (last - first + 1); + } + // builtins