mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 10:03:31 +00:00
Download external images in ebook format
This commit is contained in:
+12
-6
@@ -70,20 +70,26 @@ function writeStream(filename, st) {
|
||||
}
|
||||
|
||||
// Find a filename available
|
||||
function getUniqueFilename(base) {
|
||||
var ext = path.extname(base);
|
||||
base = path.join(path.dirname(base), path.basename(base, ext));
|
||||
function getUniqueFilename(base, filename) {
|
||||
if (!filename) {
|
||||
filename = base;
|
||||
base = "/";
|
||||
}
|
||||
|
||||
var filename = base+ext;
|
||||
filename = path.resolve(base, filename);
|
||||
var ext = path.extname(filename);
|
||||
filename = path.join(path.dirname(filename), path.basename(filename, ext));
|
||||
|
||||
var _filename = filename+ext;
|
||||
|
||||
var i = 0;
|
||||
while (1) {
|
||||
if (!fs.existsSync(filename)) break;
|
||||
filename = base+"_"+i+ext;
|
||||
_filename = filename+"_"+i+ext;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return filename;
|
||||
return path.relative(base, _filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-18
@@ -2,12 +2,11 @@ var _ = require("lodash");
|
||||
var Q = require("q");
|
||||
var fs = require("./fs");
|
||||
var exec = require('child_process').exec;
|
||||
var request = require("request");
|
||||
|
||||
var links = require("./links");
|
||||
|
||||
// Convert a svg file
|
||||
var convertSVGFile = function(source, dest, options) {
|
||||
var convertSVG = function(source, dest, options) {
|
||||
if (!fs.existsSync(source)) return Q.reject(new Error("File doesn't exist: "+source));
|
||||
|
||||
var d = Q.defer();
|
||||
@@ -29,22 +28,6 @@ var convertSVGFile = function(source, dest, options) {
|
||||
return d.promise;
|
||||
};
|
||||
|
||||
// Convert a svg file or url
|
||||
var convertSVG = function(source, dest, options) {
|
||||
if (!links.isExternal(source)) return convertSVGFile(source, dest, options);
|
||||
|
||||
return fs.tmp.file({ postfix: '.svg' })
|
||||
|
||||
// Download file
|
||||
.then(function(tmpfile) {
|
||||
return fs.writeStream(tmpfile, request(source))
|
||||
.thenResolve(tmpfile);
|
||||
})
|
||||
.then(function(tmpfile) {
|
||||
return convertSVGFile(tmpfile, dest, options);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
convertSVG: convertSVG,
|
||||
INVALID: [".svg"]
|
||||
|
||||
@@ -84,6 +84,16 @@ module.exports = function(_write, logLevel) {
|
||||
logger[levelKey].ln = _.partial(logger.logLn, level);
|
||||
logger[levelKey].ok = _.partial(logger.ok, level);
|
||||
logger[levelKey].fail = _.partial(logger.fail, level);
|
||||
logger[levelKey].promise = function(p) {
|
||||
return p.
|
||||
then(function(st) {
|
||||
logger[levelKey].ok();
|
||||
return st;
|
||||
}, function(err) {
|
||||
logger[levelKey].fail();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return logger;
|
||||
|
||||
+35
-29
@@ -2,6 +2,7 @@ var Q = require('q');
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var cheerio = require('cheerio');
|
||||
var request = require('request');
|
||||
|
||||
var links = require('./links');
|
||||
var imgUtils = require('./images');
|
||||
@@ -81,9 +82,7 @@ function normalizeHtml(src, options) {
|
||||
var dest = svgId+".svg";
|
||||
|
||||
// Generate filename
|
||||
dest = path.resolve(outputRoot, dest);
|
||||
dest = fs.getUniqueFilename(dest);
|
||||
dest = "/"+path.relative(outputRoot, dest);
|
||||
dest = "/"+fs.getUniqueFilename(outputRoot, dest);
|
||||
|
||||
svgContent[dest] = content;
|
||||
$(this).replaceWith($("<img>").attr("src", dest));
|
||||
@@ -92,6 +91,7 @@ function normalizeHtml(src, options) {
|
||||
|
||||
// Find images to normalize
|
||||
$("img").each(function() {
|
||||
var origin = undefined;
|
||||
var src = $(this).attr("src");
|
||||
var isExternal = links.isExternal(src);
|
||||
|
||||
@@ -102,12 +102,19 @@ function normalizeHtml(src, options) {
|
||||
|
||||
// Convert if needed
|
||||
if (options.convertImages) {
|
||||
// If image is external and ebook, then downlaod the images
|
||||
if (isExternal) {
|
||||
origin = src;
|
||||
src = "/"+fs.getUniqueFilename(outputRoot, path.basename(src));
|
||||
src = links.toAbsolute(src, options.base, options.output);
|
||||
isExternal = false;
|
||||
}
|
||||
|
||||
var ext = path.extname(src);
|
||||
var srcAbs = path.join("/", options.base, src);
|
||||
|
||||
// Test image extension
|
||||
if (_.contains(imgUtils.INVALID, ext)) {
|
||||
var srcAbs = isExternal? src : path.join("/", options.base, src);
|
||||
|
||||
if (imgConversionCache[outputRoot][srcAbs]) {
|
||||
// Already converted
|
||||
src = imgConversionCache[outputRoot][srcAbs];
|
||||
@@ -116,21 +123,11 @@ function normalizeHtml(src, options) {
|
||||
var dest = "";
|
||||
|
||||
// Replace extension
|
||||
if (isExternal) {
|
||||
dest = path.basename(srcAbs, ext)+".png";
|
||||
} else {
|
||||
dest = path.join(path.dirname(srcAbs), path.basename(srcAbs, ext)+".png");
|
||||
dest = dest[0] == "/"? dest.slice(1) : dest;
|
||||
}
|
||||
|
||||
// Absolute with input
|
||||
dest = path.resolve(outputRoot, dest);
|
||||
dest = path.join(path.dirname(srcAbs), path.basename(srcAbs, ext)+".png");
|
||||
dest = dest[0] == "/"? dest.slice(1) : dest;
|
||||
|
||||
// Get a name that doesn't exists
|
||||
dest = fs.getUniqueFilename(dest);
|
||||
|
||||
// Reset as relative to book
|
||||
dest = path.relative(outputRoot, dest);
|
||||
dest = fs.getUniqueFilename(outputRoot, dest);
|
||||
|
||||
options.book.log.debug.ln("detect invalid image (will be converted to png):", srcAbs);
|
||||
|
||||
@@ -139,6 +136,7 @@ function normalizeHtml(src, options) {
|
||||
|
||||
// Push to convert
|
||||
toConvert.push({
|
||||
origin: origin,
|
||||
content: svgContent[srcAbs],
|
||||
source: isExternal? srcAbs : path.join("./", srcAbs),
|
||||
dest: path.join("./", dest)
|
||||
@@ -150,6 +148,14 @@ function normalizeHtml(src, options) {
|
||||
// Reset as relative to output
|
||||
src = links.toAbsolute(src, options.base, options.output);
|
||||
}
|
||||
|
||||
else if (origin) {
|
||||
// Need to downlaod image
|
||||
toConvert.push({
|
||||
origin: origin,
|
||||
source: path.join("./", srcAbs)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(this).attr("src", src);
|
||||
@@ -204,29 +210,29 @@ function convertImages(images, options) {
|
||||
options.book.log.info.ln("convert ", images.length, "images to png");
|
||||
|
||||
return _.reduce(images, function(prev, image) {
|
||||
var imgin = links. isExternal(image.source)? image.source : path.resolve(options.book.options.output, image.source);
|
||||
var imgout = path.resolve(options.book.options.output, image.dest);
|
||||
var imgin = path.resolve(options.book.options.output, image.source);
|
||||
|
||||
return prev
|
||||
|
||||
// Write image if need to be download
|
||||
.then(function() {
|
||||
if (!image.origin) return;
|
||||
options.book.log.info("download image", image.origin);
|
||||
return options.book.log.info.promise(fs.writeStream(imgin, request(image.origin)));
|
||||
})
|
||||
|
||||
// Write svg if content
|
||||
.then(function() {
|
||||
if (!image.content) return;
|
||||
|
||||
return fs.writeFile(imgin, image.content);
|
||||
})
|
||||
|
||||
// Convert
|
||||
.then(function(){
|
||||
if (!image.dest) return;
|
||||
var imgout = path.resolve(options.book.options.output, image.dest);
|
||||
options.book.log.debug("convert image", image.source, "to", image.dest, "...");
|
||||
|
||||
return imgUtils.convertSVG(imgin, imgout)
|
||||
.then(function() {
|
||||
options.book.log.debug.ok();
|
||||
}, function(err) {
|
||||
options.book.log.debug.fail();
|
||||
throw err;
|
||||
});
|
||||
return options.book.log.debug.promise(imgUtils.convertSVG(imgin, imgout));
|
||||
});
|
||||
}, Q())
|
||||
.then(function() {
|
||||
|
||||
@@ -18,6 +18,10 @@ describe('eBook Generator', function () {
|
||||
var readmeContent = fs.readFileSync(path.join(output, "index.html"), {encoding: "utf8"});
|
||||
var pageContent = fs.readFileSync(path.join(output, "sub/PAGE.html"), {encoding: "utf8"});
|
||||
|
||||
// Remote image
|
||||
assert(pageContent.indexOf('src="../Tux.png"') >= 0);
|
||||
assert(fs.existsSync(path.join(output, "Tux.png")));
|
||||
|
||||
assert(fs.existsSync(path.join(output, "test.png")));
|
||||
assert(fs.existsSync(path.join(output, "NewTux.png")));
|
||||
|
||||
|
||||
Vendored
+6
-1
@@ -1,9 +1,10 @@
|
||||
##
|
||||
|
||||
## Image from root page
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Inline svg
|
||||
|
||||
{% html %}
|
||||
@@ -11,3 +12,7 @@
|
||||
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
|
||||
</svg>
|
||||
{% endhtml %}
|
||||
|
||||
## Remote image
|
||||
|
||||

|
||||
|
||||
Reference in New Issue
Block a user