ADR-0011: Unify image types to inline-only representation
Status: accepted | Date: 2026-02-19
References: ADR-0008
Context
Per ADR-0008, the codebase has four image-related variants:
HtmlElement::Image— block-level resolved imageHtmlElement::ImageMarker— block-level pending imageInlineFragment::InlineImage— inline resolved imageInlineFragment::ImageMarker— inline pending image
This creates redundancy: the same image data is represented in two places (HtmlElement vs InlineFragment).
Problem Statement
The block/inline distinction for images is a rendering concern, not a content concern. In HTML, <img> is always an inline element — the “block-level” appearance comes from the container (e.g., <p><img></p>), not the image itself.
Maintaining separate types for block and inline images:
- Duplicates code and logic
- Requires adapters to handle both variants
- Mixes content representation with presentation concerns
Constraints
- ADR-0008 established the ImageMarker pattern for deferred upload
- Adapters (Notion, Confluence) have different handling for block vs inline images
Options Considered
- Keep current design — 4 variants, explicit block/inline
- Unify to inline-only — Remove HtmlElement Image variants, detect single-image paragraphs at render time
Decision
We will remove HtmlElement::Image and HtmlElement::ImageMarker variants and unify image representation to inline-only because:
- Single source of truth: Images are always represented as
InlineFragment::InlineImageorInlineFragment::ImageMarker - Separation of concerns: IR represents content; adapters decide presentation (block vs inline rendering)
- Simpler parsing: Standalone
<img>elements parse asParagraph { fragments: [InlineImage] }
Implementation Notes
Parsing changes:
- Remove
parse_image()function fromblocks.rs <img>at block level becomesParagraphwith singleInlineImage
Adapter changes:
- Add helper function
is_single_image_paragraph(fragments: &[InlineFragment]) -> bool - Notion: Single-image paragraph → image block
- Confluence: Single-image paragraph →
<ac:image>block - HTML: All images render as
<img>
Consequences
Positive
- Simpler type system: 2 image variants instead of 4
- Clear separation: IR for content, adapters for presentation
- Easier maintenance: Single code path for image handling
Negative
- Adapters need to detect single-image paragraphs for special rendering (mitigation: provide helper function in adapters-core)
- Breaking change to IR structure (mitigation: we explicitly allow breaking changes per task description)
Neutral
- Standalone
<img>HTML producesParagraphinstead ofImageelement