diff options
-rw-r--r-- | lib/generator.js | 5 | ||||
-rw-r--r-- | lib/generators/json.js | 13 | ||||
-rw-r--r-- | lib/utils/links.js | 67 | ||||
-rw-r--r-- | lib/utils/page.js | 66 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | test/fixtures/test1/SUMMARY.md | 2 | ||||
-rw-r--r-- | test/fixtures/test1/sub/test1.md | 6 | ||||
-rw-r--r-- | test/generation.js | 6 | ||||
-rw-r--r-- | test/parsing.js | 5 |
9 files changed, 157 insertions, 14 deletions
diff --git a/lib/generator.js b/lib/generator.js index 58a9c79..fa6b8b0 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -83,9 +83,4 @@ BaseGenerator.prototype.finish = function() { return Q.reject(new Error("Could not finish generation")); }; -// Modify an extension from a path -BaseGenerator.prototype.changeExtension = function(filename, newext) { - return path.basename(filename, path.extname(filename))+newext; -} - module.exports = BaseGenerator; diff --git a/lib/generators/json.js b/lib/generators/json.js index 2e8c731..65197e0 100644 --- a/lib/generators/json.js +++ b/lib/generators/json.js @@ -5,7 +5,8 @@ var _ = require("lodash"); var fs = require("../utils/fs"); var BaseGenerator = require("../generator"); - +var links = require("../utils/links"); +var pageUtil = require("../utils/page"); var Generator = function() { BaseGenerator.apply(this, arguments); @@ -21,10 +22,14 @@ Generator.prototype.writeParsedFile = function(page, input) { var that = this; var json = { progress: page.progress, - sections: page.sections + sections: pageUtil.normalize(page.sections, { + navigation: that.book.navigation, + base: path.dirname(input) || './', + output: path.dirname(input) || './' + }) }; - var output = that.changeExtension(input, ".json"); + var output = links.changeExtension(input, ".json"); output = path.join(that.options.output, output); return fs.writeFile( @@ -41,7 +46,7 @@ Generator.prototype.langsIndex = function(langs) { if (langs.length == 0) return Q.reject("Need at least one language"); var mainLang = _.first(langs).lang; - var readme = that.changeExtension(that.book.readmeFile, ".json"); + var readme = links.changeExtension(that.book.readmeFile, ".json"); return Q() .then(function() { diff --git a/lib/utils/links.js b/lib/utils/links.js new file mode 100644 index 0000000..e607c94 --- /dev/null +++ b/lib/utils/links.js @@ -0,0 +1,67 @@ +var url = require('url'); +var path = require('path'); + +// Is the link an external link +var isExternal = function(href) { + try { + return Boolean(url.parse(href).protocol); + } catch(err) { } + + return false; +}; + +// Return true if the link is relative +var isRelative = function(href) { + try { + var parsed = url.parse(href); + + return !parsed.protocol && parsed.path && parsed.path[0] != '/'; + } catch(err) {} + + return true; +}; + +// Relative to absolute path +// dir: directory parent of the file currently in rendering process +// outdir: directory parent from the html output + +var toAbsolute = function(_href, dir, outdir) { + // Absolute file in source + _href = path.join(dir, _href); + + // make it relative to output + _href = path.relative(outdir, _href); + + if (process.platform === 'win32') { + _href = _href.replace(/\\/g, '/'); + } + + return _href; +}; + +// Join links +var join = function() { + var _href = path.join.apply(path, arguments); + + if (process.platform === 'win32') { + _href = _href.replace(/\\/g, '/'); + } + + return _href; +}; + +// Change extension +var changeExtension = function(filename, newext) { + return path.join( + path.dirname(filename), + path.basename(filename, path.extname(filename))+newext + ); +}; + +module.exports = { + isRelative: isRelative, + isExternal: isExternal, + toAbsolute: toAbsolute, + join: join, + changeExtension: changeExtension +}; diff --git a/lib/utils/page.js b/lib/utils/page.js new file mode 100644 index 0000000..00e4757 --- /dev/null +++ b/lib/utils/page.js @@ -0,0 +1,66 @@ +var _ = require('lodash'); +var path = require('path'); +var cheerio = require('cheerio'); + +var links = require('./links'); + +// Adapt an html snippet to be relative to a base folder +function normalizeHtml(src, options) { + var $ = cheerio.load(src); + + $("img").each(function() { + var src = $(this).attr("src"); + + // Transform as absolute + if (links.isRelative(src)) { + src = links.toAbsolute(src, options.base, options.output); + } + + $(this).attr("src", src); + }); + + $("a").each(function() { + var href = $(this).attr("href"); + + if (links.isRelative(href)) { + var absolutePath = path.join(options.base, href); + + // If is in navigation relative: change extsnio nto be .html + if (options.navigation[absolutePath]) href = links.changeExtension(href, ".html"); + + // Transform as absolute + href = links.toAbsolute(href, options.base, options.output); + } else { + $(this).attr("target", "_blank"); + } + + // Transform extension + $(this).attr("href", href); + }); + + return $.html(); +}; + +// Adapt page content to be relative to a base folder +function normalizePage(sections, options) { + options = _.defaults(options || {}, { + // Navigation to use to transform path + navigation: {}, + + // Directory parent of the file currently in rendering process + base: "./", + + // Directory parent from the html output + output: "./" + }); + + return _.map(sections, function(section) { + if (section.type != "normal") return section; + section.content = normalizeHtml(section.content, options); + return section; + }); +}; + +module.exports = { + normalize: normalizePage +}; diff --git a/package.json b/package.json index 11ef3fd..53d375c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "nunjucks": "git+https://github.com/SamyPesse/nunjucks.git#4019d1b7379372336b86ce1b0bf84352a2029747", "semver": "2.2.1", "npmi": "0.1.1", + "cheerio": "0.18.0", "gitbook-plugin-mathjax": "0.0.6", "gitbook-plugin-livereload": "0.0.1" }, diff --git a/test/fixtures/test1/SUMMARY.md b/test/fixtures/test1/SUMMARY.md index 4adaf3e..4a87f8c 100644 --- a/test/fixtures/test1/SUMMARY.md +++ b/test/fixtures/test1/SUMMARY.md @@ -1,6 +1,6 @@ # Summary * [Chapter 1](test.md) - * [Article 1](test1.md) + * [Article 1](sub/test1.md) * [Chapter 2](test2.md) diff --git a/test/fixtures/test1/sub/test1.md b/test/fixtures/test1/sub/test1.md new file mode 100644 index 0000000..6a6e788 --- /dev/null +++ b/test/fixtures/test1/sub/test1.md @@ -0,0 +1,6 @@ +# This file is used to etst links transformations: + +This is a relative link [test](../intro.md). + + + diff --git a/test/generation.js b/test/generation.js index b043885..d339837 100644 --- a/test/generation.js +++ b/test/generation.js @@ -24,7 +24,11 @@ describe('Book generation', function () { it('should correctly generate a book to json', function(done) { testGeneration(book1, "json", function(output) { assert(!fs.existsSync(path.join(output, "README.json"))); - assert(fs.existsSync(path.join(output, "intro.json"))) + assert(fs.existsSync(path.join(output, "intro.json"))); + assert(fs.existsSync(path.join(output, "sub/test1.json"))); + + var test1 = JSON.parse(fs.readFileSync(path.join(output, "sub/test1.json"))); + assert(test1.sections[0].content.indexOf("intro.html") > 0); }, done); }); diff --git a/test/parsing.js b/test/parsing.js index 477631f..4e76d2c 100644 --- a/test/parsing.js +++ b/test/parsing.js @@ -31,8 +31,7 @@ describe('Book parsing', function () { it('should correctly parse list of files', function() { var FILES = book1.files; - assert.equal(FILES.length, 2); - assert.equal(_.difference(FILES, [ 'intro.md', 'README.md' ]).length, 0); + assert.deepEqual(FILES, [ 'README.md', 'intro.md', 'sub/', 'sub/test1.md' ]); }); it('should correctly parse the languages', function() { @@ -49,7 +48,7 @@ describe('Book parsing', function () { it('should correctly parse the navigation', function() { var NAVIGATION = book1.navigation; - assert.equal(_.size(NAVIGATION), 1); + assert.equal(_.size(NAVIGATION), 2); assert(NAVIGATION["intro.md"]) assert.equal(NAVIGATION["intro.md"].title, "Introduction"); assert.equal(NAVIGATION["intro.md"].prev, null); |