fix: escape values substituted into quoted frontmatter scalars - #1659
Conversation
Authors quote tokens in template frontmatter to keep the raw template valid
YAML (Obsidian's parser warns on bare {{...}}, issue #1655). The substituted
value was inserted verbatim, so a value containing the surrounding quote
character corrupted the created note's frontmatter. Escape VALUE and FIELD
substitutions when the token exactly spans an author-quoted sole-value scalar.
|
Warning Review limit reached
Next review available in: 28 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe formatter now escapes variable and field substitutions inside quoted YAML front-matter scalars. Typed values consume author-provided quotes when required. Tests and documentation cover quoting, control characters, and property types. ChangesQuoted YAML substitutions
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying quickadd with
|
| Latest commit: |
eef133a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://133f0cf1.quickadd.pages.dev |
| Branch Preview URL: | https://fix-1655-quoted-token-escapi.quickadd.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/formatters/formatter.ts`:
- Around line 1301-1308: The quoted-scalar escaping currently misses anonymous
VALUE substitutions and non-collected array fallbacks for VALUE and FIELD.
Update replaceValueInString and the relevant VALUE/FIELD fallback paths to pass
generated scalar and joined-array text through
escapeValueInsideQuotedYamlScalar, while preserving existing collected
replacement behavior; add regression coverage for both anonymous and
joined-array cases.
In `@src/utils/yamlScalarQuoting.ts`:
- Around line 64-73: The double-quoted scalar escaping in the current function
handles only LF, CR, and tab, leaving other YAML control characters invalid.
Extract or reuse a shared double-quoted YAML escape routine with
quoteYamlDouble, ensuring all control characters are escaped consistently, and
add regression coverage for null, backspace, form feed, escape, and other
remaining control characters.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d9d33acb-bf68-4d02-bd54-708d6ef82747
📒 Files selected for processing (5)
docs/src/content/docs/docs/Choices/TemplateChoice.mdsrc/formatters/formatter-quoted-scalar.test.tssrc/formatters/formatter.tssrc/utils/yamlScalarQuoting.test.tssrc/utils/yamlScalarQuoting.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf9cb3e546
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A quoted token normally writes a string, but an explicit |type:number, |type:slider, or |type:checkbox declares the intended property type: the author's quotes (there to keep the raw template valid YAML, #1655) are consumed so Obsidian reads the typed value. |type:text and |type:multiline keep string semantics and their quotes.
…l control-char coverage
Anonymous {{VALUE}} substitutions and non-collected joined-array fallbacks
(VALUE/FIELD/FILE) now run through the same quoted-scalar escaping as named
tokens, and the double-quoted escape routine is shared with quoteYamlDouble
and covers all C0/DEL control characters.
…oted-token-escaping
Investigating #1655: the console warning comes from Obsidian's own YAML parser reading the raw template file -
Title: {{VALUE:fileName}}is not valid YAML, so Obsidian complains when it indexes the template. QuickAdd can't suppress that, and the community-suggested workaround (wrap the token in quotes) is the right call. This PR makes the quoted form fully safe and useful:1. Escaping (
cf9cb3e5). QuickAdd substituted the answer verbatim inside the author's quotes, so a value containing the quote character corrupted the created note's frontmatter -Title: "{{VALUE:fileName}}"answered withMy "Great" NotewroteTitle: "My "Great" Note", which Obsidian cannot parse (the note loses all its properties). VALUE and FIELD substitutions are now escaped when the token exactly spans an author-quoted sole-value scalar: double-quoted scalars get the|type:textescaping rules (\"and control characters), single-quoted scalars get YAML's''. Everywhere else (unquoted scalars, partial values like"prefix {{VALUE:x}}", note bodies) the value passes through byte-identical.2. Explicit
|type:consumes the quotes (b354c8a1). A quoted token normally writes a string - and stays that way, so released setups likeid: "{{VALUE:id}}"keeping0042intact are untouched. But when the token declares|type:number,|type:slider, or|type:checkbox, the declared type wins: the author's quotes are consumed andrating: "{{VALUE:r|type:number}}"writesrating: 42, which Obsidian reads as a Number. So a template can be both warning-free (quoted) and correctly typed.|type:textand|type:multilinedeclare string semantics and keep their quotes (with escaping).Verified live in Obsidian 1.13.4 (escaping): a template with
Title: "{{VALUE:fileName}}"/author: '{{VALUE:who}}'answered withMy "Great" Note/O'BriencreatesTitle: "My \"Great\" Note"/author: 'O''Brien', and Obsidian reads both properties back as the exact strings. On master the same run produces unparseable frontmatter.Also adds a docs section to the Template choice page explaining the warning, the quoting recipe, and the
|type:interaction.pnpm test(4872 tests incl. unit + formatter regression coverage for both behaviors),pnpm build-with-lintpass.Refs #1655
Summary by CodeRabbit
Bug Fixes
Documentation