quarto-dev / quarto-dev/q2

Optional-variable syntax for doctemplate: $variable?$

Open
#158 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement templates
Dominant language
Rust
Stars
255
Forks
17
Avg merge
6h 20m
Merged PRs (30d)
109

Description

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:

$variable?$

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

  1. 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.

  2. 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.

  3. 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.

  4. 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).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md § Follow-up, then inspect tree-sitter-doctemplate/grammar/grammar.js and the VariableRef/render_variable entry points described there. Done means reaching and documenting a decision on suffix spelling, applied-partial behavior, built-in templates, and Pandoc compatibility before implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, rust
Domain
compilers, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.