From 5553d980a0f07c10839f7b56b2c4468af92a40f0 Mon Sep 17 00:00:00 2001 From: Vanshaj Poonia Date: Mon, 12 Oct 2026 21:02:09 +0530 Subject: [PATCH] fix(#177): quote special variable values that contain double quotes wrapInQuotes skipped any value containing a double quote, assuming the user had quoted it. Values whose quotes sit inside a helper argument, such as {{ datetime format="YYYY" }}, were then left unquoted and the frontmatter failed to parse. Only skip values that start with a quote, and escape backslashes and double quotes when wrapping so the value comes out as written. --- src/parser.ts | 10 ++++++---- tests/parser.spec.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 36bd554..ad08740 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -215,14 +215,16 @@ export class Parser { } const firstMatch = matches[0]; + const splitVal = firstMatch.split(":"); + const value = splitVal.slice(1).join(":").trim(); - // Don't do anything if it already contains a double quote - if (firstMatch.indexOf("\"") !== -1) { + // Don't do anything if the user has already quoted the value + if (value.startsWith("\"") || value.startsWith("'")) { continue; } - const splitVal = firstMatch.split(":"); - const wrappedString = `${splitVal[0]}: "${splitVal.slice(1).join(":").trim()}"`; + const escapedValue = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\""); + const wrappedString = `${splitVal[0]}: "${escapedValue}"`; definitionsBlock = definitionsBlock.replace(firstMatch, wrappedString); } diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts index b7584bf..3ef7507 100644 --- a/tests/parser.spec.ts +++ b/tests/parser.spec.ts @@ -383,6 +383,49 @@ describe("Template parser", () => { expect(parsedTemplate).toBeNull(); }); + test("should quote special variable values that contain double quotes", async () => { + const template = { + id: "note-id", + title: "Some Template", + body: dedent` + --- + template_title: {{ datetime format="dddd D MMMM YYYY" }} + template_tags: {{ datetime format="YYYY" }}, weekly + template_todo_alarm: {{ datetime set_time="09:00" delta_days=1 }} + + --- + ` + }; + + const parsedTemplate = await parser.parseTemplate(template); + + assert(parsedTemplate); + expect(parsedTemplate.title).toEqual("Thursday 12 August 2021"); + expect(parsedTemplate.tags).toStrictEqual(["2021", "weekly"]); + expect(parsedTemplate.todo_due).toEqual(1628845200000); // 13 August 2021 09:00 + }); + + test("should keep backslashes and already quoted special variable values as written", async () => { + const titleWithBackslash = "Q3\\Q4 {{ datetime format=\"YYYY\" }}"; + const template = { + id: "note-id", + title: "Some Template", + body: dedent` + --- + template_title: ${titleWithBackslash} + template_tags: 'weekly, {{ datetime format="YYYY" }}' + + --- + ` + }; + + const parsedTemplate = await parser.parseTemplate(template); + + assert(parsedTemplate); + expect(parsedTemplate.title).toEqual("Q3\\Q4 2021"); + expect(parsedTemplate.tags).toStrictEqual(["weekly", "2021"]); + }); + test("should show an error message if notebook defined in templates_notebook doesn't exist", async () => { const template = { id: "note-id",