Problem statement
Settings → Import & export → Replace with a file reads Markdown and applies it with setContent. A line like:

becomes an image node with src and alt only. width and height stay empty.
The editor then paints the picture at IMAGE_LAYOUT_FALLBACK (320×240). On the desktop sheet that is about 39% of the 830px writing column, and it forces a 4:3 box onto 16:9 art.
This showed up while replacing /demo from PROPOSAL-demo/DEMO.md. The live local page stores every illustration at 830×467. The Markdown file cannot name that size, and the importer has no other place to read it from.
Alt works.  stores alt.
The italic line under the picture works. That is a following paragraph, not the image node.
The toolbar caption field does not. Common Markdown has no syntax for the node caption attribute. The local demo does not use that field (all 17 pictures have an empty caption). Out of scope here unless a later slice adds a Markdown convention for it.
HTML such as <img width="830" height="467"> is not a workaround today: the importer treats that tag as plain text.
Proposed solution
On Markdown import (and the Settings replace path that consumes it), an image with no width / height should land at a size that fills the writing column and keeps the picture's real aspect ratio.
A reader who imports DEMO.md should see the same column-width pictures they see on http://localhost:3000/demo, without dragging sixteen resize handles.
How we get the size is an implementation choice. Do not stamp a fixed 830×467 on every imported image: that squashes anything that is not 16:9.
Candidates to evaluate in the work, not to pick now:
- After the image loads, commit
naturalWidth / naturalHeight fitted to the editor column.
- Teach the Markdown parse to keep
width / height when the source can name them, if we add a syntax that marked actually emits.
Alternatives considered
- Drag each picture to the sheet edge after import. Works. Does not scale.
- Write Tiptap JSON through
PATCH /content. Keeps size, video, audio, and embeds. Not the Settings Markdown path.
- Change
IMAGE_LAYOUT_FALLBACK to 830×467. That would resize every unsized picture in the product, including small ones.
Impact
Anyone who replaces a document from .md (the public demo, and later users). The demo page is the first document that needs this.
Acceptance criteria
Related gaps (not this ticket)
Markdown import also turns uploaded video, uploaded audio, and the six embed URLs into links. The live /demo page holds real video / audio / provider nodes. File those as their own tasks when we pick them up.
Additional context
- Fallback:
extensions/extension-hypermultimedia IMAGE_LAYOUT_FALLBACK = { width: 320, height: 240 }.
- Column:
56rem sheet minus 1px border and sm:p-8 each side = 830px.
- Apply path: Settings
applyStaged → editor.commands.setContent(sanitizeJsonContent(...)). The conversion API already returned JSON; the editor then rejects or paints what it is given.
- Repro file:
PROPOSAL-demo/DEMO.md.
Checklist
Problem statement
Settings → Import & export → Replace with a file reads Markdown and applies it with
setContent. A line like:becomes an
imagenode withsrcandaltonly.widthandheightstay empty.The editor then paints the picture at
IMAGE_LAYOUT_FALLBACK(320×240). On the desktop sheet that is about 39% of the 830px writing column, and it forces a 4:3 box onto 16:9 art.This showed up while replacing
/demofromPROPOSAL-demo/DEMO.md. The live local page stores every illustration at 830×467. The Markdown file cannot name that size, and the importer has no other place to read it from.Alt works.
storesalt.The italic line under the picture works. That is a following paragraph, not the image node.
The toolbar caption field does not. Common Markdown has no syntax for the node
captionattribute. The local demo does not use that field (all 17 pictures have an emptycaption). Out of scope here unless a later slice adds a Markdown convention for it.HTML such as
<img width="830" height="467">is not a workaround today: the importer treats that tag as plain text.Proposed solution
On Markdown import (and the Settings replace path that consumes it), an image with no
width/heightshould land at a size that fills the writing column and keeps the picture's real aspect ratio.A reader who imports
DEMO.mdshould see the same column-width pictures they see onhttp://localhost:3000/demo, without dragging sixteen resize handles.How we get the size is an implementation choice. Do not stamp a fixed 830×467 on every imported image: that squashes anything that is not 16:9.
Candidates to evaluate in the work, not to pick now:
naturalWidth/naturalHeightfitted to the editor column.width/heightwhen the source can name them, if we add a syntax thatmarkedactually emits.Alternatives considered
PATCH /content. Keeps size, video, audio, and embeds. Not the Settings Markdown path.IMAGE_LAYOUT_FALLBACKto 830×467. That would resize every unsized picture in the product, including small ones.Impact
Anyone who replaces a document from
.md(the public demo, and later users). The demo page is the first document that needs this.Acceptance criteria
PROPOSAL-demo/DEMO.mdthrough Settings → Replace with a file leaves each/demo-assets/dN-*.pngfilling the writing column, 16:9, not 320×240.altand the italic line under the picture still survive import.code+linkon one run of text stays invalid; do not reintroduce[/path](/path).width: 100%; max-width: {width}pxstill shrinks with the column.Related gaps (not this ticket)
Markdown import also turns uploaded video, uploaded audio, and the six embed URLs into links. The live
/demopage holds realvideo/audio/ provider nodes. File those as their own tasks when we pick them up.Additional context
extensions/extension-hypermultimediaIMAGE_LAYOUT_FALLBACK={ width: 320, height: 240 }.56remsheet minus 1px border andsm:p-8each side = 830px.applyStaged→editor.commands.setContent(sanitizeJsonContent(...)). The conversion API already returned JSON; the editor then rejects or paints what it is given.PROPOSAL-demo/DEMO.md.Checklist