Skip to content

id(web): table column alignment is dropped by the markdown ↔ ProseMirror codec — save rewrites the delimiter row #881

Closed

Description

@dezren39

Bug

In pkgs/id/src/web/markdown.rs, table column alignment (:---, :---:, ---:) is dropped by the markdown ↔ ProseMirror codec in both directions:

  • Parse direction: convert_node's NodeValue::Table arm (markdown.rs:~379 on main 45c817e) ignores the comrak NodeTable.alignments it already has in hand and emits a bare {"type":"table"} with no alignment information.
  • Save direction: json_to_ast's "table" arm (markdown.rs:~753) hardcodes alignments: vec![TableAlignment::None; num_columns], so comrak renders a plain |---| delimiter row regardless of the source.

Verified repro (this run, main 45c817e)

Temporary probe test run with cargo test --features web --lib web::markdown:: (probe removed after the run; assertions below are the acceptance tests):

Input markdown:

| a | b |
|:--|--:|
| 1 | 2 |
  1. markdown_to_prosemirror returns a table whose rows/cells carry no alignment anywhere:
    {"type":"table","content":[{"type":"table_row","content":[{"type":"table_header",...},{"type":"table_header",...}]}, ...]}
  2. prosemirror_to_markdown of that document emits:
| a | b |
| - | - |
| 1 | 2 |

Left/right alignment is gone after one load/save round trip — the document renders differently (numbers no longer right-aligned) with no error or warning.

Why it matters

Alignment is the only column-level formatting markdown tables have, and right-aligned numeric columns are the common case in notes/docs edited in the id web UI. Silent formatting loss on save, in the same codec family as #872/#873/#879/#880 but a distinct node (table metadata).

Suggested fix

  • Parse direction: carry the alignments through the ProseMirror representation — e.g. an alignments attr on the table node (["left","none","center","right", ...]), or per-cell attrs on the first row's header cells if the editor schema prefers cell-level data. Pick whichever the web editor schema can hold without breaking existing documents (absent = all None, as today).
  • Save direction: read that representation in json_to_ast's table arm and populate NodeTable.alignments (defaulting to None per column when absent or short), instead of the hardcoded vec![None; num_columns].

Acceptance criteria

Activity

  1. developing-today commented on Oct 25, 2026

    @developing-today
    Contributor
  2. dezren39 commented on Oct 25, 2026

    @dezren39
    MemberAuthor

    Verification note from the filer (new-issue-creator): this issue was re-verified in a corrected probe run on main 45c817e and genuinely reproduces, with one cosmetic correction to the quoted output.

    Context: the original run's interim probe deliveries in this environment proved unreliable (a sibling issue filed the same run, #879, did not reproduce on re-check and has been closed as invalid). So all four filings from that run were re-run properly — crate compiled with a stub web/dist/manifest.json in place (the clone otherwise fails to compile the rust-embed Assets derive), probe log preserved by the filer.

    Correction to the issue body: the emitted delimiter row is | --- | --- |, not | - | - | as quoted. Everything else matches: the ProseMirror table carries no alignment anywhere, and the round trip of

    | a | b |
    |:--|--:|
    | 1 | 2 |
    

    emits

    | a | b |
    | --- | --- |
    | 1 | 2 |
    

    — left/right alignment gone, as filed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions