Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for PDF output #78

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -16,7 +18,7 @@ svgexport <datafile>

<options> [<format>] [<quality>] [<input viewbox>] [<output size>] [<resize mode>] [<styles>]

<format> png|jpeg|jpg
<format> png|jpeg|jpg|pdf
If not specified, it will be inferred from output file extension or defaults to "png".

<quality> 1%-100%
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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*
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
39 changes: 33 additions & 6 deletions render.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,21 @@ 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');

}, input, output, clip);

var svgContent = await page.content();

clip.x = Math.max(clip.x, 0);
clip.y = Math.max(clip.y, 0);

var renderContent = `
<!DOCTYPE html>
<html>
Expand All @@ -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;
"
Expand All @@ -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');

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/exported/*.pdf
/exported/*.png
/exported/*.jpg
Binary file added test/expected/32-64-pad.pdf
Binary file not shown.
Binary file added test/expected/64-32-pad.pdf
Binary file not shown.
Binary file added test/expected/offset.pdf
Binary file not shown.
Binary file added test/expected/simple.pdf
Binary file not shown.
8 changes: 6 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -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([], {
Expand Down Expand Up @@ -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'
Expand Down
4 changes: 4 additions & 0 deletions test/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
Expand Down