quarto-dev / quarto-dev/quarto-cli
default-image-extension: per-image opt-out and existence-based resolution for extensionless sources
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 458
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
Follow-up to #6092. PR #14634 fixes the two provably-spurious cases (shortcode double-extension #14583, and empty-filename URLs like https://example.com/), but the original #6092 report — badge / API URLs such as https://bestpractices.coreinfrastructure.org/projects/1882/badge — is deliberately left untouched.
The reason: Quarto sets default-image-extension as a Pandoc reader option, and Pandoc appends it at parse time to any extensionless source that isn't a data: URI (no URL guard in Pandoc). After parsing, .../badge becomes .../badge.png, which is byte-identical to a user-typed .../badge.png pointing at a real file. There is no way to tell the two apart, and a remote URL cannot be stat-checked offline at render time. So auto-detection is not possible for these.
Two complementary opt-in mechanisms could close the remaining gap:
Remote URLs — explicit per-image opt-out
For remote sources where the user knows there is no extension (badges, image APIs, embeds), an explicit marker lets them assert it:
{.no-img-ext}
A Lua filter would strip exactly one appended default-image-extension suffix when the marker is present, then consume the marker so it does not leak into output. This is additive and does not change the default, so it is safe outside a release-cycle boundary. Today the only escape is default-image-extension: "", which is document/project-wide and cannot be scoped to a single image in a doc that also relies on the multi-format behaviour.
Local files — resolve by existence (#6092 "option C")
For local sources, the extension could be resolved against the filesystem instead of appended unconditionally: if path/figure.{default} does not exist but path/figure does, use the extensionless file.
This is the long-term direction discussed in #6092. It needs care:
- Path resolution must use the correct base (project dir, resource paths) — a false "doesn't exist" would strip a working extension and silently regress documents that render fine today.
- Multi-format targets generated later in the pipeline will not exist when the filter runs, so the strip condition must be conservative (only when the default-extension target is provably absent and the extensionless file provably present).
Per the discussion in #6092, changing this default-adjacent behaviour should land at the start of a release cycle.
Related: #6092, #14583, #14634.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing where Quarto sets the Pandoc default-image-extension reader option and where its Lua filters process images; review #6092, #14583, and #14634 for constraints. Done means supporting the .no-img-ext remote-image opt-out and conservative existence-based local resolution without changing the existing default behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, lua, markdown
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100