diff options
| author | tv <tv@krebsco.de> | 2015-03-20 10:36:12 +0100 | 
|---|---|---|
| committer | tv <tv@krebsco.de> | 2019-02-16 17:28:55 +0100 | 
| commit | fe08236da659ff27eda98c6170fabbf981455c80 (patch) | |
| tree | aab3b8c8be0b291ac93c3cd5b43aacbf6316a22f | |
| parent | bfbeca92fb2c85edd1bbbed34ed3d27f854ed406 (diff) | |
lib.xml: init
| -rw-r--r-- | lib/default.nix | 1 | ||||
| -rw-r--r-- | lib/xml.nix | 84 | 
2 files changed, 85 insertions, 0 deletions
| diff --git a/lib/default.nix b/lib/default.nix index 75086f8..8ba55b5 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -9,6 +9,7 @@ let      krops = import ../submodules/krops/lib;      shell = import ./shell.nix { inherit lib; };      types = nixpkgs-lib.types // import ./types.nix { inherit lib; }; +    xml = import ./xml.nix { inherit lib; };      eq = x: y: x == y;      ne = x: y: x != y; diff --git a/lib/xml.nix b/lib/xml.nix new file mode 100644 index 0000000..92f5521 --- /dev/null +++ b/lib/xml.nix @@ -0,0 +1,84 @@ +{ lib }: +with lib; +with builtins; +rec { + +  # Use `term` to construct XML. +  # +  # Examples: +  # +  #   (term "bool" null null) +  #   (term "cool" null []) +  #   (term "fool" { hurr = "durr"; } null) +  #   (term "hool" null [ +  #     (term "tool" null null) +  #   ]) +  # +  # See `render` for how these get transformed into actuall XML documents. +  # +  term = name: attrs: content: { +    inherit name attrs content; +  }; + +  empty = term null null null; + +  # Ref http://www.w3.org/TR/xml/#syntax +  # +  # Example: +  # +  #   (quote "<cheez!>")                 #===>   <cheez!> +  # +  quote = let +    sub = { +      "&" = "&"; +      "<" = "<"; +      ">" = ">"; +      "'" = "'"; +      "\"" = """; +    }; +  in +    stringAsChars (c: sub.${c} or c); + +  # Turn an XML element to an XML document string. +  doc = t: +    "<?xml version='1.0' encoding='UTF-8'?>${render t}"; + +  # Render an XML element to a string. +  # +  # Rendering `empty` yields the empty string. +  # +  # Examples: +  # +  #   (term "bool" null null)                 #===>   <bool/> +  #   (term "cool" null [])                   #===>   <cool></cool> +  #   (term "fool" { hurr = "durr"; } null)   #===>   <fool hurr="durr"/> +  #   (term "hool" null [ +  #     (term "tool" null null) +  #   ])                                      #===>   <hool><tool/></hool> +  # +  render = let +    render-attrs = attrs: +      getAttr (typeOf attrs) { +        null = ""; +        set = concatStrings (mapAttrsToList (n: v: " ${n}=\"${v}\"") attrs); +      }; + +    render-content = content: +      getAttr (typeOf content) { +        bool = toJSON content; +        int = toJSON content; +        list = concatMapStrings render content; +        string = content; +      }; +  in +    { name, attrs, content }: +    if name == null +      then "" +      else let +        attrs' = render-attrs attrs; +        content' = render-content content; +      in +        if content == null +          then "<${name}${attrs'}/>" +          else "<${name}${attrs'}>${content'}</${name}>"; +} | 
