Skip to content

Instantly share code, notes, and snippets.

/to_xml.nix Secret

Created March 11, 2017 16:50
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save anonymous/c52b3c9ca41f586a95a113d1a2bb26d3 to your computer and use it in GitHub Desktop.
let
lib = import <nixpkgs/lib>;
inherit (builtins) typeOf;
# TODO: escape the values
toKV = k: v: "${k}=${toString v}";
attrsToString = attrs:
lib.concatStringsSep " " (lib.mapAttrsToList toKV attrs);
contentToString = content:
let t = typeOf content;
in
assert (t == "set" || t == "string");
toString content;
# toXML
__toString = self:
let
attrs = lib.optionalString (self.attrs != {})
(" " + (attrsToString self.attrs));
tail =
if self.content == null then "/"
else
">" + (lib.concatStrings (map contentToString self.content)) + "</${self.name}";
in
"<${self.name}${attrs}${tail}>";
in
rec {
# TODO: introduce a mkText that can be escaped properly
# if content is null, it's a self-closing tag
mkTag = name: attrs: content:
assert typeOf name == "string";
assert typeOf attrs == "set";
{ inherit name attrs content __toString; };
mkX = name: attrs: mkTag name attrs null;
mkT = name: content:
assert typeOf content == "list";
mkTag name {} content;
mkXT = name: mkTag name {} null;
s1 = mkTag "hello" { name = "bryan"; } null;
s2 = mkTag "hello" { name = "rob"; } [
mkXT "hr"
];
sample = mkTag "html" { lang="en"; } [
(mkT "head" [
(mkX "meta" {charset="utf-8";})
])
(mkT "body" [
(mkT "h1" [
"Hello"
])
(mkT "p" [
"This is"
"a test"
])
(mkXT "hr")
])
];
test =
let
value = "<html lang=en><head><meta charset=utf-8/></head><body><h1>Hello</h1><p>This isa test</p><hr/></body></html>";
result = toString sample;
in
assert result == value;
result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment