Skip to content

Raw storage tables: document the escape hatch and make it round-trip #55

Description

@willkg

Context

With cell background colors landing in #54, markdown covers the table features people ask for most. What it still can't express: explicit column widths (<colgroup>/<col>), data-table-width, a layout other than align-start (center/wide/full-width), rowspan/colspan, and per-cell alignment (that one's #48).

For those, the escape hatch is pasting a raw storage <table> into the markdown — the same thing we already tell people to do for macros and layouts. It works today, but it's undocumented, and read destroys it.

Part 1 — document it

Verified behavior on the publish path (probed locally, all three shapes come out intact):

  • A <table> block passes through verbatim, including data-table-width, data-layout, <colgroup>/<col> widths, data-highlight-colour, rowspan, and <p style="text-align: right;">.
  • Blank lines inside the table don't break it. The blank line is dropped and the structure survives, despite <table> being a goldmark HTML block (which normally ends at a blank line).
  • Markdown inside a <td> is converted when separated by blank lines — the same convention as <ac:layout-cell>. Tight against the tags it stays literal.

Two gotchas worth documenting alongside, from the empirical table-format work:

  • markfluence does not stamp its usual data-layout="align-start" onto a raw table. The author owns every attribute — including the layout.
  • A <colgroup> on a table with no data-layout makes Confluence default the layout to full-width, so a raw table with column widths must always carry an explicit data-layout or it silently goes edge-to-edge. Also: px widths are honored with or without data-table-width, but percentage widths require it (they're resolved against it, and are silently ignored without it).

Deliverables: a README subsection under the raw-storage docs, and a regression case — testdata/regression/raw-storage/main.md currently contains no table at all, so nothing pins this behavior.

Part 2 — make it round-trip

renderTable in internal/convert/storage_to_md.go renders every table as a bare GFM pipe table and ignores all attributes. Reading a complex page proves the cost — on page 2913502220 (21 colored cells, three layouts, a distributed-column table), markfluence read returns:

| **header 1** | **header 2** |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- |
| data | data | data | data | data | data | data |

Everything is gone: all cell backgrounds, data-layout: center, data-table-width, the colgroup, and the text-align cell alignment. So read → edit → update silently strips a hand-built table — which makes the escape hatch a trap rather than a hatch, since it can't be documented as safe until this is fixed.

Proposed rule, consistent with how read already handles unmapped macros and column layouts:

  1. If a table only uses what markdown can express, emit a GFM table. Cell backgrounds are now expressible, so map data-highlight-colour back to a <!-- bg:COLOR --> marker (preferring the swatch name, falling back to the hex). Alignment joins this list once Table cell alignment is silently dropped when publishing #48 lands.
  2. Otherwise emit the table verbatim as raw storage, so it round-trips exactly.

Deliverables: a raw-table case added to TestRoundTripPassthrough in storage_to_md_test.go (read → publish → read is stable), plus forward-path regression coverage.

Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions