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

Allow choosing EOL and appending final newline #1546

Merged
merged 7 commits into from
Sep 11, 2021
Merged
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
116 changes: 116 additions & 0 deletions lib/svgo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,122 @@ test('allow to disable and customize plugins in preset', () => {
`);
});

describe('allow to configure EOL', () => {
test('should respect EOL set to LF', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, {
js2svg: { eol: 'lf', pretty: true, indent: 2 },
});
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120">\n <circle fill="red" cx="60" cy="60" r="50"/>\n</svg>\n'
);
});

test('should respect EOL set to CRLF', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, {
js2svg: { eol: 'crlf', pretty: true, indent: 2 },
});
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120">\r\n <circle fill="red" cx="60" cy="60" r="50"/>\r\n</svg>\r\n'
);
});

test('should default to LF line break for any other EOL values', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, {
js2svg: { eol: 'invalid', pretty: true, indent: 2 },
});
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120">\n <circle fill="red" cx="60" cy="60" r="50"/>\n</svg>\n'
);
});
});

describe('allow to configure final newline', () => {
test('should not add final newline when unset', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, { js2svg: { eol: 'lf' } });
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120"><circle fill="red" cx="60" cy="60" r="50"/></svg>'
);
});

test('should add final newline when set', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, {
js2svg: { finalNewline: true, eol: 'lf' },
});
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120"><circle fill="red" cx="60" cy="60" r="50"/></svg>\n'
);
});

test('should not add extra newlines when using pretty: true', () => {
const svg = `
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 120 120">
<desc>
Not standard description
</desc>
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
</svg>
`;
const { data } = optimize(svg, {
js2svg: { finalNewline: true, pretty: true, indent: 2, eol: 'lf' },
});
// using toEqual because line endings matter in these tests
expect(data).toEqual(
'<svg viewBox="0 0 120 120">\n <circle fill="red" cx="60" cy="60" r="50"/>\n</svg>\n'
);
});
});

test('allow to customize precision for preset', () => {
const svg = `
<svg viewBox="0 0 120 120">
Expand Down
24 changes: 24 additions & 0 deletions lib/svgo/coa.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ module.exports = function makeProgram(program) {
)
.option('--pretty', 'Make SVG pretty printed')
.option('--indent <INTEGER>', 'Indent number when pretty printing SVGs')
.option(
'--eol <EOL>',
'Line break to use when outputting SVG: lf, crlf. If unspecified, uses platform default.'
)
.option('--final-newline', 'Ensure SVG ends with a line break')
.option(
'-r, --recursive',
"Use with '--folder'. Optimizes *.svg files in folders recursively."
Expand Down Expand Up @@ -112,6 +117,13 @@ async function action(args, opts, command) {
}
}

if (opts.eol != null && opts.eol !== 'lf' && opts.eol !== 'crlf') {
console.error(
"error: option '--eol' must have one of the following values: 'lf' or 'crlf'"
);
process.exit(1);
}

// --show-plugins
if (opts.showPlugins) {
showAvailablePlugins();
Expand Down Expand Up @@ -185,6 +197,18 @@ async function action(args, opts, command) {
}
}

// --eol
if (opts.eol) {
config.js2svg = config.js2svg || {};
config.js2svg.eol = opts.eol;
}

// --final-newline
if (opts.finalNewline) {
config.js2svg = config.js2svg || {};
config.js2svg.finalNewline = true;
}

// --output
if (output) {
if (input.length && input[0] != '-') {
Expand Down
35 changes: 26 additions & 9 deletions lib/svgo/js2svg.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var EOL = require('os').EOL,
var platformEOL = require('os').EOL,
textElems = require('../../plugins/_collections.js').textElems;

var defaults = {
Expand Down Expand Up @@ -28,6 +28,8 @@ var defaults = {
encodeEntity: encodeEntity,
pretty: false,
useShortTags: true,
eol: platformEOL === '\r\n' ? 'crlf' : 'lf',
finalNewline: false,
};

var entities = {
Expand Down Expand Up @@ -64,15 +66,21 @@ function JS2SVG(config) {
this.config.indent = ' ';
}

if (this.config.eol === 'crlf') {
this.eol = '\r\n';
} else {
this.eol = '\n';
}
adalinesimonian marked this conversation as resolved.
Show resolved Hide resolved

if (this.config.pretty) {
this.config.doctypeEnd += EOL;
this.config.procInstEnd += EOL;
this.config.commentEnd += EOL;
this.config.cdataEnd += EOL;
this.config.tagShortEnd += EOL;
this.config.tagOpenEnd += EOL;
this.config.tagCloseEnd += EOL;
this.config.textEnd += EOL;
this.config.doctypeEnd += this.eol;
this.config.procInstEnd += this.eol;
this.config.commentEnd += this.eol;
this.config.cdataEnd += this.eol;
this.config.tagShortEnd += this.eol;
this.config.tagOpenEnd += this.eol;
this.config.tagCloseEnd += this.eol;
this.config.textEnd += this.eol;
}

this.indentLevel = 0;
Expand Down Expand Up @@ -118,6 +126,15 @@ JS2SVG.prototype.convert = function (data) {

this.indentLevel--;

if (
this.config.finalNewline &&
this.indentLevel === 0 &&
svg.length > 0 &&
svg[svg.length - 1] !== '\n'
adalinesimonian marked this conversation as resolved.
Show resolved Hide resolved
) {
svg += this.eol;
}

return {
data: svg,
info: {
Expand Down