Skip to content

Commit

Permalink
support template literals to exclude specific pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
zgid123 committed Apr 13, 2022
1 parent f77bf0a commit e3ee27c
Show file tree
Hide file tree
Showing 7 changed files with 873 additions and 718 deletions.
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@ console.log(interpole(source, ['format'], { clearDirtyParam: true })); // This f
const source = 'This function can :method this template with :type value';

console.log(
interpole(source, {
method: 'format',
}, {
clearDirtyParam: true,
}),
interpole(
source,
{
method: 'format',
},
{
clearDirtyParam: true,
},
),
); // This function can format this template with value
```

Expand Down Expand Up @@ -189,3 +193,30 @@ console.log(
),
); // Hello Alpha
```

# Changelogs

- 1.0.4: support template literals, it will exclude the pattern if has template literals as prefix

```ts
import interpole from 'string-interpolation-js';

const source = 'Hello {{ user.name }} ${{ user.name }}';

console.log(
interpole(
source,
{
user: {
name: 'Alpha',
},
},
{
exactMatch: true,
specElement: '_',
pattern: '{{ _ }}',
templateLiterals: '$',
},
),
); // Hello Alpha {{ user.name }}
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "string-interpolation-js",
"version": "1.0.3",
"version": "1.0.5",
"description": "Simple module to format string from template",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
3 changes: 3 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export interface IOptionsWithPatternProps extends IOptionsBaseProps {
// only this example is true {{ name }}
// if false, those two examples above are true
exactMatch?: boolean;
// will exclude if matches
// <templateLiterals><pattern>
templateLiterals?: string;
}

export interface IOptionsWithRegExpPatternProps extends IOptionsBaseProps {
Expand Down
19 changes: 16 additions & 3 deletions src/utils/replaceKeyword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function replaceKeyword(
value: any,
options: Omit<TOptions, 'clearDirtyParam'> = {},
): string {
const { pattern, specElement, exactMatch } = options;
const { pattern, specElement, exactMatch, templateLiterals } = options;

if (pattern instanceof RegExp) {
return source.replace(pattern, value);
Expand All @@ -25,12 +25,25 @@ function replaceKeyword(
keyword = ` *${keyword} *`;
}

const replacementPattern = escapeRegExp(pattern).replace(
// TODO: change to pattern (?<!<templateLitterals>)<pattern> when all browsers support negative lookbehind
const escapePattern = escapeRegExp(pattern).replace(
specElement,
keyword.toString(),
);
const replacementPattern = `(\\S|)${escapePattern}`;
const escapeRegExpPatternWithBegin = new RegExp(`^${escapePattern}$`);

return source.replace(new RegExp(replacementPattern, 'g'), value);
return source.replace(new RegExp(replacementPattern, 'g'), (replacement) => {
if (escapeRegExpPatternWithBegin.test(replacement)) {
return value;
}

if (replacement[0] === templateLiterals) {
return replacement.slice(1);
}

return `${replacement[0]}${value}`;
});
}

export function replaceKeywordForArrayParams(
Expand Down
27 changes: 27 additions & 0 deletions tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,30 @@ describe('interpole string with nested object params', () => {
).toEqual(result);
});
});

describe('interpole string with template literals', () => {
const template = 'Hello {{ user.name }}, are you a ${{ user.job.name }}?';
const result = 'Hello Alpha, are you a {{ user.job.name }}?';

test('keep template pattern', () => {
expect(
interpole(
template,
{
user: {
name: 'Alpha',
job: {
name: 'developer',
},
},
},
{
exactMatch: true,
specElement: '_',
pattern: '{{ _ }}',
templateLiterals: '$',
},
),
).toEqual(result);
});
});
64 changes: 64 additions & 0 deletions tests/utils/replaceKeyword.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { replaceKeywordForObjectParams } from '../../src/utils';

describe('replace keyword for object params', () => {
const template = 'Hello :name {{ name }} ${{ name }}';

test('replace param with : as prefix', () => {
expect(
replaceKeywordForObjectParams(
template,
{
name: 'test',
},
{},
),
).toEqual('Hello test {{ name }} ${{ name }}');
});

test('replace param with pattern', () => {
expect(
replaceKeywordForObjectParams(
template,
{
name: 'test',
},
{
pattern: '{{ _ }}',
specElement: '_',
},
),
).toEqual('Hello :name test $test');
});

test('replace param with pattern and exclude pattern has template litterals as prefix', () => {
expect(
replaceKeywordForObjectParams(
template,
{
name: 'test',
},
{
pattern: '{{ _ }}',
specElement: '_',
templateLiterals: '$',
},
),
).toEqual('Hello :name test {{ name }}');

const otherTemplate = 'Hello :name ${{ name }} $${{ name }}';

expect(
replaceKeywordForObjectParams(
otherTemplate,
{
name: 'test',
},
{
pattern: '${{ _ }}',
specElement: '_',
templateLiterals: '$',
},
),
).toEqual('Hello :name test ${{ name }}');
});
});
Loading

0 comments on commit e3ee27c

Please sign in to comment.