diff --git a/src/parser.ts b/src/parser.ts index 36bd554..75c3d33 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -134,7 +134,10 @@ export class Parser { throw new Error(`${variable} should be a string, found ${typeof specialVariables[variable]}.`); } - const compiledText = Handlebars.compile(specialVariables[variable]); + // noEscape: templates render into markdown notes, not html, so + // values must be inserted verbatim. Without this, an apostrophe in + // a variable turns into ' in the note title. + const compiledText = Handlebars.compile(specialVariables[variable], { noEscape: true }); res[variable] = compiledText(context); } @@ -283,7 +286,8 @@ export class Parser { }; const templateBody = processedTemplate.body; - const compiledTemplate = Handlebars.compile(templateBody); + // See the note on noEscape in parseSpecialVariables above. + const compiledTemplate = Handlebars.compile(templateBody, { noEscape: true }); // note_id is intentionally excluded from the shared context above // because it is only meaningful in the note body (it resolves to a diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts index b7584bf..e4796b0 100644 --- a/tests/parser.spec.ts +++ b/tests/parser.spec.ts @@ -1093,4 +1093,40 @@ describe("Template parser", () => { expect(parsedTemplate).toBeNull(); expect(errorMessagesShown).toEqual(1); }); + test("should not html escape special characters in template output", async () => { + // Templates render into markdown notes, not html, so characters like + // apostrophes and quotes must survive as typed. + const template = { + id: "note-id", + title: "Some Template", + body: dedent` + --- + note_text: text + template_title: Notes on {{ note_text }} + template_tags: {{ note_text }} + --- + + {{ note_text }} + {{{ note_text }}} + ` + }; + testVariableTypes({ + note_text: TextCustomVariable + }); + handleVariableDialog("ok", { + note_text: "it's a \"test\" & more" + }); + + const parsedTemplate = await parser.parseTemplate(template); + + assert(parsedTemplate); + // The triple stache was the old workaround, and must keep behaving + // identically now that the double stache no longer escapes. + expect(parsedTemplate.body).toEqual(dedent` + it's a "test" & more + it's a "test" & more + `); + expect(parsedTemplate.title).toEqual("Notes on it's a \"test\" & more"); + expect(parsedTemplate.tags).toEqual(["it's a \"test\" & more"]); + }); });