diff --git a/pkg/prosemirror/html_block.go b/pkg/prosemirror/html_block.go index e7468856c..636631e0e 100644 --- a/pkg/prosemirror/html_block.go +++ b/pkg/prosemirror/html_block.go @@ -462,7 +462,11 @@ func (c *htmlBlockConverter) convertTableRow(tr *html.Node) (*Node, error) { } func (c *htmlBlockConverter) convertTableCell(n *html.Node, typ NodeType) (*Node, error) { - attrs, err := json.Marshal(TableCellAttrs{}) + cellAttrs := TableCellAttrs{ + Colspan: tableSpanFromHTML(n, "colspan"), + Rowspan: tableSpanFromHTML(n, "rowspan"), + } + attrs, err := json.Marshal(cellAttrs) if err != nil { return nil, fmt.Errorf("cannot marshal table cell attrs: %w", err) } @@ -598,3 +602,18 @@ func attrVal(n *html.Node, key string) string { } return "" } + +// tableSpanFromHTML reads colspan or rowspan from a table cell element. +// Missing, invalid, or non-positive values yield 1, matching HTML defaults +// and ProseMirror/Tiptap cell attrs. +func tableSpanFromHTML(n *html.Node, key string) int { + s := strings.TrimSpace(attrVal(n, key)) + if s == "" { + return 1 + } + v, err := strconv.Atoi(s) + if err != nil || v < 1 { + return 1 + } + return v +} diff --git a/pkg/prosemirror/markdown_test.go b/pkg/prosemirror/markdown_test.go index 400341015..7cc91cb34 100644 --- a/pkg/prosemirror/markdown_test.go +++ b/pkg/prosemirror/markdown_test.go @@ -428,6 +428,31 @@ func TestParseMarkdown_BlockHTMLTable(t *testing.T) { require.Len(t, doc.Content[0].Content[0].Content, 2) assert.Equal(t, NodeTableHeader, doc.Content[0].Content[0].Content[0].Type) assert.Equal(t, NodeTableCell, doc.Content[0].Content[0].Content[1].Type) + + thAttrs, err := doc.Content[0].Content[0].Content[0].TableCellAttrs() + require.NoError(t, err) + assert.Equal(t, 1, thAttrs.Colspan) + assert.Equal(t, 1, thAttrs.Rowspan) + + tdAttrs, err := doc.Content[0].Content[0].Content[1].TableCellAttrs() + require.NoError(t, err) + assert.Equal(t, 1, tdAttrs.Colspan) + assert.Equal(t, 1, tdAttrs.Rowspan) +} + +func TestParseMarkdown_BlockHTMLTableCellSpans(t *testing.T) { + t.Parallel() + + md := `
X
` + "\n" + doc, err := ParseMarkdown(md) + require.NoError(t, err) + require.Len(t, doc.Content, 1) + cell := doc.Content[0].Content[0].Content[0] + require.Equal(t, NodeTableCell, cell.Type) + attrs, err := cell.TableCellAttrs() + require.NoError(t, err) + assert.Equal(t, 3, attrs.Colspan) + assert.Equal(t, 2, attrs.Rowspan) } func TestParseMarkdown_BlockHTMLScriptRemovedKeepsSafeContent(t *testing.T) {