Ractive template AST representation

Parse html text as Ractive AST and traverse AST to create a nested visualization

by vikikamath

HTML

<main></main>
<script type="text/ractive" id="template">
  <div class="module module-jobs">

    <h4>Job Board</h4>


    <ul class="job-list">

      <li>
        <a href="http://codepen.io/url/job/nqeRen">
          <strong>
            Billy Graham Evangelistic Association          </strong> is hiring a Front End Web Developer </a>
      </li>
      <li>
        <a href="http://codepen.io/url/job/nLYxGz">
          <strong>
            Anchor          </strong> is hiring a Lead Front End Engineer </a>
      </li>
      <li>
        <a href="http://codepen.io/url/job/nJoedz">
          <strong>
            BetterHelp.com          </strong> is hiring a UI / UX Designer and Developer </a>
      </li>

    </ul>

    <div class="button-wrap">
      <a href="/jobs/" class="button">See More Jobs</a> &nbsp;
      <a href="http://codepen.io/jobs/post/" class="button button-bold">Post a Job</a>
    </div>

  </div>
</script>

<result>
</result>

CSS

result {
  text-align: center;
  box-sizing: border-box;
  margin: 1rem;
}

result ul {
  list-style: none;
  padding: 0;
}

result ul li {
  display: inline-block;
  padding: 0.3rem;
  text-decoration: underline;
}

span.header {
  font-size: 2rem;
  font-weight: 700;
  color: crimson;
}

div.text {
  color: gray;
}

div.class {
  color: black;
}

div.tag {
  color: blue;
  border: solid 1px blue;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  align-items: baseline;
  align-content: space-around;
  padding: 0.7rem;
}

.classes:before {
  content: " [";
}

.classes::after {
  content: "] ";
}

JavaScript

var traverse = function(node) {

  if (!node) {
    return '';
  } else if (typeof node === 'string') {
    return '<div class="text">' + node + '</div>';
  }

  var ret = '<div class="tag"><span class="header">' + node.e + '</span>';

  if (node.a && node.a.class) {

    ret = node.a.class.split(' ').reduce(function(agg, cl) {
      agg += '<li class="class">' + cl + '</li>';
      return agg;
    }, (ret += '<ul class="classes">'));

    ret += '</ul>';
  }
  return ret + node.f.reduce(function(agg, o) {
    agg += traverse(o);
    return agg;
  }, '') + '</div>';
}

var r = new Ractive({
  el: 'main',
  template: '#template'
})

var z = new Ractive({
	el: 'result',
  template: (traverse(r.template[0]))
})