Repository navigation
Description
Summary
A link or image destination that contains a space is silently rewritten to its %20-encoded form on save, and the ProseMirror document itself changes (no round-trip fixpoint at the PM level). The angle-bracket destination the author wrote — the only CommonMark form that carries a space verbatim — is never re-emitted.
Evidence (verified 2026-10-26 on main 786d2129, standalone verbatim-codec probe)
Probe: hidden_files/probe-2026-10-26-1615/out4.log (crate = current pkgs/id/src/web/markdown.rs copied verbatim + round-trip harness).
Markdown → PM → markdown:
IN : "[notes](<my notes.md>)\n"
PM : href "my notes.md"
OUT: "[notes](my%20notes.md)\n"
PM2: href "my%20notes.md" SAMEPM: false
IN : "\n"
PM : src "my pic.png"
OUT: "\n"
PM2: src "my%20pic.png" SAMEPM: false
PM → markdown shows the same: an editor-created link with href: "https://e.com/a b" saves as [t](https://e.com/a%20b) and reparses with the mutated href (probe case link-href-space, out3.log).
Why it matters
The codec passes destinations verbatim in both directions (markdown.rs:299 parse arm copies link.url into the PM href; markdown.rs:1223 save arm copies it back into NodeLink.url) — the mutation happens in comrak's CommonMark renderer, which percent-encodes a space in a bare destination instead of emitting the <…> angle form. For an absolute URL the encoded form usually still resolves, but for a relative file link — the common case in id's own documents — my%20notes.md names a file that does not exist, so one save silently breaks the link. It also means the editor's in-memory href and the file's href diverge after the first save.
Acceptance criteria
- Round trip preserves a destination containing a space exactly:
[notes](<my notes.md>)saves byte-identically (angle form retained), and PM → markdown → PM returns the identicalhref/src. - Same for image
src. - Destinations without spaces are unchanged; existing web::markdown tests pass.
Suggested direction
The fix layer needs a triage decision: comrak's renderer offers no angle-destination option, so options are (a) a targeted post-process of the rendered output for destinations known (from the AST) to contain spaces, (b) pre-render substitution with a placeholder that is restored afterwards, or (c) documenting + normalizing on the parse side instead (accept %20 in PM as canonical — but that still rewrites the user's file on first save). Any of these beats the current silent mutation; (a)/(b) preserve the file.
Activity
developing-today commentedon Oct 26, 2026
CODE-180
dezren39 commentedon Oct 26, 2026
🤖 Agent note · filed
6 remaining items
dezren39 commentedon Oct 26, 2026
🤖 Agent note · picked up
Merge pull request #1022 from developing-today/queue/1181-1019-spaced…
dezren39 commentedon Oct 26, 2026
🤖 Agent note · done
76672b97df023607d8469d462f21420604fe92d5) after the merge-resolution commit2ffe5d7ewent CI-green (all checks pass, merge state CLEAN). Issue auto-closed by the merge. The fix (placeholder substitution around the comrak render, restoring spaced destinations in<...>form, by lane A) plus the id(web): footnotes are backslash-escaped on save — [^1] syntax mangled, definition orphaned #945 footnote tests kept through the conflict resolution are both on main.