From 056ee77ab2ed3cf488ac9b1b8ac82664948a42a3 Mon Sep 17 00:00:00 2001 From: Quentin Aristote Date: Fri, 11 Nov 2022 18:38:28 +0100 Subject: initial ocommit --- lib/default.nix | 5 ++ lib/html.nix | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 lib/default.nix create mode 100644 lib/html.nix (limited to 'lib') diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..2e3127d --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,5 @@ +{ lib }: + +{ + pp.html = import ./html.nix { inherit lib; }; +} diff --git a/lib/html.nix b/lib/html.nix new file mode 100644 index 0000000..aa1c839 --- /dev/null +++ b/lib/html.nix @@ -0,0 +1,219 @@ +{ lib, ... }: + +let + comment = content: ""; + lines = lib.concatStringsSep "\n"; + sortByPath = cmp: keys: + lib.sort + (x: y: cmp (lib.getAttrFromPath keys x) (lib.getAttrFromPath keys y)); + sortByKey = cmp: key: sortByPath cmp [ key ]; + for = iterable: f: + if lib.isList iterable then + builtins.map f iterable + else + lib.mapAttrsToList f iterable; + + setAttr = attr: value: ''${attr}="${value}"''; + tagWithAttrs = tag: attrs: + "<${tag}${ + lib.concatMapStrings (x: " ${x}") (lib.mapAttrsToList setAttr attrs) + }>"; + lineOrLines = f: content: + if lib.isList content then f (lines content) else f content; + tryOverride = f: arg: + if lib.isAttrs arg then + tryOverride (attrs: content: f (arg // attrs) content) + else + f { } arg; + container = tag: + tryOverride (attrs: + lineOrLines (content: "${tagWithAttrs tag attrs}${content}")); + + empty = tagWithAttrs; + + tagsContainer = [ + # Main root + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#main_root + "html" + # Document metadata + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#document_metadata + "head" + "style" + "title" + # Sectioning root + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#sectioning_root + "body" + # Content sectioning + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning + "address" + "article" + "aside" + "footer" + "header" + "h1" + "h2" + "h3" + "h4" + "h5" + "h6" + "main" + "nav" + "section" + # Text content + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#text_content + "blockquote" + "dd" + "div" + "dl" + "dt" + "figcaption" + "figure" + "li" + "menu" + "ol" + "p" + "pre" + "ul" + # Inline text semantics + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#inline_text_semantics + "a" + "abbr" + "b" + "bdi" + "bdo" + "cite" + "code" + "data" + "dfn" + "em" + "i" + "kbd" + "mark" + "q" + "rp" + "rt" + "ruby" + "s" + "samp" + "small" + "span" + "strong" + "sub" + "time" + "u" + "var" + # Image and multimedia + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#image_and_multimedia + "audio" + "map" + "track" + "video" + # Embedded content + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#embedded_content + "iframe" + "object" + "picture" + "portal" + "source" + # SVG and MathML + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#svg_and_mathml + "svg" + "math" + # Scripting + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#scripting + "canvas" + "noscript" + "script" + # Demarcating edits + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#demarcating_edits + "del" + "ins" + # Table content + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#table_content + "caption" + "colgroup" + "table" + "tbody" + "td" + "tfoot" + "th" + "thead" + "tr" + # Forms + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#forms + "button" + "datalist" + "fieldset" + "form" + "label" + "legend" + "meter" + "optgroup" + "option" + "output" + "progress" + "select" + "textarea" + # Interactive elements + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#interactive_elements + "details" + "dialog" + "summary" + # Web components + # https://developer.mozilla.org/en-US/docs/Web/HTML/Element#web_components + "slot" + "template" + ]; + tagsContainerFuns = + builtins.foldl' (module: tag: module // { "${tag}" = container tag; }) { } + tagsContainer; + + tagsEmpty = [ + "area" + "base" + "br" + "col" + "embed" + "hr" + "img" + "input" + "keygen" + "link" + "meta" + "param" + "source" + "track" + "wbr" + ]; + tagsEmptyFuns = builtins.foldl' (module: tag: + let tagWith = empty tag; + in module // { + "${tag}With" = tagWith; + "${tag}" = tagWith { }; + }) { } tagsEmpty; + + file = path: "/static/files/${path}"; + href = tryOverride (attrs: url: content: + tagsContainerFuns.a ({ href = url; } // attrs) content); + icon = + tryOverride (attrs: id: tagsContainerFuns.i (attrs // { class = id; }) ""); + mailto = tryOverride (attrs: address: href attrs "mailto:${address}" address); + timerange = start: end: + "${tagsContainerFuns.time { date = start; } start} - ${ + tagsContainerFuns.time { date = end; } end + }"; +in tagsContainerFuns // tagsEmptyFuns // { + inherit for comment container empty file href icon lines mailto timerange; +} // { + sort = let + lt = x: y: x < y; + gt = x: y: x > y; + in { + byKey = sortByKey lt; + byPath = sortByPath lt; + reverse = { + byKey = sortByKey gt; + byPath = sortByPath gt; + }; + }; +} -- cgit v1.2.3