Skip to content

Commit

Permalink
Add useFallback option to replaceSymbols() (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 4, 2024
1 parent d0118bb commit 0ab1df3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 28 deletions.
21 changes: 16 additions & 5 deletions index.d.ts
Expand Up @@ -246,8 +246,19 @@ Symbols to use on any terminal.
*/
export default figureSet;

export type Options = {
/**
Whether to replace symbols with fallbacks.
This can be set to `true` to always use fallback symbols, whether the terminal has poor Unicode support or not.
@default `true` if the terminal has poor Unicode support
*/
readonly useFallback?: boolean;
};

/**
Replace Unicode symbols depending on the terminal.
Returns the input with replaced fallback symbols if the terminal has poor Unicode support.
@param string - String where the Unicode symbols will be replaced with fallback symbols depending on the terminal.
@returns The input with replaced fallback Unicode symbols.
Expand All @@ -260,9 +271,9 @@ console.log(replaceSymbols('✔ check'));
// On terminals with Unicode symbols: ✔ check
// On other terminals: √ check
console.log(figures.tick);
// On terminals with Unicode symbols:
// On other terminals: √
console.log(replaceSymbols('✔ check', {useFallback: true}));
// On terminals with Unicode symbols: √ check
// On other terminals: √ check
```
*/
export function replaceSymbols(string: string): string;
export function replaceSymbols(string: string, options?: Options): string;
12 changes: 5 additions & 7 deletions index.js
Expand Up @@ -281,13 +281,11 @@ export default figures;
const replacements = Object.entries(specialMainSymbols);

// On terminals which do not support Unicode symbols, substitute them to other symbols
export const replaceSymbols = string => {
if (shouldUseMain) {
return string;
}

for (const [key, mainSymbol] of replacements) {
string = string.replaceAll(mainSymbol, fallbackSymbols[key]);
export const replaceSymbols = (string, {useFallback = !shouldUseMain} = {}) => {
if (useFallback) {
for (const [key, mainSymbol] of replacements) {
string = string.replaceAll(mainSymbol, fallbackSymbols[key]);
}
}

return string;
Expand Down
18 changes: 15 additions & 3 deletions index.test-d.ts
@@ -1,7 +1,19 @@
import {expectType} from 'tsd';
import figures, {replaceSymbols, mainSymbols, fallbackSymbols} from './index.js';
import {expectType, expectError} from 'tsd';
import figures, {mainSymbols, fallbackSymbols, replaceSymbols} from './index.js';

expectType<string>(replaceSymbols('✔ check'));
expectType<string>(figures.tick);

expectType<string>(mainSymbols.tick);

expectType<string>(fallbackSymbols.tick);

expectType<string>(replaceSymbols('✔ check'));
expectError(replaceSymbols(true));
expectError(replaceSymbols());

replaceSymbols('', {});
replaceSymbols('', {useFallback: undefined});
replaceSymbols('', {useFallback: true});
expectError(replaceSymbols('', {useFallback: 'other'}));
expectError(replaceSymbols('', {other: true}));
expectError(replaceSymbols('', ''));
27 changes: 24 additions & 3 deletions readme.md
Expand Up @@ -17,7 +17,7 @@ npm install figures
## Usage

```js
import figures, {replaceSymbols, mainSymbols, fallbackSymbols} from 'figures';
import figures, {mainSymbols, fallbackSymbols, replaceSymbols} from 'figures';

console.log(figures.tick);
// On terminals with Unicode symbols: ✔
Expand Down Expand Up @@ -50,9 +50,9 @@ Symbols to use when the terminal supports Unicode symbols.

Symbols to use when the terminal does not support Unicode symbols.

### replaceSymbols(string)
### replaceSymbols(string, options?)

Returns the input with replaced fallback Unicode symbols on older terminals.
Returns the input with replaced fallback symbols if the terminal has poor Unicode support.

All the below [figures](#figures) are attached to the default export as shown in the example above.

Expand All @@ -62,6 +62,27 @@ Type: `string`

String where the Unicode symbols will be replaced with fallback symbols depending on the terminal.

#### options

Type: `object`

##### useFallback

Type: `boolean`\
Default: `true` if the terminal has poor Unicode support

Whether to replace symbols with fallbacks.

This can be set to `true` to always use fallback symbols, whether the terminal has poor Unicode support or not.

```js
import {replaceSymbols} from 'figures';

console.log(replaceSymbols('✔ check', {useFallback: true}));
// On terminals with Unicode symbols: √ check
// On other terminals: √ check
```

## Figures

`Fallback` characters are only shown when they differ from the `Main` ones.
Expand Down
30 changes: 20 additions & 10 deletions test.js
Expand Up @@ -2,12 +2,14 @@ import test from 'ava';
import isUnicodeSupported from 'is-unicode-supported';
import figures, {replaceSymbols, mainSymbols, fallbackSymbols} from './index.js';

const result = (mainSymbols, fallbackSymbols) => isUnicodeSupported() ? mainSymbols : fallbackSymbols;
const getCorrectSymbols = (mainSymbols, fallbackSymbols) => isUnicodeSupported() ? mainSymbols : fallbackSymbols;
const getMainSymbols = mainSymbols => mainSymbols;
const getFallbackSymbols = (mainSymbols, fallbackSymbols) => fallbackSymbols;

console.log(` ${Object.values(figures).join(' ')}\n`);

test('figures', t => {
t.is(figures.tick, result('✔', '√'));
t.is(figures.tick, getCorrectSymbols('✔', '√'));
});

test('mainSymbols', t => {
Expand All @@ -18,15 +20,23 @@ test('fallbackSymbols', t => {
t.is(fallbackSymbols.tick, '√');
});

test('replaceSymbols() keep non-figures as is', t => {
t.is(replaceSymbols('foo'), 'foo');
});
const testKeepFigures = (t, useFallback) => {
t.is(replaceSymbols('foo', {useFallback}), 'foo');
};

test('replaceSymbols() replace figures', t => {
t.is(replaceSymbols('✔ ✔ ✔'), result('✔ ✔ ✔', '√ √ √'));
t.is(replaceSymbols('✔ ✘\n★ ◼'), result('✔ ✘\n★ ◼', '√ ×\n✶ ■'));
t.is(replaceSymbols('✔ ✘ ★ ◼'), result('✔ ✘ ★ ◼', '√ × ✶ ■'));
});
test('replaceSymbols() keep non-figures as is', testKeepFigures, undefined);
test('"useFallback: false" keep non-figures as is', testKeepFigures, false);
test('"useFallback: true" keep non-figures as is', testKeepFigures, true);

const testReplace = (t, useFallback, getSymbols) => {
t.is(replaceSymbols('✔ ✔ ✔', {useFallback}), getSymbols('✔ ✔ ✔', '√ √ √'));
t.is(replaceSymbols('✔ ✘\n★ ◼', {useFallback}), getSymbols('✔ ✘\n★ ◼', '√ ×\n✶ ■'));
t.is(replaceSymbols('✔ ✘ ★ ◼', {useFallback}), getSymbols('✔ ✘ ★ ◼', '√ × ✶ ■'));
};

test('replaceSymbols() sometimes replaces figures', testReplace, undefined, getCorrectSymbols);
test('"useFallback: false" never replaces figures', testReplace, false, getMainSymbols);
test('"useFallback: true" always replaces figures', testReplace, true, getFallbackSymbols);

test('figures are non-empty strings', t => {
for (const figure of Object.values(figures)) {
Expand Down

0 comments on commit 0ab1df3

Please sign in to comment.