summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cf33a0ef.svg259
-rw-r--r--lib/output/assets-inliner.js4
-rw-r--r--lib/output/base.js26
-rw-r--r--lib/output/folder.js17
-rw-r--r--lib/utils/fs.js9
-rw-r--r--test/assets-inliner.js82
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': '![image](test.svg)',
- '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': '![image](test.svg)',
+ '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': '![image](https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png)',
+ 'remote_svg.md': '![image](https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg)',
- // 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');
+ });
});
});