diff options
Diffstat (limited to 'lib/backbone/summary.js')
-rw-r--r-- | lib/backbone/summary.js | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/lib/backbone/summary.js b/lib/backbone/summary.js deleted file mode 100644 index 2dbcecb..0000000 --- a/lib/backbone/summary.js +++ /dev/null @@ -1,349 +0,0 @@ -var _ = require('lodash'); -var util = require('util'); - -var location = require('../utils/location'); -var error = require('../utils/error'); -var BackboneFile = require('./file'); - -/* - An article represent an entry in the Summary. - It's defined by a title, a reference, and children articles, - the reference (ref) can be a filename + anchor or an external file (optional) -*/ -function TOCArticle(def, parent) { - // Title - this.title = def.title; - - // Parent TOCPart or TOCArticle - this.parent = parent; - - // As string indicating the overall position - // ex: '1.0.0' - this.level; - this._next; - this._prev; - - // When README has been automatically added - this.isAutoIntro = def.isAutoIntro; - this.isIntroduction = def.isIntroduction; - - this.validate(); - - // Path can be a relative path or an url, or nothing - this.ref = def.path; - if (this.ref && !this.isExternal()) { - var parts = this.ref.split('#'); - this.path = (parts.length > 1? parts.slice(0, -1).join('#') : this.ref); - this.anchor = (parts.length > 1? '#' + _.last(parts) : null); - - // Normalize path to remove ('./', etc) - this.path = location.normalize(this.path); - } - - this.articles = _.map(def.articles || [], function(article) { - if (article instanceof TOCArticle) return article; - return new TOCArticle(article, this); - }, this); -} - -// Validate the article -TOCArticle.prototype.validate = function() { - if (!this.title) { - throw error.ParsingError(new Error('SUMMARY entries should have an non-empty title')); - } -}; - -// Iterate over all articles in this articles -TOCArticle.prototype.walk = function(iter, base) { - base = base || this.level; - - _.each(this.articles, function(article, i) { - var level = levelId(base, i); - - if (iter(article, level) === false) { - return false; - } - article.walk(iter, level); - }); -}; - -// Return templating context for an article -TOCArticle.prototype.getContext = function() { - return { - level: this.level, - title: this.title, - depth: this.depth(), - path: this.isExternal()? undefined : this.path, - anchor: this.isExternal()? undefined : this.anchor, - url: this.isExternal()? this.ref : undefined - }; -}; - -// Return true if is pointing to a file -TOCArticle.prototype.hasLocation = function() { - return Boolean(this.path); -}; - -// Return true if is pointing to an external location -TOCArticle.prototype.isExternal = function() { - return location.isExternal(this.ref); -}; - -// Return true if this article is the introduction -TOCArticle.prototype.isIntro = function() { - return Boolean(this.isIntroduction); -}; - -// Return true if has children -TOCArticle.prototype.hasChildren = function() { - return this.articles.length > 0; -}; - -// Return true if has an article as parent -TOCArticle.prototype.hasParent = function() { - return !(this.parent instanceof TOCPart); -}; - -// Return depth of this article -TOCArticle.prototype.depth = function() { - return this.level.split('.').length; -}; - -// Return next article in the TOC -TOCArticle.prototype.next = function() { - return this._next; -}; - -// Return previous article in the TOC -TOCArticle.prototype.prev = function() { - return this._prev; -}; - -// Map over all articles -TOCArticle.prototype.map = function(iter) { - return _.map(this.articles, iter); -}; - - -/* - A part of a ToC is a composed of a tree of articles and an optiona title -*/ -function TOCPart(part, parent) { - if (!(this instanceof TOCPart)) return new TOCPart(part, parent); - - TOCArticle.apply(this, arguments); -} -util.inherits(TOCPart, TOCArticle); - -// Validate the part -TOCPart.prototype.validate = function() { }; - -// Return a sibling (next or prev) of this part -TOCPart.prototype.sibling = function(direction) { - var parts = this.parent.parts; - var pos = _.findIndex(parts, this); - - if (parts[pos + direction]) { - return parts[pos + direction]; - } - - return null; -}; - -// Iterate over all entries of the part -TOCPart.prototype.walk = function(iter, base) { - var articles = this.articles; - - if (articles.length == 0) return; - - // Has introduction? - if (articles[0].isIntro()) { - if (iter(articles[0], '0') === false) { - return; - } - - articles = articles.slice(1); - } - - - _.each(articles, function(article, i) { - var level = levelId(base, i); - - if (iter(article, level) === false) { - return false; - } - - article.walk(iter, level); - }); -}; - -// Return templating context for a part -TOCPart.prototype.getContext = function(onArticle) { - onArticle = onArticle || function(article) { - return article.getContext(); - }; - - return { - title: this.title, - articles: this.map(onArticle) - }; -}; - -/* -A summary is composed of a list of parts, each composed wit a tree of articles. -*/ -function Summary() { - BackboneFile.apply(this, arguments); - - this.parts = []; - this._length = 0; -} -util.inherits(Summary, BackboneFile); - -Summary.prototype.type = 'summary'; - -// Prepare summary when non existant -Summary.prototype.parseNotFound = function() { - this.update([]); -}; - -// Parse the summary content -Summary.prototype.parse = function(content) { - var that = this; - - return this.parser.summary(content) - - .then(function(summary) { - that.update(summary.parts); - }); -}; - -// Return templating context for the summary -Summary.prototype.getContext = function() { - function onArticle(article) { - var result = article.getContext(); - if (article.hasChildren()) { - result.articles = article.map(onArticle); - } - - return result; - } - - return { - summary: { - path: this.path, - parts: _.map(this.parts, function(part) { - return part.getContext(onArticle); - }) - } - }; -}; - -// Iterate over all entries of the summary -// iter is called with an TOCArticle -Summary.prototype.walk = function(iter) { - var hasMultipleParts = this.parts.length > 1; - - _.each(this.parts, function(part, i) { - part.walk(iter, hasMultipleParts? levelId('', i) : null); - }); -}; - -// Find a specific article using a filter -Summary.prototype.find = function(filter) { - var result; - - this.walk(function(article) { - if (filter(article)) { - result = article; - return false; - } - }); - - return result; -}; - -// Flatten the list of articles -Summary.prototype.flatten = function() { - var result = []; - - this.walk(function(article) { - result.push(article); - }); - - return result; -}; - -// Return the first TOCArticle for a specific page (or path) -Summary.prototype.getArticle = function(page) { - if (!_.isString(page)) page = page.path; - - return this.find(function(article) { - return article.path == page; - }); -}; - -// Return the first TOCArticle for a specific level -Summary.prototype.getArticleByLevel = function(lvl) { - return this.find(function(article) { - return article.level == lvl; - }); -}; - -// Return the count of articles in the summary -Summary.prototype.count = function() { - return this._length; -}; - -// Prepare the summary -Summary.prototype.update = function(parts) { - var that = this; - - - that.parts = _.map(parts, function(part) { - return new TOCPart(part, that); - }); - - // Create first part if none - if (that.parts.length == 0) { - that.parts.push(new TOCPart({}, that)); - } - - // Add README as first entry - var firstArticle = that.parts[0].articles[0]; - if (!firstArticle || firstArticle.path != that.book.readme.path) { - that.parts[0].articles.unshift(new TOCArticle({ - title: 'Introduction', - path: that.book.readme.path, - isAutoIntro: true - }, that.parts[0])); - } - that.parts[0].articles[0].isIntroduction = true; - - - // Update the count and indexing of "level" - var prev = undefined; - - that._length = 0; - that.walk(function(article, level) { - // Index level - article.level = level; - - // Chain articles - article._prev = prev; - if (prev) prev._next = article; - - prev = article; - - that._length += 1; - }); -}; - - -// Return a level string from a base level and an index -function levelId(base, i) { - i = i + 1; - return (base? [base || '', i] : [i]).join('.'); -} - -module.exports = Summary; |