{ config, options, lib, pkgs, ... }: let inherit (lib) mkOption types ; templates = import ./templates.nix { inherit lib; }; # TODO: optionally run the whole thing through the validator # https://github.com/validator/validator render-html = document: let eval = lib.evalModules { class = "DOM"; modules = [ document (import ./dom.nix) ]; }; in toString eval.config; in { options.templates = let # arbitrarily nested attribute set where the leaves are of type `type` recursiveAttrs = type: with types; # NOTE: due to how `either` works, the first match is significant, # so if `type` happens to be an attrset, the typecheck will consider # `type`, not `attrsOf` attrsOf (either type (recursiveAttrs type)); in mkOption { description = '' Collection of named helper functions for conversion different structured representations which can be rendered to a string ''; type = recursiveAttrs (with types; functionTo (coercedTo attrs toString str)); }; config.templates.html = { markdown = { name, body }: let commonmark = pkgs.runCommand "${name}.html" { buildInputs = [ pkgs.cmark ]; } '' cmark ${builtins.toFile "${name}.md" body} > $out ''; in builtins.readFile commonmark; nav = { menu, page }: let render-item = item: if item ? menu then ''