diff options
-rw-r--r-- | lib/backbone/file.js | 14 | ||||
-rw-r--r-- | lib/backbone/summary.js | 4 | ||||
-rw-r--r-- | lib/book.js | 6 | ||||
-rw-r--r-- | lib/config/index.js | 6 | ||||
-rw-r--r-- | lib/output.js | 2 | ||||
-rw-r--r-- | lib/page/index.js | 31 | ||||
-rw-r--r-- | lib/utils/path.js | 11 | ||||
-rw-r--r-- | test/page.js | 47 |
8 files changed, 89 insertions, 32 deletions
diff --git a/lib/backbone/file.js b/lib/backbone/file.js index a58063c..6c46d5e 100644 --- a/lib/backbone/file.js +++ b/lib/backbone/file.js @@ -7,7 +7,7 @@ function BackboneFile(book) { this.log = this.book.log; // Filename in the book - this.filename = ''; + this.path = ''; this.parser; _.bindAll(this); @@ -23,7 +23,7 @@ BackboneFile.prototype.parse = function() { // Return true if backbone file exists BackboneFile.prototype.exists = function() { - return Boolean(this.filename); + return Boolean(this.path); }; // Locate a backbone file, could be .md, .asciidoc, etc @@ -36,7 +36,7 @@ BackboneFile.prototype.locate = function() { .then(function(result) { if (!result) return; - that.filename = result.path; + that.path = result.path; that.parser = result.parser; }); }; @@ -44,15 +44,15 @@ BackboneFile.prototype.locate = function() { // Read and parse the file BackboneFile.prototype.load = function() { var that = this; - this.log.debug.ln('loading', this.type, ':', that.filename); + this.log.debug.ln('loading', this.type, ':', that.path); return this.locate() .then(function() { - if (!that.filename) return; + if (!that.path) return; - that.log.debug.ln(that.type, 'located at', that.filename); + that.log.debug.ln(that.type, 'located at', that.path); - return that.book.readFile(that.filename) + return that.book.readFile(that.path) // Parse it .then(function(content) { diff --git a/lib/backbone/summary.js b/lib/backbone/summary.js index 35f65e6..aa52104 100644 --- a/lib/backbone/summary.js +++ b/lib/backbone/summary.js @@ -23,7 +23,7 @@ function TOCArticle(summary, title, ref, articles, parent) { } var parts = url.parse(ref); - this.filename = parts.pathname; + this.path = parts.pathname; this.anchor = parts.hash; this.articles = _.map(articles || [], function(article) { @@ -42,7 +42,7 @@ TOCArticle.prototype.walk = function(iter) { // Return true if is pointing to a file TOCArticle.prototype.hasLocation = function() { - return Boolean(this.filename); + return Boolean(this.path); }; // Return true if has children diff --git a/lib/book.js b/lib/book.js index 148706c..8c0d39b 100644 --- a/lib/book.js +++ b/lib/book.js @@ -199,7 +199,7 @@ Book.prototype.parse = function() { // Index summary's articles that.summary.walk(function(article) { if (!article.hasLocation()) return; - that.addPage(article.filename); + that.addPage(article.path); }); }) @@ -210,9 +210,9 @@ Book.prototype.parse = function() { // Mark a filename as being parsable Book.prototype.addPage = function(filename) { - filename = pathUtil.normalize(filename); + if (this.hasPage(filename)) return this.getPage(filename); - if (this.pages[filename]) return; + filename = pathUtil.normalize(filename); this.pages[filename] = new Page(this, filename); return this.pages[filename]; }; diff --git a/lib/config/index.js b/lib/config/index.js index 563f03b..d83dae4 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -19,7 +19,7 @@ function Config(book, baseConfig) { this.book = book; this.fs = book.fs; this.log = book.log; - this.filename = null; + this.path = null; this.replace(baseConfig || {}); } @@ -37,7 +37,7 @@ Config.prototype.load = function() { return that.fs.loadAsObject(that.book.resolve(filename)) .then(function(_config) { - that.filename = filename; + that.path = filename; return that.replace(_config); }) .fail(function(err) { @@ -102,7 +102,7 @@ Config.prototype.replace = function(options) { // Return true if book has a configuration file Config.prototype.exists = function() { - return Boolean(this.filename); + return Boolean(this.path); }; // Return path to a structure file diff --git a/lib/output.js b/lib/output.js index b787edc..2ada022 100644 --- a/lib/output.js +++ b/lib/output.js @@ -27,7 +27,7 @@ function Output(book, type) { '.bookignore', // The configuration file should not be copied in the output - this.book.config.filename + this.book.config.path ])); } diff --git a/lib/page/index.js b/lib/page/index.js index e7a4fec..711e0e1 100644 --- a/lib/page/index.js +++ b/lib/page/index.js @@ -3,6 +3,7 @@ var path = require('path'); var parsers = require('gitbook-parsers'); var error = require('../utils/error'); +var pathUtil = require('../utils/path'); var HTMLPipeline = require('./html'); /* @@ -40,10 +41,25 @@ function Page(book, filename) { // Return the filename of the page with another extension // "README.md" -> "README.html" Page.prototype.withExtension = function(ext) { - return path.join( - path.dirname(this.path), - path.basename(this.path, path.extname(this.path)) + ext - ); + return pathUtil.setExtension(this.path, ext); +}; + +// Filename for output +// READMEs are replaced by index.html +Page.prototype.outputPath = function(ext) { + ext = ext || '.html'; + var output; + + if ( + path.basename(this.path, path.extname(this.path)) == 'README' || + output == this.book.readme.path + ) { + output = path.join(path.dirname(output), 'index'+ext); + } else { + output = pathUtil.setExtension(output, ext); + } + + return output; }; // Update content of the page @@ -107,8 +123,13 @@ Page.prototype.parse = function(opts) { // Normalize HTML output .then(function() { var pipelineOpts = _.extend({ + + // Replace links to page of summary onRelativeLink: function(href) { - console.log('href', href); + var to = that.book.getPage(href); + if (to) return to.outputPath(); + + return href; } }, opts); var pipeline = new HTMLPipeline(that.content, pipelineOpts); diff --git a/lib/utils/path.js b/lib/utils/path.js index f195d6c..c233c92 100644 --- a/lib/utils/path.js +++ b/lib/utils/path.js @@ -42,8 +42,17 @@ function resolveInRoot(root) { return result; } +// Chnage extension +function setExtension(filename, ext) { + return path.join( + path.dirname(filename), + path.basename(filename, path.extname(filename)) + ext + ); +} + module.exports = { isInRoot: isInRoot, resolveInRoot: resolveInRoot, - normalize: normalizePath + normalize: normalizePath, + setExtension: setExtension }; diff --git a/test/page.js b/test/page.js index 5f5c311..90a0260 100644 --- a/test/page.js +++ b/test/page.js @@ -5,29 +5,56 @@ describe('Page', function() { before(function() { return mock.setupDefaultBook({ - 'heading.md': '# Hello\n\n## World' + 'heading.md': '# Hello\n\n## World', + 'links.md': '[link](hello.md) [readme](README.md)' }) .then(function(_book) { book = _book; - return book.summary.load(); + return book.parse(); }); }); - it('should add a default ID to headings', function() { - var page = book.addPage('heading.md'); + describe('Headings', function() { + it('should add a default ID to headings', function() { + var page = book.addPage('heading.md'); - return page.parse() - .then(function() { + return page.parse() + .then(function() { + page.content.should.be.html({ + 'h1#hello': { + count: 1 + }, + 'h2#world': { + count: 1 + } + }); + }); + }); + }); + + describe('Links', function() { + var page; + + before(function() { + page = book.addPage('links.md'); + return page.parse(); + }); + + it('should replace links to page to .html', function() { page.content.should.be.html({ - 'h1#hello': { - count: 1 - }, - 'h2#world': { + 'a[href="index.html"]': { count: 1 } }); }); + it('should not replace links to file not in SUMMARY', function() { + page.content.should.be.html({ + 'a[href="hello.md"]': { + count: 1 + } + }); + }); }); });
\ No newline at end of file |