From c503cb23dfbdd6f146d6dea16a84eab3df1f7aa9 Mon Sep 17 00:00:00 2001 From: Harttle Date: Sun, 6 Mar 2022 00:20:11 +0800 Subject: [PATCH] feat: allow strip filter with specified char, closes #390 --- src/builtin/filters/string.ts | 22 ++++++++++++++++++---- src/util/underscore.ts | 4 ++++ test/integration/builtin/filters/string.ts | 17 +++++++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/builtin/filters/string.ts b/src/builtin/filters/string.ts index 650602af13..58bd9558f0 100644 --- a/src/builtin/filters/string.ts +++ b/src/builtin/filters/string.ts @@ -3,7 +3,7 @@ * * * prefer stringify() to String() since `undefined`, `null` should eval '' */ -import { stringify } from '../../util/underscore' +import { escapeRegExp, stringify } from '../../util/underscore' import { assert } from '../../util/assert' export function append (v: string, arg: string) { @@ -16,7 +16,11 @@ export function prepend (v: string, arg: string) { return stringify(arg) + stringify(v) } -export function lstrip (v: string) { +export function lstrip (v: string, chars?: string) { + if (chars) { + chars = escapeRegExp(stringify(chars)) + return stringify(v).replace(new RegExp(`^[${chars}]+`, 'g'), '') + } return stringify(v).replace(/^\s+/, '') } @@ -36,7 +40,11 @@ export function removeFirst (v: string, l: string) { return stringify(v).replace(String(l), '') } -export function rstrip (str: string) { +export function rstrip (str: string, chars?: string) { + if (chars) { + chars = escapeRegExp(stringify(chars)) + return stringify(str).replace(new RegExp(`[${chars}]+$`, 'g'), '') + } return stringify(str).replace(/\s+$/, '') } @@ -48,7 +56,13 @@ export function split (v: string, arg: string) { return arr } -export function strip (v: string) { +export function strip (v: string, chars?: string) { + if (chars) { + chars = escapeRegExp(stringify(chars)) + return stringify(v) + .replace(new RegExp(`^[${chars}]+`, 'g'), '') + .replace(new RegExp(`[${chars}]+$`, 'g'), '') + } return stringify(v).trim() } diff --git a/src/util/underscore.ts b/src/util/underscore.ts index fdc335ad0f..9a1c336769 100644 --- a/src/util/underscore.ts +++ b/src/util/underscore.ts @@ -156,3 +156,7 @@ export function caseInsensitiveCompare (a: any, b: any) { export function argumentsToValue any> (fn: F) { return (...args: Parameters) => fn(...args.map(toValue)) } + +export function escapeRegExp (text: string) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} diff --git a/test/integration/builtin/filters/string.ts b/test/integration/builtin/filters/string.ts index ca61cd3f6f..f099b3bde5 100644 --- a/test/integration/builtin/filters/string.ts +++ b/test/integration/builtin/filters/string.ts @@ -86,9 +86,10 @@ describe('filters/string', function () { it('should support upcase', () => test('{{ "Parker Moore" | upcase }}', 'PARKER MOORE')) it('should return empty for undefined', () => test('{{ foo | upcase }}', '')) }) - it('should support lstrip', function () { + it('should support lstrip', async () => { const src = '{{ " So much room for activities! " | lstrip }}' - return test(src, 'So much room for activities! ') + await test(src, 'So much room for activities! ') + await test('{{ "foobarcoo" | lstrip: "fo" }}', 'barcoo') }) it('should support prepend', function () { return test('{% assign url = "liquidmarkup.com" %}' + @@ -115,9 +116,10 @@ describe('filters/string', function () { '{{ my_string | replace_first: "my", "your" }}', '\nTake your protein pills and put my helmet on') }) - it('should support rstrip', function () { - return test('{{ " So much room for activities! " | rstrip }}', + it('should support rstrip', async () => { + await test('{{ " So much room for activities! " | rstrip }}', ' So much room for activities!') + await test('{{ "foobarcoo" | rstrip: "fco" }}', 'foobar') }) it('should support split', function () { return test('{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' + @@ -126,9 +128,12 @@ describe('filters/string', function () { '{% endfor %}', 'John Paul George Ringo ') }) - it('should support strip', function () { - return test('{{ " So much room for activities! " | strip }}', + it('should support strip', async () => { + await test('{{ " So much room for activities! " | strip }}', 'So much room for activities!') + await test('{{ " So much room for activities! " | strip: "So " }}', + 'much room for activities!') + await test('{{ "&[]{}" | strip: "&[]{}" }}', '') }) it('should support strip_newlines', function () { return test('{% capture string_with_newlines %}\n' +