Skip to content

Commit

Permalink
Add --preset command line option (#1)
Browse files Browse the repository at this point in the history
* Add --preset option.

* Added tests.
  • Loading branch information
johnkenny54 authored Sep 17, 2024
1 parent 57d28bb commit 28ee1f1
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 8 deletions.
4 changes: 4 additions & 0 deletions lib/builtin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import presetDefault from '../plugins/preset-default.js';
import presetNone from '../plugins/preset-none.js';
import * as addAttributesToSVGElement from '../plugins/addAttributesToSVGElement.js';
import * as addClassesToSVGElement from '../plugins/addClassesToSVGElement.js';
import * as cleanupAttrs from '../plugins/cleanupAttrs.js';
Expand Down Expand Up @@ -57,8 +58,11 @@ import * as reusePaths from '../plugins/reusePaths.js';
import * as sortAttrs from '../plugins/sortAttrs.js';
import * as sortDefsChildren from '../plugins/sortDefsChildren.js';

export const builtinPresets = new Set(['default', 'none']);

export const builtin = Object.freeze([
presetDefault,
presetNone,
addAttributesToSVGElement,
addClassesToSVGElement,
cleanupAttrs,
Expand Down
1 change: 1 addition & 0 deletions lib/svgo.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type Config = {
* [{ name: 'myPlugin', fn: () => ({}) }]
*/
plugins?: PluginConfig[];
preset?: 'default' | 'none';
/** Options for rendering optimized SVG from AST. */
js2svg?: StringifyOptions;
/** Output as Data URI string. */
Expand Down
23 changes: 20 additions & 3 deletions lib/svgo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { parseSvg } from './parser.js';
import { stringifySvg } from './stringifier.js';
import { builtin } from './builtin.js';
import { builtin, builtinPresets } from './builtin.js';
import { invokePlugins } from './svgo/plugins.js';
import { encodeSVGDatauri } from './svgo/tools.js';
import { getDocData } from './docdata.js';
Expand Down Expand Up @@ -74,9 +74,26 @@ export { VERSION, builtin as builtinPlugins, _collections };

/**
* @param {string} input
* @param {import('./svgo.js').Config} config
* @param {import('svgo-ll').Config} config
*/
export const optimize = (input, config) => {
/**
* @param {import('svgo-ll').Config} config
* @returns {import('svgo-ll').PluginConfig[]}
*/
function getPlugins(config) {
if (config.plugins) {
return config.plugins;
}
if (config.preset) {
if (builtinPresets.has(config.preset)) {
return [`preset-${config.preset}`];
}
console.warn(`invalid preset "${config.preset}"; using preset-default`);
}
return ['preset-default'];
}

if (!config) {
config = {};
}
Expand All @@ -97,9 +114,9 @@ export const optimize = (input, config) => {
const maxPasses = config.maxPasses
? Math.max(Math.min(config.maxPasses, 10), 1)
: 10;
const plugins = getPlugins(config);
for (let i = 0; i < maxPasses; i += 1) {
info.passNumber = i;
const plugins = config.plugins || ['preset-default'];
if (!Array.isArray(plugins)) {
throw Error('malformed config, `plugins` property must be an array.');
}
Expand Down
19 changes: 16 additions & 3 deletions lib/svgo/coa.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import colors from 'picocolors';
import { fileURLToPath } from 'url';
import { decodeSVGDatauri } from './tools.js';
import { loadConfig, optimize } from '../svgo-node.js';
import { builtin } from '../builtin.js';
import { builtin, builtinPresets } from '../builtin.js';
import { SvgoParserError } from '../parser.js';

/**
Expand Down Expand Up @@ -55,8 +55,9 @@ export default function makeProgram(program) {
'Output file or folder (by default the same as the input), "-" for STDOUT',
)
.option(
'-p, --precision <INTEGER>',
'Set number of digits in the fractional part, overrides plugins params',
'--preset <default | none>',
'Specify which set of predefined plugins to use.',
'default',
)
.option(
'--config <CONFIG>',
Expand Down Expand Up @@ -94,6 +95,10 @@ export default function makeProgram(program) {
.option('--show-plugins', 'Show available plugins and exit')
// used by picocolors internally
.option('--no-color', 'Output plain text without color')
.option(
'-p, --precision <INTEGER>',
'Set number of digits in the fractional part, overrides plugins params',
)
.action(action);
}

Expand Down Expand Up @@ -227,6 +232,14 @@ async function action(args, opts, command) {
);
}

if (opts.preset) {
if (builtinPresets.has(opts.preset)) {
config.preset = opts.preset;
} else {
console.warn(`invalid preset "${opts.preset}"; using preset-default`);
}
}

// --pretty
if (opts.pretty) {
config.js2svg = config.js2svg || {};
Expand Down
5 changes: 3 additions & 2 deletions lib/svgo/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ export const invokePlugins = (
};

/**
* @param {{ name: string, plugins: ({ name: string; params?: any; fn: import('../../plugins/plugins-types.js').Plugin<any>; } )[] }} arg0
* @param {{ name: string,description?:string, plugins: ({ name: string; params?: any; fn: import('../../plugins/plugins-types.js').Plugin<any>; } )[] }} arg0
* @returns {BuiltinPreset}
*/
export const createPreset = ({ name, plugins }) => {
export const createPreset = ({ name, plugins, description }) => {
return {
name,
description: description,
isPreset: true,
plugins: Object.freeze(plugins),
fn: (ast, params, info) => {
Expand Down
1 change: 1 addition & 0 deletions plugins/plugins-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ export type BuiltinsWithOptionalParams = DefaultPlugins & {
*/
overrides?: PresetDefaultOverrides;
};
'preset-none': {};
cleanupListOfValues: {
floatPrecision?: number;
leadingZero?: boolean;
Expand Down
9 changes: 9 additions & 0 deletions plugins/preset-none.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createPreset } from '../lib/svgo/plugins.js';

const presetNone = createPreset({
name: 'preset-none',
description: 'do not run any plugins',
plugins: [],
});

export default presetNone;
52 changes: 52 additions & 0 deletions test/coa/_index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,55 @@ describe('coa', function () {
});
});
});

describe('test preset option', function () {
afterAll(() => {
fs.rmSync(tempFolder, { force: true, recursive: true });
});

const dirName = path.resolve(__dirname, 'testPreset');
const svg1 = path.resolve(dirName, 'test1.svg');
const svg1Opt = path.resolve(tempFolder, 'test1.svg');

it('should use default preset when option not specified', async () => {
await runProgram(['-i', svg1, '-o', svg1Opt, '--quiet']);
const opt = fs.readFileSync(svg1Opt, { encoding: 'utf8' });
expect(opt).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path transform="translate(10 20)" d="M10 20h10v20H10z"/></svg>',
);
});

it('should only remove whitespace when "none" specified', async () => {
await runProgram([
'-i',
svg1,
'-o',
svg1Opt,
'--quiet',
'--preset',
'none',
]);
const opt = fs.readFileSync(svg1Opt, { encoding: 'utf8' });
expect(opt).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="20" width="10" height="20" transform="matrix(1 0 0 1 10 20) "/></svg>',
);
});

it('should only minify transform when "none" specified, but custom config is used', async () => {
await runProgram([
'-i',
svg1,
'-o',
svg1Opt,
'--quiet',
'--preset',
'none',
'--config',
path.resolve(dirName, 'config1.js'),
]);
const opt = fs.readFileSync(svg1Opt, { encoding: 'utf8' });
expect(opt).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="20" width="10" height="20" transform="translate(10 20)"/></svg>',
);
});
});
3 changes: 3 additions & 0 deletions test/coa/testPreset/config1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
plugins: ['minifyTransforms'],
};
3 changes: 3 additions & 0 deletions test/coa/testPreset/test1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 28ee1f1

Please sign in to comment.