<commit_before>var util = require('util');
var handlebars = require('handlebars');
var _ = require('lodash');

var listTemplate = handlebars.compile([
  '<ul class="level-{{level}}">',
  '{{{items}}}',
  '</ul>'
].join('\n'));

var listItemTemplate = handlebars.compile([
  '<li>',
  '<a href="/{{this.url}}">{{this.title}}</a>',
  '{{{this.children}}}',
  '</li>'
].join('\n'));

function getParentPage(pages, fileName) {
  return _.find(pages, function(page) {
    if (page.name === fileName) {
      return true;
    }
    if (page.children) {
      return getParentPage(page.children, fileName);
    }
    return false;
  });
}

function getNavTree(pages, level) {

  var items = pages.map(function(page) {
    page.children = (page.children.length) ? getNavTree(page.children, level) : '';
    return listItemTemplate(page);
  }.bind(this)).join('');

  return (items) ? listTemplate({
    level: (level || 0) + 1,
    items: items
  }) : '';
}

function getPageTree(pages) {
  var pageTree = [];
  var parentPage;
  pages.forEach(function(page) {
    if (!page.parent) {
      pageTree.push(page);
    } else {
      if (parentPage = getParentPage(pageTree, page.parent)) {
        parentPage.children.push(page);
      }
    }
  });
  return pageTree;
}

module.exports = function(BaseViewModel) {

  function NavViewModel() {
    BaseViewModel.apply(this, arguments);
    this.setData('nav', getNavTree(getPageTree(this.data.pages)));
  }

  util.inherits(NavViewModel, BaseViewModel);

  return NavViewModel;
};<commit_msg>Better nav tree generation which now actually works<commit_after>var util = require('util');
var handlebars = require('handlebars');
var _ = require('lodash');

/*
 *Pre-compile the list templates.
 */
var listTemplate = handlebars.compile([
  '<ul class="level-{{level}}">',
  '{{{items}}}',
  '</ul>'
].join('\n'));

var listItemTemplate = handlebars.compile([
  '<li>',
  '<a href="/{{this.url}}">{{this.title}}</a>',
  '{{{this.children}}}',
  '</li>'
].join('\n'));

/**
 * ** Recursively ** render a navigation tree in HTML.
 * @param  {Array}    pages   The array of pages to render.
 * @param  {Integer}  level   The recursion level.
 * @return {Strng}            The full navigation tree in HTML.
 */
function renderNavTree(pages, level) {

  level = (level || 0) + 1;

  var items = pages.map(function(page) {
    return listItemTemplate(_.extend(page, {
      children: renderNavTree(page.children, level)
    }))
  });

  return (items.length) ? listTemplate({
    level: level,
    items: items.join('')
  }) : '';
}

/**
 * ** Recursively ** get all children pages for the specified parent page.
 * @param  {Object} parentPage  The parent page model.
 * @param  {Array} pages        The array of page models.
 * @return {Array}              The children pages array.
 */
function getChildrenPages(parentPage, pages) {
  return pages.filter(function(page) {
    return (page.parent === parentPage.name);
  }).map(function(page) {
    page.children = getChildrenPages(page, pages);
    return page;
  });
}

/**
 * Build a tree of pages. This function accepts a single dimensional array of pages,
 * and converts it into a tree via the page.parent >> parentPage.name relationship.
 * @param  {Array} pages The array of page models.
 * @return {Array}       The page tree array.
 */
function getPageTree(pages) {
  return pages.filter(function(page) {
    if (page.parent) return false;
    return (page.children = getChildrenPages(page, pages));
  });
}

module.exports = function(BaseViewModel) {
  /**
   * The Nav ViewModel
   */
  function NavViewModel() {
    BaseViewModel.apply(this, arguments);

    /* Generate the navigation tree HTML. */
    var pageTree = getPageTree(this.data.pages);
    var navTree = renderNavTree(pageTree);
    this.setData('nav', navTree);
  }

  util.inherits(NavViewModel, BaseViewModel);
  return NavViewModel;
};
{'fraction_non_alphanumeric': 0.1668806161745828, 'fraction_numerical': 0.0010269576379974327, 'mean_word_length': 3.5355064027939465, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4923905', 'n_tokens_mistral': 1241, 'n_tokens_neox': 1226, 'n_words': 305}