JSLT

by Cyril J

HTML

<div id="examples"></div>

JavaScript

/*
  JSON transformations, revisited

  Cyril Jandia (03/2016)

  Public Domain.

  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */
 
/*
  Cf. https://www.w3.org/TR/xslt#section-Document-Example
*/
var D1document = {
    type: "document", title: [ "Document Title" ],
    "": [
      { type: "chapter", title: [ "Chapter Title" ],
        "": [
        { type: "section", title: [ "Section Title" ],
          "": [
            { type: "para", "": [ "This is a test." ] },
            { type: "note", "": [ "This is a note." ] }
        ] },
        { type: "section", title: [ "Another Section Title" ],
          "": [
            { type: "para", "": [ "This is ", { emph: "another" }, " test." ] },
            { type: "note", "": [ "This is another note." ] }
        ] }
      ] }
    ] };

document.getElementById("examples").innerHTML += "<p>From:</p>";
document.getElementById("examples").innerHTML += "<xmp>D1document = " + JSON.stringify(D1document, null, 2) + "</xmp>";

var D1toHTML = { $: [
  [ [ function(node) { return node.type === "document"; } ],
    function(root) {
      return Per("<html>\r\n\
  <head>\r\n\
    <title>\r\n\
      {title}\r\n").map(root) + Per("\
    </title>\r\n\
  </head>\r\n\
  <body>\r\n\
{*}").map(Per(this).map(root[""])) + "\
  </body>\r\n\
</html>";
    }
  ],
  [ [ function(node) { return node.type === "chapter"; } ],
    function(chapter) {
      return Per("    <h2>{title}</h2>\r\n").map(chapter) + Per("{*}").map(Per(this).map(chapter[""]));
    }
  ],
  [ [ function(node) { return node.type === "section"; } ],
    function(section) {
      return Per("    <h3>{title}</h3>\r\n").map(section) + Per("{*}").map(Per(this).map(section[""]));
    }
  ],
  [ [ function(node) { return node.type === "para"; } ],
    function(para) {
      return Per("    <p>{*}</p>\r\n").map(Per(this).map(para[""]));
    }
  ],
  [ [ function(node) { return node.type === "note"; } ],
    function(note) {
      return Per('    <p...