diff options
Diffstat (limited to 'lib/output/assets-inliner.js')
-rw-r--r-- | lib/output/assets-inliner.js | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/lib/output/assets-inliner.js b/lib/output/assets-inliner.js index 2156bef..fb348b4 100644 --- a/lib/output/assets-inliner.js +++ b/lib/output/assets-inliner.js @@ -1,6 +1,6 @@ -var _ = require('lodash'); var util = require('util'); var path = require('path'); +var crc = require('crc'); var FolderOutput = require('./folder'); var Promise = require('../utils/promise'); @@ -13,52 +13,50 @@ var DEFAULT_ASSETS_FOLDER = 'assets'; /* Utility mixin to inline all the assets in a book: - Outline <svg> tags - - Convert svg images as png - Download remote images + - Convert .svg images as png */ function AssetsInliner() { FolderOutput.apply(this, arguments); + + // Map of svg already converted + this.svgs = {}; + this.inlineSvgs = {}; + + // Map of images already downloaded + this.downloaded = {}; } util.inherits(AssetsInliner, FolderOutput); // Output a SVG buffer as a file AssetsInliner.prototype.onOutputSVG = function(page, svg) { this.log.debug.ln('output svg from', page.path); - var filename = _.uniqueId('svg_') + '.png'; // Convert svg buffer to a png file - return imagesUtil.convertSVGBufferToPNG(svg, this.resolve(filename)) + return this.convertSVGBuffer(svg) // Return relative path from the page - .thenResolve(function() { + .then(function(filename) { return page.relative('/' + filename); }); }; + // Output an image as a file AssetsInliner.prototype.onOutputImage = function(page, src) { var that = this; - var isSVG = false; - var ext = path.extname(src).toLowerCase(); - if (ext == '.svg') { - isSVG = false; - ext = '.png'; - } return Promise() - // Allocate a new file - .then(function() { - - return that. - }) - // Download file if external .then(function() { if (!location.isExternal(src)) return; - return fs.download(src, ) + return that.downloadAsset(src) + .then(function(_asset) { + src = '/' + _asset; + }); }) .then(function() { @@ -67,16 +65,69 @@ AssetsInliner.prototype.onOutputImage = function(page, src) { } // Convert SVG to PNG - var filename = _.uniqueId('svg_') + '.png'; - return imagesUtil.convertSVGToPNG(page.resolve(src), this.resolve(filename)) - .thenResolve('/' + filename); + return that.convertSVGFile(page.resolve(src)); }) // Return relative path from the page - .thenResolve(function(filename) { + .then(function(filename) { return page.relative('/' + filename); }); }; +// Download an asset if not already download; returns the output file +AssetsInliner.prototype.downloadAsset = function(src) { + if (this.downloaded[src]) return Promise(this.downloaded[src]); + + var that = this; + var ext = path.extname(src); + var hash = crc.crc32(src).toString(16); + + // Create new file + return this.createNewFile(DEFAULT_ASSETS_FOLDER, hash + ext) + .then(function(filename) { + that.downloaded[src] = filename; + + that.log.debug.ln('downloading asset', src); + return fs.download(src, filename) + .thenResolve(filename); + }); +}; + +// Convert a .svg into an .png +// Return the output filename for the .png +AssetsInliner.prototype.convertSVGFile = function(src) { + if (this.svgs[src]) return Promise(this.svgs[src]); + + var that = this; + var hash = crc.crc32(src).toString(16); + + // Create new file + return this.createNewFile(DEFAULT_ASSETS_FOLDER, hash + '.png') + .then(function(filename) { + that.svgs[src] = filename; + + return imagesUtil.convertSVGToPNG(src, that.resolve(filename)) + .thenResolve(filename); + }); +}; + +// Convert an inline svg into an .png +// Return the output filename for the .png +AssetsInliner.prototype.convertSVGBuffer = function(buf) { + var that = this; + var hash = crc.crc32(buf).toString(16); + + // Already converted? + if (this.inlineSvgs[hash]) return Promise(this.inlineSvgs[hash]); + + return this.createNewFile(DEFAULT_ASSETS_FOLDER, hash + '.png') + .then(function(filename) { + that.inlineSvgs[hash] = filename; + + return imagesUtil.convertSVGBufferToPNG(buf, that.resolve(filename)) + .thenResolve(filename); + }); +}; + module.exports = AssetsInliner; |