summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@friendco.de>2014-03-31 17:06:35 -0700
committerAaron O'Mullan <aaron.omullan@friendco.de>2014-03-31 17:06:39 -0700
commit39f1ed055e87df7a8010f7b998ec4f931997be00 (patch)
treeed356b16663225d659c221325ecd8f3998a173f9
parent3f3bade58e3b258aadab8ecf084004d06e62cede (diff)
downloadgitbook-39f1ed055e87df7a8010f7b998ec4f931997be00.zip
gitbook-39f1ed055e87df7a8010f7b998ec4f931997be00.tar.gz
gitbook-39f1ed055e87df7a8010f7b998ec4f931997be00.tar.bz2
Add parse.navigation module
With tests
-rw-r--r--lib/parse/index.js2
-rw-r--r--lib/parse/navigation.js67
-rw-r--r--test/navigation.js46
3 files changed, 115 insertions, 0 deletions
diff --git a/lib/parse/index.js b/lib/parse/index.js
index 2caf6a4..f6593ef 100644
--- a/lib/parse/index.js
+++ b/lib/parse/index.js
@@ -1,4 +1,6 @@
module.exports = {
summary: require('./summary'),
page: require('./page'),
+
+ navigation: require('./navigation'),
};
diff --git a/lib/parse/navigation.js b/lib/parse/navigation.js
new file mode 100644
index 0000000..8d39a4e
--- /dev/null
+++ b/lib/parse/navigation.js
@@ -0,0 +1,67 @@
+var _ = require('lodash');
+
+// Cleans up an article/chapter object
+// remove 'articles' and '_path' attributes
+function clean(obj) {
+ return _.omit(obj, ['articles', '_path']);
+}
+
+// Returns a map of
+/*
+ {
+ "file/path.html": {
+ prev: ...,
+ next: ...,
+ },
+ ...
+ }
+*/
+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 = {};
+
+ // Walk the chapter/article tree and create navigation entires
+ _.each(summary.chapters, function(chapter, idx, chapters) {
+ var currentChapter = clean(chapter);
+ var prevChapter = (idx-1 < 0) ? null : clean(chapters[idx-1]);
+ var nextChapter = (idx+1 >= chapters.length) ? null : clean(chapters[idx+1]);
+
+ // Add chapter mapping
+ mapping[chapter.path] = {
+ prev: prevChapter,
+ next: nextChapter,
+ };
+
+ // Check a chapter's articles
+ _.each(chapter.articles, function(article, _idx, articles) {
+
+ var prev = (_idx-1 < 0) ? currentChapter : clean(articles[_idx-1]);
+ var next = (_idx+1 >= articles.length) ? nextChapter : clean(articles[_idx+1]);
+
+ mapping[article.path] = {
+ prev: prev,
+ next: next,
+ };
+ });
+ });
+
+ // Hack for README.html
+ mapping['README.html'] = {
+ prev: null,
+ next: clean(summary.chapters[0]),
+ };
+
+ // Filter for only files we want
+ if(files) {
+ return _.pick(mapping, files);
+ }
+
+ return mapping;
+}
+
+
+// Exports
+module.exports = navigation;
diff --git a/test/navigation.js b/test/navigation.js
new file mode 100644
index 0000000..d34c12a
--- /dev/null
+++ b/test/navigation.js
@@ -0,0 +1,46 @@
+var fs = require('fs');
+var path = require('path');
+var assert = require('assert');
+
+var summary = require('../').parse.summary;
+var navigation = require('../').parse.navigation;
+
+
+var CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/SUMMARY.md'), 'utf8');
+var LEXED = summary(CONTENT);
+
+
+describe('Summary navigation', function() {
+ it('should provide next & prev entries for a file', function() {
+ var nav = navigation(LEXED, [
+ 'README.html',
+ 'chapter-1/ARTICLE1.html',
+ 'chapter-1/ARTICLE2.html'
+ ]);
+
+ // Make sure it found the files we gave it
+ assert(nav['README.html']);
+ assert(nav['chapter-1/ARTICLE1.html']);
+ assert(nav['chapter-1/ARTICLE2.html']);
+
+ assert.equal(nav['README.html'].prev, null);
+ assert.equal(nav['README.html'].next.path, 'chapter-1/README.html');
+
+ assert.equal(nav['chapter-1/ARTICLE1.html'].prev.path, 'chapter-1/README.html');
+ assert.equal(nav['chapter-1/ARTICLE1.html'].next.path, 'chapter-1/ARTICLE2.html');
+
+ assert.equal(nav['chapter-1/ARTICLE2.html'].prev.path, 'chapter-1/ARTICLE1.html');
+ assert.equal(nav['chapter-1/ARTICLE2.html'].next.path, 'chapter-2/README.html');
+ });
+
+ it('should give full tree, when not limited', function() {
+ var nav = navigation(LEXED);
+
+ assert(nav['README.html']);
+ assert(nav['chapter-1/README.html']);
+ assert(nav['chapter-1/ARTICLE1.html']);
+ assert(nav['chapter-1/ARTICLE2.html']);
+ assert(nav['chapter-2/README.html']);
+ assert(nav['chapter-3/README.html']);
+ });
+});