summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@friendco.de>2014-04-18 11:49:51 -0700
committerAaron O'Mullan <aaron.omullan@friendco.de>2014-04-18 11:49:55 -0700
commitc9db068227877fb2d278f1d651364b67db8ec360 (patch)
treee9d9704ea0ca1dcc920103ca2a71d89e9b5b9b7c /lib
parent8a6d36ac4d8b8d3796e961e19455a3861a3a8e91 (diff)
downloadgitbook-c9db068227877fb2d278f1d651364b67db8ec360.zip
gitbook-c9db068227877fb2d278f1d651364b67db8ec360.tar.gz
gitbook-c9db068227877fb2d278f1d651364b67db8ec360.tar.bz2
Refactor navigation generation to be functional
This makes it a lot less error prone and far more robust. As well as a lot easier to understand
Diffstat (limited to 'lib')
-rw-r--r--lib/parse/navigation.js75
1 files changed, 28 insertions, 47 deletions
diff --git a/lib/parse/navigation.js b/lib/parse/navigation.js
index bba25ce..2f8669e 100644
--- a/lib/parse/navigation.js
+++ b/lib/parse/navigation.js
@@ -6,6 +6,12 @@ function clean(obj) {
return obj && _.omit(obj, ['articles']);
}
+function flattenChapters(chapters) {
+ return _.reduce(chapters, function(accu, chapter) {
+ return accu.concat([clean(chapter)].concat(chapter.articles));
+ }, []);
+}
+
// Returns from a summary a map of
/*
{
@@ -20,61 +26,36 @@ function navigation(summary, files) {
// Support single files as well as list
files = _.isArray(files) ? files : (_.isString(files) ? [files] : null);
- // Mapping of prev/next for a give path
- var mapping = {};
-
// Special README nav
var README_NAV = {
path: 'README.md',
title: 'Introduction',
+ level: '0',
};
- // Walk the chapter/article tree and create navigation entires
- _.each(summary.chapters, function(chapter, idx, chapters) {
- // Skip if no path
- if(!chapter.path) return;
-
- var currentChapter = clean(chapter);
- var prevChapter = (idx-1 < 0) ? README_NAV : chapters[idx-1];
- var nextChapter = (idx+1 >= chapters.length) ? null : chapters[idx+1];
-
- var prev = (!prevChapter || _.isEmpty(prevChapter.articles)) ?
- prevChapter : _.last(prevChapter.articles);
- var next = (!chapter || _.isEmpty(chapter.articles)) ?
- nextChapter : _.first(chapter.articles);
+ // List of all navNodes
+ var navNodes = [README_NAV].concat(flattenChapters(summary.chapters));
+ var prevNodes = [null].concat(navNodes.slice(0, -1));
+ var nextNodes = navNodes.slice(1).concat([null]);
- // Add chapter mapping
- mapping[chapter.path] = {
- title: chapter.title,
- prev: clean(prev),
- next: clean(next),
- level: (idx+1).toString(),
- };
-
- // Check a chapter's articles
- _.each(chapter.articles, function(article, _idx, articles) {
- // Skip if no path
- if(!article.path) return;
-
- var prev = (_idx-1 < 0) ? currentChapter : clean(articles[_idx-1]);
- var next = (_idx+1 >= articles.length) ? nextChapter : clean(articles[_idx+1]);
-
- mapping[article.path] = {
- title: article.title,
- prev: clean(prev),
- next: clean(next),
- level: [idx+1, _idx+1].join('.'),
- };
- });
- });
+ // Mapping of prev/next for a give path
+ var mapping = _.chain(_.zip(navNodes, prevNodes, nextNodes))
+ .map(function(nodes) {
+ var current = nodes[0], prev = nodes[1], next = nodes[2];
- // Hack for README.html
- mapping['README.md'] = {
- title: README_NAV.title,
- prev: null,
- next: clean(summary.chapters[0]),
- level: '0',
- };
+ // Skip if no path
+ if(!current.path) return null;
+
+ return [current.path, {
+ title: current.title,
+ prev: prev,
+ next: next,
+ level: current.level,
+ }];
+ })
+ .filter()
+ .object()
+ .value();
// Filter for only files we want
if(files) {