Skip to content

Commit

Permalink
Merge pull request #8 from NotNinja/cli
Browse files Browse the repository at this point in the history
Added new CLI and convertFile method to API
  • Loading branch information
neocotic committed Oct 27, 2017
2 parents 033f811 + 90cfddd commit 8079987
Show file tree
Hide file tree
Showing 12 changed files with 673 additions and 148 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"extends": "notninja/es8",
"env": {
"node": true
},
"rules": {
"no-await-in-loop": "off"
}
}
112 changes: 81 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ A [Node.js](https://nodejs.org) module for converting SVG to PNG using headless
[![Release](https://img.shields.io/npm/v/convert-svg-to-png.svg?style=flat-square)](https://www.npmjs.com/package/convert-svg-to-png)

* [Install](#install)
* [CLI](#cli)
* [API](#api)
* [Bugs](#bugs)
* [Contributors](#contributors)
Expand All @@ -24,6 +25,28 @@ $ npm install --save convert-svg-to-png

You'll need to have at least [Node.js](https://nodejs.org) 8 or newer.

If you want to use the command line interface you'll most likely want to install it globally so that you can run
`convert-svg-to-png` from anywhere:

``` bash
$ npm install --global convert-svg-to-png
```

## CLI

Usage: convert-svg-to-png [options] [files...]


Options:

-V, --version output the version number
--no-color disables color output
-b, --base-url <url> specify base URL to use for all relative URLs in SVG
-f, --filename <filename> specify name the for target PNG file when processing STDIN
--height <value> specify height for PNG
--width <value> specify width for PNG
-h, --help output usage information

## API

### `convert(source[, options])`
Expand All @@ -36,12 +59,14 @@ If the width and/or height cannot be derived from `source` then they must be pro
This method attempts to derive the dimensions from `source` via any `width`/`height` attributes or its calculated
`viewBox` attribute.

This method is resolved with the PNG buffer.

An error will occur if `source` does not contain an SVG element or no `width` and/or `height` options were provided and
this information could not be derived from `source`.

#### Options

| Option | Type | Default | Description |
| Option | Type | Default | Description |
| ---------- | ------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `baseFile` | String | N/A | Path of file to be converted into a file URL to use for all relative URLs contained within SVG. Overrides `baseUrl` option. |
| `baseUrl` | String | `"file:///path/to/cwd"` | Base URL to use for all relative URLs contained within SVG. Overridden by `baseUrl` option. |
Expand All @@ -52,44 +77,77 @@ this information could not be derived from `source`.

``` javascript
const { convert } = require('convert-svg-to-png');
const fs = require('fs');
const path = require('path');
const util = require('util');
const express = require('express');

const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const app = express();

async function convertSvgFile(filePath) {
const dirPath = path.dirname(filePath);
const input = await readFile(filePath);
const output = await convert(input, { baseFile: dirPath });
app.post('/convert', async(req, res) => {
const png = await convert(req.body);

await writeFile(path.join(dirPath, `${path.basename(filePath, '.svg')}.png`), output);
}
res.set('Content-Type', 'image/png');
res.send(png);
});

app.listen(3000);
```

### `convertFile(sourceFilePath[, options])`

Converts the SVG file at the specified path into a PNG using the `options` provided and writes it to the the target
file.

The target file is derived from `sourceFilePath` unless the `targetFilePath` option is specified.

If the width and/or height cannot be derived from the source file then they must be provided via their corresponding
options. This method attempts to derive the dimensions from the source file via any `width`/`height` attributes or its
calculated `viewBox` attribute.

This method is resolved with the path of the target (PNG) file for reference.

An error will occur if the source file does not contain an SVG element, no `width` and/or `height` options were provided
and this information could not be derived from source file, or a problem arises while reading the source file or writing
the target file.

#### Options

Has the same options as the standard `convert` method but also supports the following additional options:

| Option | Type | Default | Description |
| ---------------- | ------ | ------------------------------------------------------ | ------------------------------------------------------------- |
| `targetFilePath` | String | `sourceFilePath` with extension replaced with `".png"` | Path of the file to which the PNG output should be written to |

#### Example

``` javascript
const { convertFile } = require('convert-svg-to-png');

(async() => {
const sourceFilePath = '/path/to/my-image.svg';
const targetFilePath = await convertFile(sourceFilePath);

console.log(targetFilePath);
//=> "/path/to/my-image.png"
})();
```

### `createConverter()`

Creates an instance of `Converter`.

It is important to note that, after the first time `Converter#convert` is called, a headless Chromium instance will
remain open until `Converter#destroy` is called. This is done automatically when using the main API
[convert](#convertsource-options) method, however, when using `Converter` directly, it is the responsibility of the
caller. Due to the fact that creating browser instances is expensive, this level of control allows callers to reuse a
browser for multiple conversions. It's not recommended to keep an instance around for too long, as it will use up
resources.
It is important to note that, after the first time either `Converter#convert` or `Converter#convertFile` are called, a
headless Chromium instance will remain open until `Converter#destroy` is called. This is done automatically when using
the main API convert methods, however, when using `Converter` directly, it is the responsibility of the caller. Due to
the fact that creating browser instances is expensive, this level of control allows callers to reuse a browser for
multiple conversions. It's not recommended to keep an instance around for too long, as it will use up resources.

#### Example

``` javascript
const { createConverter } = require('convert-svg-to-png');
const fs = require('fs');
const path = require('path');
const util = require('util');

const readdir = util.promisify(fs.readdir);
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);

async function convertSvgFiles(dirPath) {
const converter = createConverter();
Expand All @@ -98,15 +156,7 @@ async function convertSvgFiles(dirPath) {
const filePaths = await readdir(dirPath);

for (const filePath of filePaths) {
const extension = path.extname(filePath);
if (extension !== '.svg') {
continue;
}

const input = await readFile(path.join(dirPath, filePath));
const output = await converter.convert(input, { baseFile: dirPath });

await writeFile(path.join(dirPath, `${path.basename(filePath, extension)}.png`), output);
await converter.convertFile(filePath);
}
} finally {
await converter.destroy();
Expand All @@ -123,7 +173,7 @@ The current version of this library.
``` javascript
const { version } = require('convert-svg-to-png');

version;
console.log(version);
//=> "0.1.0"
```

Expand Down
39 changes: 39 additions & 0 deletions bin/convert-svg-to-png
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env node

/*
* Copyright (C) 2017 Alasdair Mercer, !ninja
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

'use strict';

const CLI = require('../src/cli');

(async() => {
const cli = new CLI();

try {
await cli.parse(process.argv);
} catch (e) {
cli.error(`convert-svg-to-png failed: ${e.stack}`);

process.exit(1);
}
})();
41 changes: 19 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
"url": "https://github.com/NotNinja/convert-svg-to-png.git"
},
"dependencies": {
"chalk": "^2.3.0",
"commander": "^2.11.0",
"file-url": "^2.0.2",
"get-stdin": "^5.0.1",
"glob": "^7.1.2",
"puppeteer": "^0.12.0",
"tmp": "0.0.33"
},
Expand All @@ -35,8 +39,12 @@
"eslint": "^4.9.0",
"eslint-config-notninja": "^0.2.3",
"mocha": "^4.0.1",
"rimraf": "^2.6.2",
"sinon": "^4.0.1"
},
"bin": {
"convert-svg-to-png": "bin/convert-svg-to-png"
},
"main": "src/index.js",
"scripts": {
"pretest": "eslint \"src/**/*.js\" \"test/**/*.js\"",
Expand Down
Loading

0 comments on commit 8079987

Please # to comment.