You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 nodata-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:
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.
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.
Worth deciding whether the raw fallback should also fire for tables that are nearly expressible (e.g. a single rowspan) or whether to degrade those cells — the former is safer and simpler.
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 thanalign-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, andreaddestroys it.Part 1 — document it
Verified behavior on the publish path (probed locally, all three shapes come out intact):
<table>block passes through verbatim, includingdata-table-width,data-layout,<colgroup>/<col>widths,data-highlight-colour,rowspan, and<p style="text-align: right;">.<table>being a goldmark HTML block (which normally ends at a blank line).<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:
data-layout="align-start"onto a raw table. The author owns every attribute — including the layout.<colgroup>on a table with nodata-layoutmakes Confluence default the layout tofull-width, so a raw table with column widths must always carry an explicitdata-layoutor it silently goes edge-to-edge. Also: px widths are honored with or withoutdata-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.mdcurrently contains no table at all, so nothing pins this behavior.Part 2 — make it round-trip
renderTableininternal/convert/storage_to_md.gorenders 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 readreturns:Everything is gone: all cell backgrounds,
data-layout: center,data-table-width, the colgroup, and thetext-aligncell alignment. Soread→ edit →updatesilently 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
readalready handles unmapped macros and column layouts:data-highlight-colourback 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.Deliverables: a
raw-tablecase added toTestRoundTripPassthroughinstorage_to_md_test.go(read → publish → read is stable), plus forward-path regression coverage.Notes
rowspan) or whether to degrade those cells — the former is safer and simpler.