feat: support all BFM formats in both inline and block reference directives#5323
Merged
lukemelia merged 1 commit intoJun 24, 2026
Conversation
…ctives Inline BFM reference directives (`:card[url]`) previously carried no size/format slot, so the renderer hardcoded them to atom; only block directives (`::card[url | spec]`) could express embedded / fitted / isolated / dimensions. This makes every format available in both placements. Grammar (runtime-common/bfm-card-references.ts): - parseBfmSizeSpec accepts `atom`; BfmSizeSpec.format gains 'atom'. - The inline tokenizer splits the bracket on `|` and captures the specifier; the inline renderer emits data-boxel-bfm-format/-width/ -height via a shared bfmSizeAttrs helper used by both renderers. - extractBfmReferences strips the specifier from inline URLs. - bfmBlockFormatAndSize becomes bfmRefFormatAndSize (now includes atom) with a defaultFormat parameter (block -> embedded, inline -> atom). Writer (base/markdown-helpers.ts): - markdownEmbedForCard honors the size option for inline embeds. Renderers (host rendered-markdown.gts + base markdown.gts): - Inline refs derive format/size from the data attributes instead of forcing atom. Resolved non-atom inline slots flow as inline-block; loading/broken inline placeholders adopt the derived footprint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
backspace
approved these changes
Jun 23, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Decouples BFM render format from placement so inline (:card[...]) and block (::card[...]) directives can both express any supported format/size, with placement-specific defaults (inline → atom, block → embedded).
Changes:
- Extended BFM size parsing/extraction/rendering to support
atomand inline| spec, emitting shareddata-boxel-bfm-format/width/heightattributes for both inline and block refs. - Updated markdown writer helper (
markdownEmbedForCard) to serialize inline embeds with an optional| sizespec. - Updated host + base markdown renderers to derive inline slot format/footprint from data attributes and render non-atom inline embeds as inline-block (with matching loading/broken placeholders), plus added/updated tests and docs.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/runtime-common/bfm-card-references.ts | Adds atom size parsing, inline ` |
| packages/base/markdown-helpers.ts | Allows inline embeds to include ` |
| packages/host/app/components/operator-mode/preview-panel/rendered-markdown.gts | Derives inline format/footprint from BFM data attrs; adds inline-embed slot/loading/broken behaviors and styles. |
| packages/base/default-templates/markdown.gts | Mirrors host renderer changes for base realm markdown rendering (format derivation + inline-embed flow/styling). |
| packages/host/tests/unit/bfm-card-references-test.ts | Adds coverage for inline pipe URL extraction, inline/block attribute emission (including atom), and bfmRefFormatAndSize defaulting behavior. |
| packages/host/tests/unit/markdown-helpers-test.ts | Updates expectations so inline embeds honor size, and adds an inline embedded size test. |
| packages/host/tests/integration/components/rendered-markdown-test.gts | Adds integration coverage for inline size/format attrs and unresolved inline footprint behavior (embedded/fitted/plain). |
| packages/host/tests/integration/components/rich-markdown-field-test.gts | Verifies resolved inline embeds use --inline-embed for non-atom while atom keeps --inline. |
| packages/boxel-cli/plugin/skills/dev-bfm-syntax/SKILL.md | Documents inline `:card[URL |
| packages/boxel-cli/plugin/skills/dev-markdown-format/SKILL.md | Updates helper table to document inline ` |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
FadhlanR
approved these changes
Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves CS-11704.
Why
BFM previously coupled render format to placement: the inline directive
:card[url]had no size/format slot, so it was hardcoded to atom; only the block directive::card[url | spec]could express embedded / fitted / isolated / dimensions. This decouples format from placement so every format works in both modes — the grammar ("dictionary") side of the Markdown Editing UI design.What changed
Grammar —
packages/runtime-common/bfm-card-references.tsparseBfmSizeSpecacceptsatom(and confirmsembedded/isolated);BfmSizeSpec.formatgains'atom'.|and captures the specifier; inline renderer emitsdata-boxel-bfm-format/-width/-heightvia a new sharedbfmSizeAttrshelper used by both the inline and block renderers.extractBfmReferencesstrips the specifier from inline URLs (so:card[url | spec]extracts just the URL).bfmBlockFormatAndSize→bfmRefFormatAndSize(BfmBlockFormat→BfmRefFormat, now includesatom) with adefaultFormatparam — block defaults toembedded, inline toatom.Writer —
packages/base/markdown-helpers.tsmarkdownEmbedForCardhonors thesizeoption for inline embeds (:card[id | embedded]).Renderers —
packages/host/.../rendered-markdown.gts+packages/base/default-templates/markdown.gts(kept in parallel)display: inline-block(new--inline-embedclass); loading/broken inline placeholders adopt the derived footprint. Plain (atom) inline refs are unchanged.Docs — updated the
dev-bfm-syntaxanddev-markdown-formatskill grammar tables to document inline specs and theatomspec.Acceptance criteria
:card[url | embedded],:card[url | 400x200], and::card[url | atom]all parse, extract, and render in the correct format and placement. ✅Scope note (read/grammar side only)
This is the partial-on-
mainslice agreed for CS-11704. The literalserializeBfmReffunction and themarkdown-embed-preview-panetest referenced in the ticket live only on the open PR #5303 (cs-11673) branch, not onmain, so they're deferred. Onmainthe writer ismarkdownEmbedForCard(which #5303 turns into aserializeBfmRefdelegate); the inline-size logic added here moves intoserializeBfmRefas a straightforward conflict resolution when #5303 lands, after which the chooser emits/previews inline-formatted embeds with no further change.Tests
bfm-card-references-test,markdown-helpers-test): inline pipe-extraction, inline renderer emits format/size attrs,parseBfmSizeSpec('atom'),bfmRefFormatAndSizeatom +defaultFormat, block| atom, "ignored for inline" flipped to "honored for inline".rendered-markdown-test): inline embedded/fitted/atom data-attr + broken-footprint cases.rich-markdown-field-test): real-card resolved inline embed asserts the--inline-embed(inline-block) slot class; atom ref keeps--inline.Verified locally with
ember-tsc(host + runtime-common), eslint, and ember-template-lint. The host QUnit suite runs on CI.🤖 Generated with Claude Code