diff --git a/README.md b/README.md index 5447ca9..e423db1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # svgexport -svgexport is a Node.js module and command-line tool for exporting SVG files to PNG and JPEG, it uses Puppeteer for rendering SVG files. +svgexport is a Node.js module and command-line tool for exporting SVG files to PNG, JPEG, and PDF. + +It uses Puppeteer for rendering SVG files. ### Command Line @@ -16,7 +18,7 @@ svgexport [] [] [] [] [] [] - png|jpeg|jpg + png|jpeg|jpg|pdf If not specified, it will be inferred from output file extension or defaults to "png". 1%-100% @@ -71,6 +73,11 @@ Use a CSS to style input SVG: svgexport input.svg output.jpg "svg{background:silver;}" ``` +Export a PDF: +``` +svgexport input.svg output.pdf +``` + By default, Puppeteer has a page load timeout of 30 seconds. This might not be enough for large SVG files. If you want to change the page timeout, set the `SVGEXPORT_TIMEOUT` environment variable to the desired number of seconds. @@ -104,4 +111,4 @@ svgexport was migrated from PhantomJS to Puppeteer by [Michael Heerklotz](https: Copyright (c) 2016 Ali Shakiba Available under the MIT license -*Keywords: svg, export, rasterize, converter, png, jpeg, jpg, cli, command-line, inkscape, illustrator, coreldraw* +*Keywords: svg, export, rasterize, converter, png, jpeg, jpg, pdf, cli, command-line, inkscape, illustrator, coreldraw* diff --git a/package.json b/package.json index 66a5665..4a09b75 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "url": "https://github.com/shakiba/svgexport.git" }, "dependencies": { - "async": "^3.1.0", - "puppeteer": "^2.0.0" + "async": "^3.2.0", + "puppeteer": "^2.1.1" }, "main": "index.js", "bin": { diff --git a/render.js b/render.js index 7e9e6c2..2e06afd 100644 --- a/render.js +++ b/render.js @@ -114,6 +114,14 @@ async function renderSvg(commands, done, stdout) { svg.style.setProperty('top', 0, 'important'); } + if (clip.x > 0 && clip.y > 0) { + svg.style.setProperty('transform', `translateX(${-clip.x}px) translateY(${-clip.y}px)`, 'important'); + } else if (clip.x > 0) { + svg.style.setProperty('transform', `translateX(${-clip.x}px)`, 'important'); + } else if (clip.y > 0) { + svg.style.setProperty('transform', `translateY(${-clip.y}px)`, 'important'); + } + svg.style.setProperty('width', (input.width * output.scale) + 'px', 'important'); svg.style.setProperty('height', (input.height * output.scale) + 'px', 'important'); @@ -121,9 +129,6 @@ async function renderSvg(commands, done, stdout) { var svgContent = await page.content(); - clip.x = Math.max(clip.x, 0); - clip.y = Math.max(clip.y, 0); - var renderContent = ` @@ -142,8 +147,8 @@ async function renderSvg(commands, done, stdout) { border: 0 !important; padding: 0 !important; position: fixed !important; - left: ${clip.x}px !important; - top: ${clip.y}px !important; + left: 0 !important; + top: 0 !important; width: ${output.width}px !important; height: ${output.height}px !important; " @@ -167,7 +172,18 @@ async function renderSvg(commands, done, stdout) { } var outputEl = await page.$('#svgExportOutput-fa5ce2b6d16510'); - await outputEl.screenshot(renderSettings); + if (output.format === 'pdf') { + await page.emulateMediaType('screen'); + await page.pdf({ + path: imgfile, + displayHeaderFooter: false, + width: `${output.width}px`, + height: `${output.height}px`, + printBackground: false + }); + } else { + await outputEl.screenshot(renderSettings); + } stdout(svgfile + ' ' + imgfile + ' ' + output.toString() + '\n'); @@ -214,6 +230,17 @@ function Command(input, params, outputfile) { } }); + params.first(/^(pdf)$/i, function(match) { + output.format = match[1]; + }, function() { + if (outputfile) { + var ext = /.(pdf)$/.exec(outputfile); + if (ext && ext[1]) { + output.format = ext[1]; + } + } + }); + output.format = output.format.toLowerCase().replace('jpg', 'jpeg'); // output diff --git a/test/.gitignore b/test/.gitignore index 770f078..8c8a8d5 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,2 +1,3 @@ +/exported/*.pdf /exported/*.png /exported/*.jpg diff --git a/test/expected/32-64-pad.pdf b/test/expected/32-64-pad.pdf new file mode 100644 index 0000000..8f2f73e Binary files /dev/null and b/test/expected/32-64-pad.pdf differ diff --git a/test/expected/64-32-pad.pdf b/test/expected/64-32-pad.pdf new file mode 100644 index 0000000..182c55d Binary files /dev/null and b/test/expected/64-32-pad.pdf differ diff --git a/test/expected/offset.pdf b/test/expected/offset.pdf new file mode 100644 index 0000000..0453cfd Binary files /dev/null and b/test/expected/offset.pdf differ diff --git a/test/expected/simple.pdf b/test/expected/simple.pdf new file mode 100644 index 0000000..433a83c Binary files /dev/null and b/test/expected/simple.pdf differ diff --git a/test/test.js b/test/test.js index 46b0420..6566d69 100644 --- a/test/test.js +++ b/test/test.js @@ -7,7 +7,7 @@ var svgexport = require('../'); // TODO: compare exported files describe('Module', function() { - this.timeout(5000); + this.timeout(10000); // TODO: test input array, and 2d output array it('missing svg', function(done) { svgexport.render({ @@ -42,7 +42,7 @@ describe('Module', function() { }); describe('CLI', function() { - this.timeout(5000); + this.timeout(10000); // TODO: test input/output path with space it('no arg', function(done) { cli([], { @@ -152,6 +152,10 @@ var output = { + '/svg/simple.svg /exported/64-32-pad.png png 100% 2x -8:0:32:16 64:32\n' + '/svg/simple.svg /exported/32-64-pad.png png 100% 2x 0:-8:16:32 32:64\n' + '/svg/simple.svg /exported/offset.png png 100% 4x 8:8:8:8 32:32\n' + + '/svg/simple.svg /exported/32-64-pad.pdf pdf 100% 2x 0:-8:16:32 32:64\n' + + '/svg/simple.svg /exported/64-32-pad.pdf pdf 100% 2x -8:0:32:16 64:32\n' + + '/svg/simple.svg /exported/offset.pdf pdf 100% 4x 8:8:8:8 32:32\n' + + '/svg/simple.svg /exported/simple.pdf pdf 100% 1x 0:0:16:16 16:16\n' + '/svg/simple.svg /exported/jpeg-low.jpg jpeg 1% 20x 0:0:16:16 320:320\n' + '/svg/simple.svg /exported/jpeg-high.jpg jpeg 99% 20x 0:0:16:16 320:320\n' + '/svg/simple.svg /exported/36h.png png 100% 2x -1:-1:18:18 36:36\n' diff --git a/test/test.json b/test/test.json index ca7e821..ddb2b9f 100755 --- a/test/test.json +++ b/test/test.json @@ -11,6 +11,10 @@ "exported/64-32-pad.png pad 64:32", "exported/32-64-pad.png pad 32:64", "exported/offset.png 8:8:8:8 32:32", + "exported/64-32-pad.pdf pad 64:32", + "exported/32-64-pad.pdf pad 32:64", + "exported/offset.pdf 8:8:8:8 32:32", + "exported/simple.pdf", "exported/jpeg-low.jpg 1% 320:320", "exported/jpeg-high.jpg 99% 320:320" ]