summaryrefslogtreecommitdiffstats
path: root/lib/utils
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2015-01-28 11:43:44 +0100
committerSamy Pessé <samypesse@gmail.com>2015-01-28 11:43:44 +0100
commit324fbb2f695a7efb012eb04e1184248cae960587 (patch)
tree516261eca635fe9eaa5563648e660c5538b4042c /lib/utils
parent5539ab48a5e4cc5a94c692f62f2e9dc55d6a4e49 (diff)
downloadgitbook-324fbb2f695a7efb012eb04e1184248cae960587.zip
gitbook-324fbb2f695a7efb012eb04e1184248cae960587.tar.gz
gitbook-324fbb2f695a7efb012eb04e1184248cae960587.tar.bz2
Convert svg images to png in ebook
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/fs.js22
-rw-r--r--lib/utils/images.js29
-rw-r--r--lib/utils/page.js75
3 files changed, 121 insertions, 5 deletions
diff --git a/lib/utils/fs.js b/lib/utils/fs.js
index 8d8c189..e434953 100644
--- a/lib/utils/fs.js
+++ b/lib/utils/fs.js
@@ -43,9 +43,27 @@ var fsUtils = {
},
existsSync: fs.existsSync.bind(fs),
readFileSync: fs.readFileSync.bind(fs),
- clean: cleanFolder
+ clean: cleanFolder,
+ getUniqueFilename: getUniqueFilename
}
+// Find a filename available
+function getUniqueFilename(base) {
+ var ext = path.extname(base);
+ base = path.join(path.dirname(base), path.basename(base, ext));
+
+ var filename = base+ext;
+
+ var i = 0;
+ while (1) {
+ if (!fs.existsSync(filename)) break;
+ filename = base+"_"+i+ext;
+ i = i + 1;
+ }
+
+ return filename;
+};
+
// List files in a directory
function listFiles(root, options) {
@@ -112,7 +130,7 @@ function cleanFolder(root) {
var _file = path.join(root, file);
d.notify({
- i: i,
+ i: i+1,
count: files.length,
file: _file
});
diff --git a/lib/utils/images.js b/lib/utils/images.js
new file mode 100644
index 0000000..5a39927
--- /dev/null
+++ b/lib/utils/images.js
@@ -0,0 +1,29 @@
+var _ = require("lodash");
+var Q = require("q");
+var fs = require("fs");
+var gm = require("gm");
+
+
+var convert = function(source, dest, options) {
+ var d = Q.defer();
+ options = _.defaults(options || {}, {
+ resize: null
+ });
+
+ var img = gm(source)
+ .options({
+ imageMagick: true
+ });
+
+ if (options.resize) img = img.resize(options.resize.w, options.resize.h);
+
+ img.noProfile()
+ .write(dest, d.makeNodeResolver());
+
+ return d.promise;
+};
+
+module.exports = {
+ convert: convert,
+ INVALID: [".svg"]
+};
diff --git a/lib/utils/page.js b/lib/utils/page.js
index 525722e..e526afb 100644
--- a/lib/utils/page.js
+++ b/lib/utils/page.js
@@ -1,8 +1,11 @@
+var Q = require('q');
var _ = require('lodash');
var path = require('path');
var cheerio = require('cheerio');
var links = require('./links');
+var imgUtils = require('./images');
+var fs = require('./fs');
function replaceText($, el, search, replace, text_only ) {
return $(el).each(function(){
@@ -61,6 +64,7 @@ function pregQuote( str ) {
// Adapt an html snippet to be relative to a base folder
function normalizeHtml(src, options) {
var $ = cheerio.load(src);
+ var toConvert = [];
$("img").each(function() {
var src = $(this).attr("src");
@@ -70,6 +74,31 @@ function normalizeHtml(src, options) {
src = links.toAbsolute(src, options.base, options.output);
}
+ // Convert if needed
+ if (options.convertImages) {
+ var ext = path.extname(src);
+ if (_.contains(imgUtils.INVALID, ext)) {
+ // Replace extension
+ var dest = path.join(path.dirname(src), path.basename(src, ext)+".png");
+
+ // Absolute with input
+ dest = path.resolve(options.book.root, dest);
+
+ // Get a name that doesn't exists
+ dest = fs.getUniqueFilename(dest);
+
+ // Reset as relative to book
+ dest = path.relative(options.book.root, dest);
+
+ options.book.log.debug.ln("detect invalid image (will be converted to png):", src);
+ toConvert.push({
+ source: src,
+ dest: dest
+ });
+ src = dest;
+ }
+ }
+
$(this).attr("src", src);
});
@@ -109,13 +138,40 @@ function normalizeHtml(src, options) {
});
});
- return $.html();
+ return {
+ html: $.html(),
+ images: toConvert
+ };
+};
+
+// Convert svg images to png
+function convertImages(images, options) {
+ return _.reduce(images, function(prev, image) {
+ return prev.then(function() {
+ var imgin = path.resolve(options.book.root, image.source);
+ var imgout = path.resolve(options.book.options.output, image.dest);
+
+ options.book.log.debug("convert image", image.source, "to", image.dest, "...");
+ return imgUtils.convert(imgin, imgout)
+ .then(function() {
+ options.book.log.debug.ok();
+ }, function() {
+ options.book.log.debug.fail();
+ });
+ });
+ }, Q());
};
// Adapt page content to be relative to a base folder
function normalizePage(sections, options) {
options = _.defaults(options || {}, {
+ // Current book
+ book: null,
+
+ // Do we need to convert svg?
+ convertImages: false,
+
// Current file path
input: ".",
@@ -132,11 +188,24 @@ function normalizePage(sections, options) {
glossary: []
});
- return _.map(sections, function(section) {
+ // List of images to convert
+ var toConvert = [];
+
+ sections = _.map(sections, function(section) {
if (section.type != "normal") return section;
- section.content = normalizeHtml(section.content, options);
+
+ var out = normalizeHtml(section.content, options);;
+
+ toConvert = toConvert.concat(out.images);
+ section.content = out.html;
return section;
});
+
+ return Q()
+ .then(function() {
+ return convertImages(toConvert, options);
+ })
+ .thenResolve(sections);
};
// Extract text from sections