Skip to content

Commit

Permalink
Merge pull request #12 from kreuzerk/feature/delimiterOption
Browse files Browse the repository at this point in the history
Feature/delimiter option
  • Loading branch information
nivekcode authored Dec 31, 2019
2 parents cb8ece9 + c972786 commit 659bf06
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 26 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ To make SVGs tree shakeable its a good way to export them as string constants.
Of course you don't always want to regenerate all the strings by hand. That's where
svg-to-ts comes in.

**Do you want to find out how to create your own icon library?** [Find out more in this blogpost](https://medium.com/angular-in-depth/how-to-create-an-icon-library-in-angular-4f8863d95a)

# What it does

This library generates a Typescript file with your svg definitons. The file
Expand Down Expand Up @@ -60,15 +62,16 @@ Additonally we also optimize the SVG icons with the help of the `svgo` package.

The CLI can be used with the `tsvg` command. This command accepts the following arguments.

| -v | --version | output the version number |
| --- | -------------------------- | ----------------------------------------------------- |
| -t | --typeName <string> | name of the generated type (myIcons) |
| -p | --prefix <string> | prefix for the generated svg constants (myIcon) |
| -i | --interfaceName <string> | name for the generated interface (MyIcon) |
| -f | --fileName <string> | file name of the generated file (default: "my-icons") |
| -s | --srcDirectory <string> | name of the source directory (default: ".") |
| -o | --outputDirectory <string> | name of the output directory (default: "./dist") |
| -h | --help | output usage information |
| -v | --version | output the version number |
| --- | -------------------------- | -------------------------------------------------------------------------------------------------------- |
| -t | --typeName <string> | name of the generated type (myIcons) |
| -p | --prefix <string> | prefix for the generated svg constants (myIcon) |
| -i | --interfaceName <string> | name for the generated interface (MyIcon) |
| -f | --fileName <string> | file name of the generated file (default: "my-icons") |
| -d | --delimiter <Delimiter> | delimiter which is used to generate the types and name properties (CAMEL,KEBAB,SNAKE) (default: "SNAKE") |
| -s | --srcDirectory <string> | name of the source directory (default: ".") |
| -o | --outputDirectory <string> | name of the output directory (default: "./dist") |
| -h | --help | output usage information |

# Example

Expand Down
File renamed without changes
5 changes: 5 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"format:write": "prettier --write 'src/**/*.ts'",
"prebuild": "npm run copy:readme",
"start": "ts-node ./src/bin/svg-to-ts.ts -s ./inputfiles",
"start:kebap": "ts-node ./src/bin/svg-to-ts.ts -s ./inputfiles -d KEBAB",
"start:multiple-source": "ts-node ./src/bin/svg-to-ts.ts -s ./inputfiles -s ./inputfilesBis",
"start:custom": "ts-node ./src/bin/svg-to-ts.ts -s ./inputfiles -o ./dist -t sampleIcon -i SampleIcon -p sampleIcon -f icons",
"start:help": "ts-node ./src/bin/svg-to-ts.ts -h",
Expand Down Expand Up @@ -46,6 +47,7 @@
"chalk": "^3.0.0",
"commander": "^4.0.1",
"lodash.camelcase": "^4.3.0",
"lodash.kebabcase": "^4.1.1",
"lodash.snakecase": "^4.1.1",
"prettier": "^1.19.1",
"svgo": "^1.3.2"
Expand Down
17 changes: 12 additions & 5 deletions src/bin/svg-to-ts.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#!/usr/bin/env node
import * as packgeJSON from '../../package.json';
import commander from 'commander';
import { convert } from '../lib/convert';
import { convert, Delimiter } from '../lib/convert';

const DEFAULTS = {
typeName: 'myIcons',
interfaceName: 'MyIcon',
fileName: 'my-icons',
delimiter: Delimiter.SNAKE,
interfaceName: 'MyIcon',
outputDirectory: './dist',
prefix: 'myIcon',
sourceDirectories: ['.'],
outputDirectory: './dist'
typeName: 'myIcons'
};

function collect(value, previous) {
Expand All @@ -20,13 +21,18 @@ commander
.version(packgeJSON.version)
.option('-t --typeName <string>', 'name of the generated enumeration type', DEFAULTS.typeName)
.option('-f --fileName <string>', 'name of the generated file', DEFAULTS.fileName)
.option(
'-d --delimiter <Delimiter>',
`delimiter which is used to generate the types and name properties (${Object.values(Delimiter).join(',')})`,
DEFAULTS.delimiter
)
.option('-p --prefix <string>', 'prefix for the generated svg constants', DEFAULTS.prefix)
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULTS.interfaceName)
.option('-s --srcDirectory <value>', 'name of the source directory', collect, [])
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULTS.outputDirectory)
.parse(process.argv);

const { typeName, fileName, prefix, interfaceName, outputDirectory } = commander;
const { delimiter, fileName, interfaceName, outputDirectory, prefix, typeName } = commander;

// Because of commander adding default value to params
// See: https://stackoverflow.com/questions/30238654/commander-js-collect-multiple-options-always-include-default
Expand All @@ -36,6 +42,7 @@ if (srcDirectories.length === 0) {
}

const convertionOptions = {
delimiter,
typeName,
fileName,
prefix,
Expand Down
39 changes: 27 additions & 12 deletions src/lib/convert.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { svgo } from './svgo';
import { getInterfaceDefinition, getSvgConstant, getTypeDefinition } from './definitions';
import snakeCase from 'lodash.snakecase';
import camelCase from 'lodash.camelcase';
import kebapCase from 'lodash.kebabcase';
import * as prettier from 'prettier/standalone';
import chalk from 'chalk';
import typescriptParser from 'prettier/parser-typescript';

import { Dirent } from 'fs';
import * as util from 'util';
import * as path from 'path';
import * as fs from 'fs';

const util = require('util');
const path = require('path');
const fs = require('fs');
import { svgo } from './svgo';
import { getInterfaceDefinition, getSvgConstant, getTypeDefinition } from './definitions';

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

export interface ConvertionOptions {
delimiter: Delimiter;
typeName: string;
prefix: string;
fileName: string;
Expand All @@ -24,6 +27,12 @@ export interface ConvertionOptions {
outputDirectory: string;
}

export enum Delimiter {
CAMEL = 'CAMEL',
KEBAB = 'KEBAB',
SNAKE = 'SNAKE'
}

export const convert = async (convertionOptions: ConvertionOptions): Promise<void> => {
let svgConstants = '';

Expand Down Expand Up @@ -52,13 +61,9 @@ export const convert = async (convertionOptions: ConvertionOptions): Promise<voi
const rawSvg = await extractSvgContent(fileNameWithEnding, directoryPath);
const optimizedSvg = await svgo.optimize(rawSvg);
const variableName = getVariableName(convertionOptions, filenameWithoutEnding);
types += `'${snakeCase(filenameWithoutEnding)}'${typesDelimitor}`;
svgConstants += getSvgConstant(
variableName,
convertionOptions.interfaceName,
snakeCase(filenameWithoutEnding),
optimizedSvg.data
);
const typeName = getTypeName(filenameWithoutEnding, convertionOptions.delimiter);
types += `'${typeName}'${typesDelimitor}`;
svgConstants += getSvgConstant(variableName, convertionOptions.interfaceName, typeName, optimizedSvg.data);
}
}
types = types.substring(0, types.length - typesDelimitor.length) + ';';
Expand All @@ -74,6 +79,16 @@ export const convert = async (convertionOptions: ConvertionOptions): Promise<voi
}
};

const getTypeName = (filenameWithoutEnding, delimiter: Delimiter): string => {
if (delimiter === Delimiter.CAMEL) {
return `${camelCase(filenameWithoutEnding)}`;
}
if (delimiter === Delimiter.KEBAB) {
return `${kebapCase(filenameWithoutEnding)}`;
}
return `${snakeCase(filenameWithoutEnding)}`;
};

const generateFileContent = (svgContstants: string, types: string, convertionOptions: ConvertionOptions): string => {
const fileContent = (svgContstants += types += getInterfaceDefinition(
convertionOptions.interfaceName,
Expand Down

0 comments on commit 659bf06

Please sign in to comment.