diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-01-19 09:47:36 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-01-19 09:47:36 +0100 |
commit | ec586dd3cdf06e9567f5d3e4961022ddc3c94778 (patch) | |
tree | cc7825ab73110b4e6fbedee404427b052edffa17 /lib/parse | |
parent | 80432161708357bdcf0e00533d9e6d327636dab6 (diff) | |
download | gitbook-ec586dd3cdf06e9567f5d3e4961022ddc3c94778.zip gitbook-ec586dd3cdf06e9567f5d3e4961022ddc3c94778.tar.gz gitbook-ec586dd3cdf06e9567f5d3e4961022ddc3c94778.tar.bz2 |
Clear folder
Diffstat (limited to 'lib/parse')
-rw-r--r-- | lib/parse/glossary.js | 48 | ||||
-rw-r--r-- | lib/parse/include.js | 12 | ||||
-rw-r--r-- | lib/parse/includer.js | 15 | ||||
-rw-r--r-- | lib/parse/index.js | 11 | ||||
-rw-r--r-- | lib/parse/is_exercise.js | 17 | ||||
-rw-r--r-- | lib/parse/is_quiz.js | 87 | ||||
-rw-r--r-- | lib/parse/langs.js | 25 | ||||
-rw-r--r-- | lib/parse/lex.js | 79 | ||||
-rw-r--r-- | lib/parse/navigation.js | 64 | ||||
-rw-r--r-- | lib/parse/page.js | 160 | ||||
-rw-r--r-- | lib/parse/progress.js | 47 | ||||
-rw-r--r-- | lib/parse/readme.js | 45 | ||||
-rw-r--r-- | lib/parse/renderer.js | 141 | ||||
-rw-r--r-- | lib/parse/summary.js | 167 |
14 files changed, 0 insertions, 918 deletions
diff --git a/lib/parse/glossary.js b/lib/parse/glossary.js deleted file mode 100644 index 549e9fd..0000000 --- a/lib/parse/glossary.js +++ /dev/null @@ -1,48 +0,0 @@ -var _ = require('lodash'); -var kramed = require('kramed'); - -// Get all the pairs of header + paragraph in a list of nodes -function groups(nodes) { - // A list of next nodes - var next = nodes.slice(1).concat(null); - - return _.reduce(nodes, function(accu, node, idx) { - // Skip - if(!( - node.type === 'heading' && - (next[idx] && next[idx].type === 'paragraph') - )) { - return accu; - } - - // Add group - accu.push([ - node, - next[idx] - ]); - - return accu; - }, []); -} - -function parseGlossary(src) { - var nodes = kramed.lexer(src); - - return groups(nodes) - .map(function(pair) { - // Simplify each group to a simple object with name/description - return { - name: pair[0].text, - id: entryId(pair[0].text), - description: pair[1].text, - }; - }); -} - -// Normalizes a glossary entry's name to create an ID -function entryId(name) { - return name.toLowerCase(); -} - -module.exports = parseGlossary; -module.exports.entryId = entryId; diff --git a/lib/parse/include.js b/lib/parse/include.js deleted file mode 100644 index 483b184..0000000 --- a/lib/parse/include.js +++ /dev/null @@ -1,12 +0,0 @@ -var _ = require('lodash'); - -module.exports = function(markdown, includer) { - // Memoized include function (to cache lookups) - var _include = _.memoize(includer); - - return markdown.replace(/{{([\s\S]+?)}}/g, function(match, key) { - // If fails leave content as is - key = key.trim(); - return _include(key) || match; - }); -}; diff --git a/lib/parse/includer.js b/lib/parse/includer.js deleted file mode 100644 index f7f20e0..0000000 --- a/lib/parse/includer.js +++ /dev/null @@ -1,15 +0,0 @@ -// Return a fs inclduer -module.exports = function(ctx, folders, resolveFile, readFile) { - return function(name) { - return ctx[name] || - folders.map(function(folder) { - // Try including snippet from FS - try { - var fname = resolveFile(folder, name); - // Trim trailing newlines/space of imported snippets - return readFile(fname, 'utf8').trimRight(); - } catch(err) {} - }) - .filter(Boolean)[0]; - } -}; diff --git a/lib/parse/index.js b/lib/parse/index.js deleted file mode 100644 index 23471af..0000000 --- a/lib/parse/index.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - summary: require('./summary'), - glossary: require('./glossary'), - langs: require('./langs'), - page: require('./page'), - lex: require('./lex'), - progress: require('./progress'), - navigation: require('./navigation'), - readme: require('./readme'), - includer: require('./includer') -}; diff --git a/lib/parse/is_exercise.js b/lib/parse/is_exercise.js deleted file mode 100644 index 74ed753..0000000 --- a/lib/parse/is_exercise.js +++ /dev/null @@ -1,17 +0,0 @@ -var _ = require('lodash'); - -function isExercise(nodes) { - var codeType = { type: 'code' }; - - // Number of code nodes in section - var len = _.filter(nodes, codeType).length; - - return ( - // Got 3 or 4 code blocks - (len === 3 || len === 4) && - // Ensure all nodes are at the end - _.all(_.last(nodes, len), codeType) - ); -} - -module.exports = isExercise; diff --git a/lib/parse/is_quiz.js b/lib/parse/is_quiz.js deleted file mode 100644 index 3322ff0..0000000 --- a/lib/parse/is_quiz.js +++ /dev/null @@ -1,87 +0,0 @@ -var _ = require('lodash'); - -function isQuizNode(node) { - return (/^[(\[][ x][)\]]/).test(node.text || node); -} - -function isTableQuestion(nodes) { - var block = questionBlock(nodes); - return ( - block.length === 1 && - block[0].type === 'table' && - _.all(block[0].cells[0].slice(1), isQuizNode) - ); -} - -function isListQuestion(nodes) { - var block = questionBlock(nodes); - // Counter of when we go in and out of lists - var inlist = 0; - // Number of lists we found - var lists = 0; - // Elements found outside a list - var outsiders = 0; - // Ensure that we have nothing except lists - _.each(block, function(node) { - if(node.type === 'list_start') { - inlist++; - } else if(node.type === 'list_end') { - inlist--; - lists++; - } else if(inlist === 0) { - // Found non list_start or list_end whilst outside a list - outsiders++; - } - }); - return lists > 0 && outsiders === 0; -} - -function isQuestion(nodes) { - return isListQuestion(nodes) || isTableQuestion(nodes); -} - -// Remove (optional) paragraph header node and blockquote -function questionBlock(nodes) { - return nodes.slice( - nodes[0].type === 'paragraph' ? 1 : 0, - _.findIndex(nodes, { type: 'blockquote_start' }) - ); -} - -function splitQuestions(nodes) { - // Represents nodes in current question - var buffer = []; - return _.reduce(nodes, function(accu, node) { - // Add node to buffer - buffer.push(node); - - // Flush buffer once we hit the end of a question - if(node.type === 'blockquote_end') { - accu.push(buffer); - // Clear buffer - buffer = []; - } - - return accu; - }, []); -} - -function isQuiz(nodes) { - // Extract potential questions - var questions = splitQuestions( - // Skip quiz title if there - nodes.slice( - (nodes[0] && nodes[0].type) === 'paragraph' ? 1 : 0 - ) - ); - - // Nothing that looks like questions - if(questions.length === 0) { - return false; - } - - // Ensure all questions are correctly structured - return _.all(questions, isQuestion); -} - -module.exports = isQuiz; diff --git a/lib/parse/langs.js b/lib/parse/langs.js deleted file mode 100644 index 01b7c8c..0000000 --- a/lib/parse/langs.js +++ /dev/null @@ -1,25 +0,0 @@ -var _ = require("lodash"); -var parseEntries = require("./summary").entries; - - -var parseLangs = function(content) { - var entries = parseEntries(content); - - return { - list: _.chain(entries) - .filter(function(entry) { - return Boolean(entry.path); - }) - .map(function(entry) { - return { - title: entry.title, - path: entry.path, - lang: entry.path.replace("/", "") - }; - }) - .value() - }; -}; - - -module.exports = parseLangs;
\ No newline at end of file diff --git a/lib/parse/lex.js b/lib/parse/lex.js deleted file mode 100644 index 3391acf..0000000 --- a/lib/parse/lex.js +++ /dev/null @@ -1,79 +0,0 @@ -var _ = require('lodash'); -var kramed = require('kramed'); - -var isExercise = require('./is_exercise'); -var isQuiz = require('./is_quiz'); - -// Split a page up into sections (lesson, exercises, ...) -function splitSections(nodes) { - var section = []; - - return _.reduce(nodes, function(sections, el) { - if(el.type === 'hr') { - sections.push(section); - section = []; - } else { - section.push(el); - } - - return sections; - }, []).concat([section]); // Add remaining nodes -} - -// What is the type of this section -function sectionType(nodes, idx) { - if(isExercise(nodes)) { - return 'exercise'; - } else if(isQuiz(nodes)) { - return 'quiz'; - } - - return 'normal'; -} - -// Generate a uniqueId to identify this section in our code -function sectionId(section, idx) { - return _.uniqueId('gitbook_'); -} - -function lexPage(src) { - // Lex file - var nodes = kramed.lexer(src); - - return _.chain(splitSections(nodes)) - .map(function(section, idx) { - // Detect section type - section.type = sectionType(section, idx); - return section; - }) - .map(function(section, idx) { - // Give each section an ID - section.id = sectionId(section, idx); - return section; - - }) - .filter(function(section) { - return !_.isEmpty(section); - }) - .reduce(function(sections, section) { - var last = _.last(sections); - - // Merge normal sections together - if(last && last.type === section.type && last.type === 'normal') { - last.push.apply(last, [{'type': 'hr'}].concat(section)); - } else { - // Add to list of sections - sections.push(section); - } - - return sections; - }, []) - .map(function(section) { - section.links = nodes.links; - return section; - }) - .value(); -} - -// Exports -module.exports = lexPage; diff --git a/lib/parse/navigation.js b/lib/parse/navigation.js deleted file mode 100644 index ae4eb9d..0000000 --- a/lib/parse/navigation.js +++ /dev/null @@ -1,64 +0,0 @@ -var _ = require('lodash'); - -// Cleans up an article/chapter object -// remove 'articles' attributes -function clean(obj) { - return obj && _.omit(obj, ['articles']); -} - -function flattenChapters(chapters) { - return _.reduce(chapters, function(accu, chapter) { - return accu.concat([clean(chapter)].concat(flattenChapters(chapter.articles))); - }, []); -} - -// Returns from a summary a map of -/* - { - "file/path.md": { - prev: ..., - next: ..., - }, - ... - } -*/ -function navigation(summary, files) { - // Support single files as well as list - files = _.isArray(files) ? files : (_.isString(files) ? [files] : null); - - // List of all navNodes - // Flatten chapters, then add in default README node if ndeeded etc ... - var navNodes = flattenChapters(summary.chapters); - var prevNodes = [null].concat(navNodes.slice(0, -1)); - var nextNodes = navNodes.slice(1).concat([null]); - - // 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]; - - // 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) { - return _.pick(mapping, files); - } - - return mapping; -} - - -// Exports -module.exports = navigation; diff --git a/lib/parse/page.js b/lib/parse/page.js deleted file mode 100644 index 5fb2081..0000000 --- a/lib/parse/page.js +++ /dev/null @@ -1,160 +0,0 @@ -var _ = require('lodash'); -var kramed = require('kramed'); -var hljs = require('highlight.js'); - -var lex = require('./lex'); -var renderer = require('./renderer'); - -var include = require('./include'); -var lnormalize = require('../utils/lang').normalize; - - - -// Render a section using our custom renderer -function render(section, _options) { - // Copy section - var links = section.links || {}; - section = _.toArray(section); - section.links = links; - - // Build options using defaults and our custom renderer - var options = _.extend({}, kramed.defaults, { - renderer: renderer(null, _options), - - // Synchronous highlighting with highlight.js - highlight: function (code, lang) { - if(!lang) return code; - - // Normalize lang - lang = lnormalize(lang); - - try { - return hljs.highlight(lang, code).value; - } catch(e) { } - - return code; - } - }); - - return kramed.parser(section, options); -} - -function quizQuestion(node) { - if (node.text) { - node.text = node.text.replace(/^([\[(])x([\])])/, "$1 $2"); - } else { - return node.replace(/^([\[(])x([\])])/, "$1 $2"); - } -} - -function parsePage(src, options) { - options = options || {}; - - // Lex if not already lexed - var parsed = { - lexed: (_.isArray(src) ? src : lex(include(src, options.includer || function() { return undefined; }))) - }; - parsed.sections = parsed.lexed.map(function(section) { - // Transform given type - if(section.type === 'exercise') { - var nonCodeNodes = _.reject(section, { - 'type': 'code' - }); - - var codeNodes = _.filter(section, { - 'type': 'code' - }); - - // Languages in code blocks - var langs = _.pluck(codeNodes, 'lang').map(lnormalize); - - // Check that they are all the same - var validLangs = _.all(_.map(langs, function(lang) { - return lang && lang === langs[0]; - })); - - // Main language - var lang = validLangs ? langs[0] : null; - - return { - id: section.id, - type: section.type, - content: render(nonCodeNodes, options), - lang: lang, - code: { - base: codeNodes[0].text, - solution: codeNodes[1].text, - validation: codeNodes[2].text, - // Context is optional - context: codeNodes[3] ? codeNodes[3].text : null, - } - }; - } else if (section.type === 'quiz') { - var quiz = [], question, foundFeedback = false; - var nonQuizNodes = section[0].type === 'paragraph' && section[1].type !== 'list_start' ? [section[0]] : []; - var quizNodes = section.slice(0); - quizNodes.splice(0, nonQuizNodes.length); - - for (var i = 0; i < quizNodes.length; i++) { - var node = quizNodes[i]; - - if (question && (((node.type === 'list_end' || node.type === 'blockquote_end') && i === quizNodes.length - 1) - || node.type === 'table' || (node.type === 'paragraph' && !foundFeedback))) { - quiz.push({ - base: render(question.questionNodes, options), - solution: render(question.solutionNodes, options), - feedback: render(question.feedbackNodes, options) - }); - } - - if (node.type === 'table' || (node.type === 'paragraph' && !foundFeedback)) { - question = { questionNodes: [], solutionNodes: [], feedbackNodes: [] }; - } - - if (node.type === 'blockquote_start') { - foundFeedback = true; - } else if (node.type === 'blockquote_end') { - foundFeedback = false; - } - - if (node.type === 'table') { - question.solutionNodes.push(_.cloneDeep(node)); - node.cells = node.cells.map(function(row) { - return row.map(quizQuestion); - }); - question.questionNodes.push(node); - } else if (!/blockquote/.test(node.type)) { - if (foundFeedback) { - question.feedbackNodes.push(node); - } else if (node.type === 'paragraph' || node.type === 'text'){ - question.solutionNodes.push(_.cloneDeep(node)); - quizQuestion(node); - question.questionNodes.push(node); - } else { - question.solutionNodes.push(node); - question.questionNodes.push(node); - } - } - } - - return { - id: section.id, - type: section.type, - content: render(nonQuizNodes, options), - quiz: quiz - }; - } - - // Render normal pages - return { - id: section.id, - type: section.type, - content: render(section, options) - }; - }); - - return parsed; -} - -// Exports -module.exports = parsePage; diff --git a/lib/parse/progress.js b/lib/parse/progress.js deleted file mode 100644 index 10a06d2..0000000 --- a/lib/parse/progress.js +++ /dev/null @@ -1,47 +0,0 @@ -var _ = require("lodash"); - -// Returns from a navigation and a current file, a snapshot of current detailed state -var calculProgress = function(navigation, current) { - var n = _.size(navigation); - var percent = 0, prevPercent = 0, currentChapter = null; - var done = true; - - var chapters = _.chain(navigation) - .map(function(nav, path) { - nav.path = path; - return nav; - }) - .map(function(nav, i) { - // Calcul percent - nav.percent = (i * 100) / Math.max((n - 1), 1); - - // Is it done - nav.done = done; - if (nav.path == current) { - currentChapter = nav; - percent = nav.percent; - done = false; - } else if (done) { - prevPercent = nav.percent; - } - - return nav; - }) - .value(); - - return { - // Previous percent - prevPercent: prevPercent, - - // Current percent - percent: percent, - - // List of chapter with progress - chapters: chapters, - - // Current chapter - current: currentChapter - }; -} - -module.exports = calculProgress;
\ No newline at end of file diff --git a/lib/parse/readme.js b/lib/parse/readme.js deleted file mode 100644 index 9d8f552..0000000 --- a/lib/parse/readme.js +++ /dev/null @@ -1,45 +0,0 @@ -var _ = require('lodash'); -var kramed = require('kramed'); -var textRenderer = require('kramed-text-renderer'); - -function extractFirstNode(nodes, nType) { - return _.chain(nodes) - .filter(function(node) { - return node.type == nType; - }) - .pluck("text") - .first() - .value(); -} - - -function parseReadme(src) { - var nodes, title, description; - var renderer = textRenderer(); - - // Parse content - nodes = kramed.lexer(src); - - title = extractFirstNode(nodes, "heading") || ''; - description = extractFirstNode(nodes, "paragraph") || ''; - - var convert = _.compose( - function(text) { - return _.unescape(text.replace(/(\r\n|\n|\r)/gm, "")); - }, - function(text) { - return kramed.parse(text, _.extend({}, kramed.defaults, { - renderer: renderer - })); - } - ); - - return { - title: convert(title), - description: convert(description) - }; -} - - -// Exports -module.exports = parseReadme; diff --git a/lib/parse/renderer.js b/lib/parse/renderer.js deleted file mode 100644 index 5b6a79d..0000000 --- a/lib/parse/renderer.js +++ /dev/null @@ -1,141 +0,0 @@ -var url = require('url'); -var _ = require('lodash'); -var inherits = require('util').inherits; -var links = require('../utils').links; -var kramed = require('kramed'); - -var rendererId = 0; - -function GitBookRenderer(options, extra_options) { - if(!(this instanceof GitBookRenderer)) { - return new GitBookRenderer(options, extra_options); - } - GitBookRenderer.super_.call(this, options); - - this._extra_options = extra_options; - this.quizRowId = 0; - this.id = rendererId++; - this.quizIndex = 0; -} -inherits(GitBookRenderer, kramed.Renderer); - -GitBookRenderer.prototype._unsanitized = function(href) { - var prot = ''; - try { - prot = decodeURIComponent(unescape(href)) - .replace(/[^\w:]/g, '') - .toLowerCase(); - - } catch (e) { - return true; - } - - if(prot.indexOf('javascript:') === 0) { - return true; - } - - return false; -}; - -GitBookRenderer.prototype.link = function(href, title, text) { - // Our "fixed" href - var _href = href; - - // Don't build if it looks malicious - if (this.options.sanitize && this._unsanitized(href)) { - return text; - } - - // Parsed version of the url - var parsed = url.parse(href); - var o = this._extra_options; - var extname = parsed.path? _.last(parsed.path.split(".")) : ""; - - // Relative link, rewrite it to point to github repo - if(links.isRelative(_href) && extname == "md") { - _href = links.toAbsolute(_href, o.dir || "./", o.outdir || "./"); - _href = _href.replace(".md", ".html"); - } - - // Generate HTML for link - var out = '<a href="' + _href + '"'; - // Title if no null - if (title) { - out += ' title="' + title + '"'; - } - // Target blank if external - if(parsed.protocol) { - out += ' target="_blank"'; - } - out += '>' + text + '</a>'; - return out; -}; - -GitBookRenderer.prototype.image = function(href, title, text) { - // Our "fixed" href - var _href = href; - - // Parsed version of the url - var parsed = url.parse(href); - - // Options - var o = this._extra_options; - - // Relative image, rewrite it depending output - if(links.isRelative(href) && o && o.dir && o.outdir) { - // o.dir: directory parent of the file currently in rendering process - // o.outdir: directory parent from the html output - - _href = links.toAbsolute(_href, o.dir, o.outdir); - } - - return GitBookRenderer.super_.prototype.image.call(this, _href, title, text); -}; - -GitBookRenderer.prototype.tablerow = function(content) { - this.quizRowId += 1; - return GitBookRenderer.super_.prototype.tablerow(content); -}; - -var fieldRegex = /^([(\[])([ x])[\])]/; -GitBookRenderer.prototype._createCheckboxAndRadios = function(text) { - var match = fieldRegex.exec(text); - if (!match) { - return text; - } - //fix radio input uncheck failed - var quizFieldName='quiz-row-' + this.id + '-' + this.quizRowId ; - var quizIdentifier = quizFieldName + '-' + this.quizIndex++; - var field = "<input name='" + quizFieldName + "' id='" + quizIdentifier + "' type='"; - field += match[1] === '(' ? "radio" : "checkbox"; - field += match[2] === 'x' ? "' checked/>" : "'/>"; - var splittedText = text.split(fieldRegex); - var length = splittedText.length; - var label = '<label class="quiz-label" for="' + quizIdentifier + '">' + splittedText[length - 1] + '</label>'; - return text.replace(fieldRegex, field).replace(splittedText[length - 1], label); -}; - -GitBookRenderer.prototype.tablecell = function(content, flags) { - return GitBookRenderer.super_.prototype.tablecell(this._createCheckboxAndRadios(content), flags); -}; - -GitBookRenderer.prototype.listitem = function(text) { - return GitBookRenderer.super_.prototype.listitem(this._createCheckboxAndRadios(text)); -}; - -GitBookRenderer.prototype.code = function(code, lang, escaped) { - return GitBookRenderer.super_.prototype.code.call( - this, - code, - lang, - escaped - ); -}; - -GitBookRenderer.prototype.heading = function(text, level, raw) { - var id = this.options.headerPrefix + raw.toLowerCase().replace(/[^\w -]+/g, '').replace(/ /g, '-'); - return '<h' + level + ' id="' + id + '">' + text + '</h' + level + '>\n'; -}; - -// Exports -module.exports = GitBookRenderer; diff --git a/lib/parse/summary.js b/lib/parse/summary.js deleted file mode 100644 index 2fdec8a..0000000 --- a/lib/parse/summary.js +++ /dev/null @@ -1,167 +0,0 @@ -var _ = require('lodash'); -var kramed = require('kramed'); - - -// 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 kramed 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); -} - -function skipSpace(nodes) { - return _.filter(nodes, function(node) { - return node && node.type != 'space'; - }); -} - -function correctLoose(nodes) { - return _.map(nodes, function(node) { - // Return normal nodes - if(!node || node.type != 'loose_item_start') { - return node - } - - // Correct loose items - node.type = 'list_item_start'; - - return node; - }) -} - -// Parses an Article or Chapter title -// supports extracting links -function parseTitle(src, nums) { - // Check if it's a link - var matches = kramed.InlineLexer.rules.link.exec(src); - - var level = nums.join('.'); - - // Not a link, return plain text - if(!matches) { - return { - title: src, - level: level, - path: null, - }; - } - - return { - title: matches[1], - level: level, - - // Normalize path - // 1. Convert Window's "\" to "/" - // 2. Remove leading "/" if exists - path: matches[2].replace(/\\/g, '/').replace(/^\/+/, ''), - }; -} - -function parseChapter(nodes, nums) { - // Convert single number to an array - nums = _.isArray(nums) ? nums : [nums]; - - return _.extend(parseTitle(_.first(nodes).text, nums), { - articles: _.map(listSplit(filterList(nodes), 'list_item_start', 'list_item_end'), function(nodes, i) { - return parseChapter(nodes, nums.concat(i + 1)); - }) - }); -} - -function defaultChapterList(chapterList) { - var first = _.first(chapterList); - - // Check if introduction node was specified in SUMMARY.md - if (first) { - var chapter = parseChapter(first, [0]); - - // Already have README node, we're good to go - if(chapter.path === 'README.md') { - return chapterList; - } - } - - // It wasn't specified, so add in default - return [ - [ { type: 'text', text: '[Introduction](README.md)' } ] - ].concat(chapterList); -} - -function listGroups(src) { - var nodes = kramed.lexer(src); - - // Get out groups of lists - return listSplit( - filterList(correctLoose(skipSpace(nodes))), - 'list_item_start', 'list_item_end' - ); -} - -function parseSummary(src) { - // Split out chapter sections - var chapters = defaultChapterList(listGroups(src)); - - return { - chapters: chapters.map(parseChapter) - }; -} - -function parseEntries (src) { - return listGroups(src).map(parseChapter); -} - - -// Exports -module.exports = parseSummary; -module.exports.entries = parseEntries; |