Raw storage tables: document the escape hatch and make it round-trip
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2
- Forks
- 0
- Avg merge
- 2h 8m
- Merged PRs (30d)
- 49
Description
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, includingdata-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-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.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-colourback to a<!-- bg:COLOR -->marker (preferring the swatch name, falling back to the hex). Alignment joins this list once #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.
Notes
- The alignment half of (1) depends on #48.
- 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with README raw-storage documentation, testdata/regression/raw-storage/main.md, and renderTable in internal/convert/storage_to_md.go. Read storage_to_md_test.go, especially TestRoundTripPassthrough and its raw-table case, then run the round-trip and forward-path regression tests. Done means documented raw-table behavior and stable read → publish → read output without losing unsupported table attributes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, documentation, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100