{ config, lib, pkgs, ... }: with lib; let isEmpty = lst: (length lst) == 0; isEmptyAttrs = attrs: (length (attrNames attrs)) == 0; renderAttr = name: value: ''${name}="${value}"''; renderAttrs = attrs: if (isEmptyAttrs attrs) then "" else " " + concatStringsSep " " (mapAttrsToList renderAttr attrs); renderTag = tag: attrs: body: "<${tag}${renderAttrs attrs}>${body}"; # renderLoneTag = tag: attrs: "<${tag}${renderAttrs attrs} />"; toXML = { tag, attrs ? { }, children ? [ ] }: let renderElement = el: if isString el then el else toXML el; body = concatStringsSep "" (map renderElement children); in renderTag tag attrs body; toXMLFile = name: content: let preformatXML = pkgs.writeText "${name}-preformat.xml" (toXML content); in pkgs.stdenv.mkDerivation { name = "${name}.xml"; phases = [ "installPhase" ]; buildInputs = with pkgs; [ xmlformat ]; installPhase = "xmlformat ${preformatXML} > $out"; }; toFormattedXML = content: let xmlFile = toXMLFile "formatted-xml" content; in readFile xmlFile; in { inherit toXML toXMLFile toFormattedXML; }