diff options
-rw-r--r-- | cf33a0ef.svg | 259 | ||||
-rw-r--r-- | lib/output/assets-inliner.js | 4 | ||||
-rw-r--r-- | lib/output/base.js | 26 | ||||
-rw-r--r-- | lib/output/folder.js | 17 | ||||
-rw-r--r-- | lib/utils/fs.js | 9 | ||||
-rw-r--r-- | test/assets-inliner.js | 82 |
6 files changed, 351 insertions, 46 deletions
diff --git a/cf33a0ef.svg b/cf33a0ef.svg new file mode 100644 index 0000000..e4b7e58 --- /dev/null +++ b/cf33a0ef.svg @@ -0,0 +1,259 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 100 100"> + + <title>SVG Logo</title> + + <a xlink:href="http://www.w3.org/Graphics/SVG/" target="_parent" + xlink:title="W3C SVG Working Group home page"> + + <rect + id="background" + fill="#FF9900" + width="100" + height="100" + rx="4" + ry="4"/> + + <rect + id="top-left" + fill="#FFB13B" + width="50" + height="50" + rx="4" + ry="4"/> + + <rect + id="bottom-right" + x="50" + y="50" + fill="#DE8500" + width="50" + height="50" + rx="4" + ry="4"/> + + <g id="circles" fill="#FF9900"> + <circle + id="n" + cx="50" + cy="18.4" + r="18.4"/> + + <circle + id="ne" + cx="72.4" + cy="27.6" + r="18.4"/> + + <circle + id="e" + cx="81.6" + cy="50" + r="18.4"/> + + <circle + id="se" + cx="72.4" + cy="72.4" + r="18.4"/> + + <circle + id="s" + cx="50" + cy="81.6" + r="18.4"/> + + <circle + id="sw" + cx="27.6" + cy="72.4" + r="18.4"/> + + <circle + id="w" + cx="18.4" + cy="50" + r="18.4"/> + + <circle + id="nw" + cx="27.6" + cy="27.6" + r="18.4"/> + </g> + + <g id="stars"> + <path + id="black-star" + d="M 63.086, 18.385 + c 0.000, -7.227 -5.859,-13.086 -13.100,-13.086 + c -7.235, 0.000 -13.096, 5.859 -13.096, 13.086 + c -5.100, -5.110 -13.395, -5.110 -18.497, 0.000 + c -5.119, 5.120 -5.119, 13.408 0.000, 18.524 + c -7.234, 0.000 -13.103, 5.859 -13.103, 13.085 + c 0.000, 7.230 5.870, 13.098 13.103, 13.098 + c -5.119, 5.110 -5.119, 13.395 0.000, 18.515 + c 5.102, 5.104 13.397, 5.104 18.497, 0.000 + c 0.000, 7.228 5.860, 13.083 13.096, 13.083 + c 7.240, 0.000 13.100, -5.855 13.100,-13.083 + c 5.118, 5.104 13.416, 5.104 18.513, 0.000 + c 5.101, -5.120 5.101,-13.410 0.000,-18.515 + c 7.216, 0.000 13.081, -5.869 13.081,-13.098 + c 0.000, -7.227 -5.865,-13.085 -13.081,-13.085 + c 5.101, -5.119 5.101,-13.406 0.000,-18.524 + C 76.502, 13.275 68.206, 13.275 63.086, 18.385 z"/> + + <path + id="white-star" + fill="#FFFFFF" + d="M 55.003, 23.405 + v 14.488 + L 65.260, 27.640 + c 0.000, -1.812 0.691,-3.618 2.066, -5.005 + c 2.780, -2.771 7.275,-2.771 10.024, 0.000 + c 2.771, 2.766 2.771, 7.255 0.000, 10.027 + c -1.377, 1.375 -3.195, 2.072 -5.015, 2.072 + L 62.101, 44.982 + H 76.590 + c 1.290, -1.280 3.054,-2.076 5.011, -2.076 + c 3.900, 0.000 7.078, 3.179 7.078, 7.087 + c 0.000, 3.906 -3.178, 7.088 -7.078, 7.088 + c -1.957, 0.000 -3.721,-0.798 -5.011, -2.072 + H 62.100 + l 10.229, 10.244 + c 1.824, 0.000 3.642, 0.694 5.015, 2.086 + c 2.774, 2.759 2.774, 7.250 0.000, 10.010 + c -2.750, 2.774 -7.239, 2.774 -10.025, 0.000 + c -1.372, -1.372 -2.064,-3.192 -2.064, -5.003 + L 55.000, 62.094 + v 14.499 + c 1.271, 1.276 2.084, 3.054 2.084, 5.013 + c 0.000, 3.906 -3.177, 7.077 -7.098, 7.077 + c -3.919, 0.000 -7.094,-3.167 -7.094, -7.077 + c 0.000, -1.959 0.811,-3.732 2.081, -5.013 + V 62.094 + L 34.738, 72.346 + c 0.000, 1.812 -0.705, 3.627 -2.084, 5.003 + c -2.769, 2.772 -7.251, 2.772 -10.024, 0.000 + c -2.775, -2.764 -2.775,-7.253 0.000,-10.012 + c 1.377, -1.390 3.214,-2.086 5.012, -2.086 + l 10.257,-10.242 + H 23.414 + c -1.289, 1.276 -3.072, 2.072 -5.015, 2.072 + c -3.917, 0.000 -7.096,-3.180 -7.096, -7.088 + s 3.177, -7.087 7.096,-7.087 + c 1.940, 0.000 3.725, 0.796 5.015, 2.076 + h 14.488 + L 27.646, 34.736 + c -1.797, 0.000 -3.632,-0.697 -5.012, -2.071 + c -2.775, -2.772 -2.775,-7.260 0.000,-10.027 + c 2.773, -2.771 7.256,-2.771 10.027, 0.000 + c 1.375, 1.386 2.083, 3.195 2.083, 5.005 + l 10.235, 10.252 + V 23.407 + c -1.270, -1.287 -2.082,-3.053 -2.082, -5.023 + c 0.000, -3.908 3.175,-7.079 7.096, -7.079 + c 3.919, 0.000 7.097, 3.168 7.097, 7.079 + C 57.088, 20.356 56.274,22.119 55.003, 23.405 z"/> + </g> + + <g id="svg-textbox"> + <path + id="text-backdrop" + fill="black" + d="M 5.30,50.00 + H 94.68 + V 90.00 + Q 94.68,95.00 89.68,95.00 + H 10.30 + Q 5.30,95.00 5.30,90.00 Z"/> + + <path + id="shine" + fill="#3F3F3F" + d="M 14.657,54.211 + h 71.394 + c 2.908, 0.000 5.312, 2.385 5.312, 5.315 + v 17.910 + c -27.584,-3.403 -54.926,-8.125 -82.011,-7.683 + V 59.526 + C 9.353,56.596 11.743,54.211 14.657,54.211 + L 14.657,54.211 z"/> + + <g id="svg-text"> + <title>SVG</title> + <path + id="S" + fill="#FFFFFF" + stroke="#000000" + stroke-width="0.5035" + d="M 18.312,72.927 + c -2.103,-2.107 -3.407, -5.028 -3.407, -8.253 + c 0.000,-6.445 5.223,-11.672 11.666,-11.672 + c 6.446, 0.000 11.667, 5.225 11.667, 11.672 + h -6.832 + c 0.000,-2.674 -2.168, -4.837 -4.835, -4.837 + c -2.663, 0.000 -4.838, 2.163 -4.838, 4.837 + c 0.000, 1.338 0.549, 2.536 1.415, 3.420 + l 0.000, 0.000 + c 0.883, 0.874 2.101, 1.405 3.423, 1.405 + v 0.012 + c 3.232, 0.000 6.145, 1.309 8.243, 3.416 + l 0.000, 0.000 + c 2.118, 2.111 3.424, 5.034 3.424, 8.248 + c 0.000, 6.454 -5.221, 11.680 -11.667, 11.680 + c -6.442, 0.000 -11.666, -5.222 -11.666,-11.680 + h 6.828 + c 0.000, 2.679 2.175, 4.835 4.838, 4.835 + c 2.667, 0.000 4.835, -2.156 4.835, -4.835 + c 0.000,-1.329 -0.545, -2.527 -1.429, -3.407 + l 0.000, 0.000 + c -0.864,-0.880 -2.082, -1.418 -3.406, -1.418 + l 0.000, 0.000 + C 23.341,76.350 20.429, 75.036 18.312, 72.927 + L 18.312,72.927 + L 18.312,72.927 z"/> + <polygon + id="V" + fill="#FFFFFF" + stroke="#000000" + stroke-width="0.5035" + points="61.588,53.005 + 53.344,92.854 + 46.494,92.854 + 38.236,53.005 + 45.082,53.005 + 49.920,76.342 + 54.755,53.005"/> + + <path + id="G" + fill="#FFFFFF" + stroke="#000000" + stroke-width="0.5035" + d="M 73.255,69.513 + h 11.683 + v 11.664 + l 0.000, 0.000 + c 0.000, 6.452 -5.226,11.678 -11.669, 11.678 + c -6.441, 0.000 -11.666,-5.226 -11.666,-11.678 + l 0.000, 0.000 + V 64.676 + h -0.017 + C 61.586,58.229 66.827,53.000 73.253, 53.000 + c 6.459, 0.000 11.683, 5.225 11.683, 11.676 + h -6.849 + c 0.000,-2.674 -2.152,-4.837 -4.834, -4.837 + c -2.647, 0.000 -4.820, 2.163 -4.820, 4.837 + v 16.501 + l 0.000, 0.000 + c 0.000, 2.675 2.173, 4.837 4.820, 4.837 + c 2.682, 0.000 4.834,-2.162 4.834, -4.827 + v -0.012 + v -4.827 + h -4.834 + L 73.255,69.513 + L 73.255,69.513 z"/> + </g> + </g> + </a> +</svg> diff --git a/lib/output/assets-inliner.js b/lib/output/assets-inliner.js index fb348b4..9733505 100644 --- a/lib/output/assets-inliner.js +++ b/lib/output/assets-inliner.js @@ -65,7 +65,7 @@ AssetsInliner.prototype.onOutputImage = function(page, src) { } // Convert SVG to PNG - return that.convertSVGFile(page.resolve(src)); + return that.convertSVGFile(that.resolveForPage(page, src)); }) // Return relative path from the page @@ -88,7 +88,7 @@ AssetsInliner.prototype.downloadAsset = function(src) { that.downloaded[src] = filename; that.log.debug.ln('downloading asset', src); - return fs.download(src, filename) + return fs.download(src, that.resolve(filename)) .thenResolve(filename); }); }; diff --git a/lib/output/base.js b/lib/output/base.js index 688ecb7..9acfb87 100644 --- a/lib/output/base.js +++ b/lib/output/base.js @@ -57,17 +57,27 @@ Output.prototype.generate = function() { .then(function() { return that.book.fs.listAllFiles(that.book.root); }) + + // We want to process assets first, then pages + // Since pages can have logic based on existance of assets .then(function(files) { - return Promise.serie(files, function(filename) { - // Ignore file present in a language book - if (isMultilingual && that.book.isInLanguageBook(filename)) return; + // Ignore file present in a language book + files = _.filter(files, function(filename) { + return !(isMultilingual && that.book.isInLanguageBook(filename)); + }); + + // List assets + var byTypes = _.groupBy(files, function(filename) { + return (that.book.hasPage(filename)? 'page' : 'asset'); + }); - // Process file as page or asset - if (that.book.hasPage(filename)) { + return Promise.serie(byTypes.asset, function(filename) { + return that.onAsset(filename); + }) + .then(function() { + return Promise.serie(byTypes.page, function(filename) { return that.onPage(that.book.getPage(filename)); - } else { - return that.onAsset(filename); - } + }); }); }) diff --git a/lib/output/folder.js b/lib/output/folder.js index 8b899f6..90a3351 100644 --- a/lib/output/folder.js +++ b/lib/output/folder.js @@ -43,6 +43,13 @@ FolderOutput.prototype.resolve = function(filename) { return pathUtil.resolveInRoot.apply(null, [this.root()].concat(_.toArray(arguments))); }; +// Resolve a file path from a page (in the output folder) +FolderOutput.prototype.resolveForPage = function(page, filename) { + var abs = page.resolveLocal(filename); + return this.resolve(abs); +}; + + // Copy a file to the output FolderOutput.prototype.copyFile = function(from, to) { var that = this; @@ -88,12 +95,20 @@ FolderOutput.prototype.hasFile = function(filename) { // Create a new unique file // Returns its filename FolderOutput.prototype.createNewFile = function(base, filename) { + var that = this; + if (!filename) { filename = path.basename(filename); base = path.dirname(base); } - return fs.uniqueFilename(this.resolve(base), filename); + return fs.uniqueFilename(this.resolve(base), filename) + .then(function(out) { + out = path.join(base, out); + + return fs.ensure(that.resolve(out)) + .thenResolve(out); + }); }; diff --git a/lib/utils/fs.js b/lib/utils/fs.js index 3f1c11f..c0ff0c9 100644 --- a/lib/utils/fs.js +++ b/lib/utils/fs.js @@ -83,6 +83,12 @@ function uniqueFilename(base, filename) { return Promise(path.relative(base, _filename)); } +// Create all required folder to create a file +function ensureFile(filename) { + var base = path.dirname(filename); + return Promise.nfcall(mkdirp, base); +} + module.exports = { exists: fileExists, existsSync: fs.existsSync, @@ -96,5 +102,6 @@ module.exports = { copy: copyFile, tmpFile: genTmpFile, download: download, - uniqueFilename: uniqueFilename + uniqueFilename: uniqueFilename, + ensure: ensureFile }; diff --git a/test/assets-inliner.js b/test/assets-inliner.js index 76b04f6..1f00b5d 100644 --- a/test/assets-inliner.js +++ b/test/assets-inliner.js @@ -1,56 +1,70 @@ var cheerio = require('cheerio'); +var path = require('path'); var mock = require('./mock'); var AssetsInliner = require('../lib/output/assets-inliner'); describe('Assets Inliner Output', function() { + var output; - describe('SVG', function() { - var output; - - before(function() { - var SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"><rect width="200" height="100" stroke="black" stroke-width="6" fill="green"/></svg>'; - - return mock.outputDefaultBook(AssetsInliner, { - 'README.md': '', - 'inline.md': 'This is a svg: '+SVG, - 'test.svg': '<?xml version="1.0" encoding="UTF-8"?>' + SVG, - 'SUMMARY.md': '* [inline](inline.md)\n\n' - }) - .then(function(_output) { - output = _output; - }); - }); + before(function() { + var SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"><rect width="200" height="100" stroke="black" stroke-width="6" fill="green"/></svg>'; + + return mock.outputDefaultBook(AssetsInliner, { + 'README.md': '', - it('should correctly SVG files convert to PNG', function() { - var page = output.book.getPage('README.md'); - var $ = cheerio.load(page.content); + // test for SVGS + 'svg_file.md': '', + 'svg_inline.md': 'This is a svg: '+SVG, + 'test.svg': '<?xml version="1.0" encoding="UTF-8"?>' + SVG, - // Is there an image? - var $img = $('img'); - $img.length.should.equal(1); + // test for remote files + 'remote_png.md': '', + 'remote_svg.md': '', - // Does the file exists - var src = $img.attr('src'); - output.should.have.file(src); + 'SUMMARY.md': '* [svg inline](svg_inline.md)\n' + + '* [svg file](svg_file.md)\n' + + '* [remote png file](remote_png.md)\n' + + '* [remote svg file](remote_svg.md)\n' + + '\n\n' + }) + .then(function(_output) { + output = _output; }); + }); + + function testImageInPage(filename) { + var page = output.book.getPage(filename); + var $ = cheerio.load(page.content); - it('should correctly inline SVG convert to PNG', function() { - var page = output.book.getPage('inline.md'); - var $ = cheerio.load(page.content); + // Is there an image? + var $img = $('img'); + $img.length.should.equal(1); - // Is there an image? - var $img = $('img'); - $img.length.should.equal(1); + // Does the file exists + var src = $img.attr('src'); + output.should.have.file(src); + path.extname(src).should.equal('.png'); + } - // Does the file exists - var src = $img.attr('src'); - output.should.have.file(src); + describe('SVG', function() { + it('should correctly convert SVG files to PNG', function() { + testImageInPage('svg_file.md'); + }); + + it('should correctly convert inline SVG to PNG', function() { + testImageInPage('svg_inline.md'); }); }); describe('Remote Assets', function() { + it('should correctly download a PNG file', function() { + testImageInPage('remote_png.md'); + }); + it('should correctly download then convert a remote SVG to PNG', function() { + testImageInPage('remote_svg.md'); + }); }); }); |