Context
While working on bd-xdnk (plumbing doctemplate diagnostics through quarto render so undefined-variable warnings reach the user), it became clear that making the warnings visible is only half the story. Once they show up, users will reasonably ask: "what's the cleanest way to silence one I actually meant to be optional?"
Today the answer is to wrap each reference in a guard:
$if(author-greeting)$$author-greeting$$endif$
This is verbose, repeats the variable name, and obscures the intent ("this variable is optional") behind boilerplate. With the warning surfaced, every optional reference becomes a place users will reach for the suppression — so the cost compounds.
Proposal
A short suffix-? form that is exactly equivalent to the $if$/$endif$ wrapper:
would render the variable's value if the variable is defined and truthy, and produce nothing (no diagnostic) otherwise.
Feasibility (already studied)
I sketched the implementation while doing bd-xdnk so we'd know whether this is a small-ish lift or a re-design. Notes from the plan (see claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md § Follow-up):
? is unused as a sigil in the current grammar. Pipes use / as their separator (tree-sitter-doctemplate/grammar/grammar.js:84-86).
- No collision with any existing pipe name:
pairs, first, last, rest, allbutlast, uppercase, lowercase, length, reverse, chomp, nowrap, alpha, roman, left, center, right.
- Implementation cost is small: one new grammar token, one
bool optional field on VariableRef, one branch in render_variable that returns Doc::Empty silently when optional is set and the lookup fails (skipping the warn_or_error_with_code(\"Q-10-2\", ...) call).
- Behavioral parity with
$if(var)$$var$$endif$ is exact for scalar values. For lists/maps, the $if$ truthy semantics already match is_truthy(), so no surprises there.
Open design questions for discussion
-
Spelling. Suffix $variable?$ reads as "optional variable" and keeps pipes pure value-to-value. The alternative $variable/?$ would treat ? as a degenerate pipe in the existing repeat(seq(\"/\", $.pipe)) chain — more uniform syntactically, but ? doesn't transform a value, it changes resolution semantics, so the suffix form feels more honest.
-
Applied partials. Should ? propagate to applied partials ($var?:partial()$ — render the partial only if var is defined)? Probably yes, same intent. Not applicable to $if$ itself.
-
Should existing built-in templates adopt it? Phase 0 of bd-xdnk found the built-in MINIMAL_HTML_TEMPLATE and FULL_HTML_TEMPLATE are clean (every $var$ is already wrapped in $if(...)$). If $variable?$ lands, those wrappers could collapse for readability — but that's a stylistic choice, not load-bearing.
-
Pandoc compatibility. Pandoc's template syntax (which we are mostly compatible with) does not have this. Adopting ? is a Q2 extension. We should weigh "qmd is a dialect, this is a useful extension" against "users may copy templates between Pandoc and qmd and now hit a parse error in one direction." (The Pandoc parser would treat $variable?$ as just a literal $variable?$ — variable name variable?, which is also invalid syntax in their grammar — so we need to be deliberate about the divergence.)
Why now, why this issue
Not asking for an implementation decision — just asking for a place to discuss before deciding whether to build it.
The bd-xdnk work uncovered the use case in a concrete way (warning noise on optional metadata variables in custom templates), but the syntax decision is the kind of thing that benefits from more eyes. If you're a Quarto contributor and you have an opinion on grammar extensions, optional-variable ergonomics, or Pandoc-compat tradeoffs, please weigh in here.
Internal tracking: bd-x5r4 (linked discovered-from to bd-xdnk).
Context
While working on bd-xdnk (plumbing doctemplate diagnostics through
quarto renderso undefined-variable warnings reach the user), it became clear that making the warnings visible is only half the story. Once they show up, users will reasonably ask: "what's the cleanest way to silence one I actually meant to be optional?"Today the answer is to wrap each reference in a guard:
This is verbose, repeats the variable name, and obscures the intent ("this variable is optional") behind boilerplate. With the warning surfaced, every optional reference becomes a place users will reach for the suppression — so the cost compounds.
Proposal
A short suffix-
?form that is exactly equivalent to the$if$/$endif$wrapper:would render the variable's value if the variable is defined and truthy, and produce nothing (no diagnostic) otherwise.
Feasibility (already studied)
I sketched the implementation while doing bd-xdnk so we'd know whether this is a small-ish lift or a re-design. Notes from the plan (see
claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md§ Follow-up):?is unused as a sigil in the current grammar. Pipes use/as their separator (tree-sitter-doctemplate/grammar/grammar.js:84-86).pairs,first,last,rest,allbutlast,uppercase,lowercase,length,reverse,chomp,nowrap,alpha,roman,left,center,right.bool optionalfield onVariableRef, one branch inrender_variablethat returnsDoc::Emptysilently whenoptionalis set and the lookup fails (skipping thewarn_or_error_with_code(\"Q-10-2\", ...)call).$if(var)$$var$$endif$is exact for scalar values. For lists/maps, the$if$truthy semantics already matchis_truthy(), so no surprises there.Open design questions for discussion
Spelling. Suffix
$variable?$reads as "optional variable" and keeps pipes pure value-to-value. The alternative$variable/?$would treat?as a degenerate pipe in the existingrepeat(seq(\"/\", $.pipe))chain — more uniform syntactically, but?doesn't transform a value, it changes resolution semantics, so the suffix form feels more honest.Applied partials. Should
?propagate to applied partials ($var?:partial()$— render the partial only ifvaris defined)? Probably yes, same intent. Not applicable to$if$itself.Should existing built-in templates adopt it? Phase 0 of bd-xdnk found the built-in
MINIMAL_HTML_TEMPLATEandFULL_HTML_TEMPLATEare clean (every$var$is already wrapped in$if(...)$). If$variable?$lands, those wrappers could collapse for readability — but that's a stylistic choice, not load-bearing.Pandoc compatibility. Pandoc's template syntax (which we are mostly compatible with) does not have this. Adopting
?is a Q2 extension. We should weigh "qmd is a dialect, this is a useful extension" against "users may copy templates between Pandoc and qmd and now hit a parse error in one direction." (The Pandoc parser would treat$variable?$as just a literal$variable?$— variable namevariable?, which is also invalid syntax in their grammar — so we need to be deliberate about the divergence.)Why now, why this issue
Not asking for an implementation decision — just asking for a place to discuss before deciding whether to build it.
The bd-xdnk work uncovered the use case in a concrete way (warning noise on optional metadata variables in custom templates), but the syntax decision is the kind of thing that benefits from more eyes. If you're a Quarto contributor and you have an opinion on grammar extensions, optional-variable ergonomics, or Pandoc-compat tradeoffs, please weigh in here.
Internal tracking: bd-x5r4 (linked
discovered-fromto bd-xdnk).