diff options
author | Aaron O'Mullan <aaron.omullan@friendco.de> | 2014-03-31 01:50:21 -0700 |
---|---|---|
committer | Aaron O'Mullan <aaron.omullan@friendco.de> | 2014-03-31 01:50:21 -0700 |
commit | 0af1886358e79b5e9f84fcdeb7017edbc185d3c7 (patch) | |
tree | 514da2c9e10154468d674dd35d30ee76b1bad08f /lib/parse/summary.js | |
parent | d18da55a184ef514cb996e731830cd0749ccdfe9 (diff) | |
download | gitbook-0af1886358e79b5e9f84fcdeb7017edbc185d3c7.zip gitbook-0af1886358e79b5e9f84fcdeb7017edbc185d3c7.tar.gz gitbook-0af1886358e79b5e9f84fcdeb7017edbc185d3c7.tar.bz2 |
Move summary & page parsing code to lib/parse/
Diffstat (limited to 'lib/parse/summary.js')
-rw-r--r-- | lib/parse/summary.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/lib/parse/summary.js b/lib/parse/summary.js new file mode 100644 index 0000000..8787554 --- /dev/null +++ b/lib/parse/summary.js @@ -0,0 +1,112 @@ +var _ = require('lodash'); +var marked = require('marked'); + + +// Utility function for splitting a list into groups +function splitBy(list, starter, ender) { + var starts = 0; + var ends = 0; + var group = []; + + // Groups + return _.reduce(list, function(groups, value) { + // Ignore start and end delimiters in resulted groups + if(starter(value)) { + starts++; + } else if(ender(value)) { + ends++; + } + + // Add current value to group + group.push(value); + + // We've got a matching + if(starts === ends && starts !== 0) { + // Add group to end groups + // (remove starter and ender token) + groups.push(group.slice(1, -1)); + + // Reset group + group = []; + } + + return groups; + }, []); +} + +function listSplit(nodes, start_type, end_type) { + return splitBy(nodes, function(el) { + return el.type === start_type; + }, function(el) { + return el.type === end_type; + }); +} + +// Get the biggest list +// out of a list of marked nodes +function filterList(nodes) { + return _.chain(nodes) + .toArray() + .rest(function(el) { + // Get everything after list_start + return el.type !== 'list_start'; + }) + .reverse() + .rest(function(el) { + // Get everything after list_end (remember we're reversed) + return el.type !== 'list_end'; + }) + .reverse() + .value().slice(1, -1); +} + +// Parses an Article or Chapter title +// supports extracting links +function parseTitle(src) { + // Check if it's a link + var matches = marked.InlineLexer.rules.link.exec(src); + + // Not a link, return plain text + if(!matches) { + return { + title: src, + path: null, + }; + } + + return { + title: matches[1], + path: matches[2], + }; +} + +function parseArticle(nodes) { + return parseTitle(_.first(nodes).text); +} + +function parseChapter(nodes) { + return { + chapter: parseTitle(_.first(nodes).text), + articles: _.map(listSplit(filterList(nodes), 'list_item_start', 'list_item_end'), parseArticle) + }; +} + +function parseSummary(src) { + var nodes = marked.lexer(src); + + // Get out list of chapters + var chapterList = filterList(nodes); + + // Split out chapter sections + var chapters = _.chain(listSplit(chapterList, 'list_item_start', 'list_item_end')) + .map(parseChapter) + .value(); + + return { + chapters: chapters + }; +} + + +// Exports +module.exports = parseSummary; |