fix(html_table): keep a declared rowspan of zero on empty cells (#4611)
## Summary
`HtmlCell.html` lost a declared `rowspan="0"` whenever the cell had no
text, while keeping it when the same cell had text.
`HtmlCell.rowspan` reports `None` for `rowspan="0"` and documents it as
HTML's spelling for *"spans every remaining row in the containing row
group"*, but the empty-cell branch went through `_format_td("",
self.colspan, self.rowspan or 1)`, and `_format_td` only emits the
attribute when `rowspan > 1`. The declared span was silently downgraded
to a one-row cell:
```python
HtmlCell(fragment_fromstring('<td rowspan="0">a</td>')).html # '<td rowspan="0">a</td>'
HtmlCell(fragment_fromstring('<td rowspan="0"></td>')).html # '<td/>'
```
## Fix
* `_format_td()` now omits `rowspan` only when it is the implicit
default `1`, so a `rowspan` of `0` is emitted
(`unstructured/common/html_table.py`, `_format_td`).
* `HtmlCell.html` passes `0` for the `None` that represents
`rowspan="0"` instead of collapsing it with `or 1`, and the docstring of
`_format_td` says so.
With the fix both spellings round-trip:
```python
cell = HtmlCell(fragment_fromstring('<td colspan="2" rowspan="0"></td>'))
cell.html # '<td colspan="2" rowspan="0"/>'
HtmlCell(...).rowspan # None again after a round-trip
```
## Tests
`test_unstructured/common/test_html_table.py`:
* added
`DescribeHtmlCell::and_it_preserves_a_rowspan_of_zero_on_an_empty_cell`,
next to the existing empty-cell span test.
Before / after on `test_unstructured/common/test_html_table.py`:
```text
before: 1 failed, 51 passed in 2.18s (the new test)
after: 52 passed in 2.06s
```
No other test edited; the rest of `test_unstructured/common` plus the
chunking suites stay green.
## Notes
The cell has to be empty to show the bug.
`unstructured/chunking/base.py::own_cell_html` currently recomputes the
remaining span for empty cells, so chunked output is not immediately
wrong — what is lost is the serialization contract of `HtmlCell.html`
(and the `len(cell.html)` bookkeeping in `BaseChunker`, plus any caller
that re-parses the produced HTML).
Fixes #4610