| 1 |
|
package doc |
| 2 |
|
|
| 3 |
|
import ( |
| 4 |
|
"github.com/yuin/goldmark/ast" |
| 5 |
|
"github.com/yuin/goldmark/extension" |
| 6 |
|
east "github.com/yuin/goldmark/extension/ast" |
| 7 |
|
"github.com/yuin/goldmark/renderer" |
| 8 |
|
"github.com/yuin/goldmark/renderer/html" |
| 9 |
|
"github.com/yuin/goldmark/util" |
| 10 |
|
) |
| 11 |
|
|
| 12 |
|
// tableRenderer wraps every GFM table in a horizontally scrollable box. |
| 13 |
|
// |
| 14 |
|
// A `<table>` will not shrink below its min-content width, and specs have |
| 15 |
|
// tables whose cells are bare URLs — an unbreakable 70-character token each. |
| 16 |
|
// Inside the page grid's `minmax(0,1fr)` column such a table simply overflows |
| 17 |
|
// its cell and paints on top of the table-of-contents rail. The wrapper is a |
| 18 |
|
// block box that does honour the column width, so the overflow becomes a scroll |
| 19 |
|
// bar on the table instead of a collision with the rail. |
| 20 |
|
// |
| 21 |
|
// Two nested divs rather than one: the review UI hangs per-block affordances in |
| 22 |
|
// the left gutter of every top-level child of .prose, and the scrolling box — |
| 23 |
|
// their containing block — would clip an absolutely positioned handle. The |
| 24 |
|
// outer div takes the block role, the inner one does the scrolling. |
| 25 |
|
// |
| 26 |
|
// Only the table element itself is overridden; rows, cells, and the alignment |
| 27 |
|
// handling stay with goldmark's own renderer. |
| 28 |
|
type tableRenderer struct{} |
| 29 |
|
|
| 30 |
|
// tableRendererPriority beats the GFM table renderer's 500. goldmark registers |
| 31 |
|
// node renderers from the lowest priority number last, so the last write to a |
| 32 |
|
// node kind — and thus the winner — is the smaller number. |
| 33 |
|
const tableRendererPriority = 100 |
| 34 |
|
|
| 35 |
22 |
func (tableRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { |
| 36 |
22 |
reg.Register(east.KindTable, renderTable) |
| 37 |
22 |
} |
| 38 |
|
|
| 39 |
4 |
func renderTable(w util.BufWriter, _ []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { |
| 40 |
4 |
if entering { |
| 41 |
2 |
_, _ = w.WriteString(`<div class="table-block"><div class="table-scroll"><table`) |
| 42 |
2 |
if n.Attributes() != nil { |
| 43 |
0 |
html.RenderAttributes(w, n, extension.TableAttributeFilter) |
| 44 |
0 |
} |
| 45 |
2 |
_, _ = w.WriteString(">\n") |
| 46 |
2 |
} else { |
| 47 |
2 |
_, _ = w.WriteString("</table></div></div>\n") |
| 48 |
2 |
} |
| 49 |
4 |
return ast.WalkContinue, nil |
| 50 |
|
} |