summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/generator.js5
-rw-r--r--lib/generators/json.js13
-rw-r--r--lib/utils/links.js67
-rw-r--r--lib/utils/page.js66
-rw-r--r--package.json1
-rw-r--r--test/fixtures/test1/SUMMARY.md2
-rw-r--r--test/fixtures/test1/sub/test1.md6
-rw-r--r--test/generation.js6
-rw-r--r--test/parsing.js5
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).
+
+![image](../image.png)
+
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);