From 21ce4218217de6e87c231fa14f3848baf3679532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Mon, 2 Dec 2024 18:03:25 +0100 Subject: [PATCH] fix: Handle backslashes before opening curly braces --- src/ExpressionSplitter.ts | 21 +++++++++++++++------ test/ExpressionSplitter.test.ts | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 test/ExpressionSplitter.test.ts diff --git a/src/ExpressionSplitter.ts b/src/ExpressionSplitter.ts index 3e94bfb..aac0a74 100644 --- a/src/ExpressionSplitter.ts +++ b/src/ExpressionSplitter.ts @@ -13,13 +13,17 @@ export interface ExpressionCode { export type ExpressionChunk = ExpressionCode | ExpressionText; -const OPEN_BRACKET = /(?\\|)(?\{\{)/; -const CLOSE_BRACKET = /(?\\|)(?\}\})/; +const OPEN_BRACKET = /(?\{\{)/; +const CLOSE_BRACKET = /(?\}\})/; export const escapeCode = (text: string): string => { return text.replace('\\}}', '}}'); }; +const normalizeBackslashes = (text: string): string => { + return text.replace(/\\\\/g, '\\'); +}; + export const splitExpression = (expression: string): ExpressionChunk[] => { const chunks: ExpressionChunk[] = []; let searchingFor: 'open' | 'close' = 'open'; @@ -51,16 +55,21 @@ export const splitExpression = (expression: string): ExpressionChunk[] => { } break; } - if (res.groups.escape) { - buffer += expr.slice(0, res.index + 3); - index += res.index + 3; + + const beforeMatch = expr.slice(0, res.index); + const backslashCount = beforeMatch.match(/\\*$/)?.[0]?.length ?? 0; + const isEscaped = backslashCount % 2 === 1; + + if (isEscaped) { + buffer += expr.slice(0, res.index + '{{'.length); + index += res.index + '{{'.length; } else { buffer += expr.slice(0, res.index); if (searchingFor === 'open') { chunks.push({ type: 'text', - text: buffer, + text: normalizeBackslashes(buffer), }); searchingFor = 'close'; activeRegex = CLOSE_BRACKET; diff --git a/test/ExpressionSplitter.test.ts b/test/ExpressionSplitter.test.ts new file mode 100644 index 0000000..65853ae --- /dev/null +++ b/test/ExpressionSplitter.test.ts @@ -0,0 +1,20 @@ +import { splitExpression } from '../src/ExpressionSplitter'; + +describe('splitExpression', () => { + test('should handle escaping backslashes before double opening curly braces', () => { + const expr = 'C:\\\\Users\\\\Administrator\\\\Desktop\\\\abc\\\\{{ $json.files[0].fileName }}'; + const result = splitExpression(expr); + + expect(result).toEqual([ + { + type: 'text', + text: 'C:\\Users\\Administrator\\Desktop\\abc\\', + }, + { + type: 'code', + text: ' $json.files[0].fileName ', + hasClosingBrackets: true, + }, + ]); + }); +});