Skip to content

fix(utils): keep every table cell in its column - #423

Open
L4XB wants to merge 1 commit into
HKUDS:mainfrom
L4XB:fix/table-body-cells
Open

L4XB wants to merge 1 commit into
HKUDS:mainfrom
L4XB:fix/table-body-cells

Conversation

@L4XB

@L4XB L4XB commented Oct 21, 2026

Copy link
Copy Markdown

Description

format_table_body turns list-shaped table_data into the Markdown table that goes into the table prompt (query.py, modalprocessors.py) and the table chunk (processor.py). That is the shape non-MinerU parsers and insert_content_list callers pass. It joined str(cell) with " | ", so four ordinary cell values broke the table:

format_table_body([["Name", "Qty", "Note"], ["pen", None, "a|b"], ["ink", 3, "two\nlines"], ["cap"]])
main:                          this PR:
| Name | Qty | Note |          | Name | Qty | Note |
| --- | --- | --- |             | --- | --- | --- |
| pen | None | a|b |            | pen |  | a\|b |
| ink | 3 | two                 | ink | 3 | two lines |
lines |                         | cap |  |  |
| cap |
  • An empty cell (None) read as the word "None".
  • A pipe inside a cell started an extra column.
  • A line break inside a cell ended the row, so lines | became a stray line.
  • A row shorter than the header stayed short.

Related Issues

None found. The list-of-lists rendering came with the content-list alias handling.

Changes Made

  • raganything/utils.py: a new _table_cell renders each cell. None becomes empty, | becomes \|, and a line break becomes a space. format_table_body now pads every row to the widest row. String table bodies and other shapes are unchanged.
  • tests/test_content_list_alias_handling.py: test_table_rows_keep_their_cells uses the table above. The existing [["A", "B"], ["C", "D"]] assertion still holds.

Checklist

  • Changes tested locally
  • Code reviewed
  • Documentation updated (if necessary)
  • Unit tests added (if applicable)

Additional Notes

  • The new test fails on main and passes here. Full pytest tests/ on Python 3.12: 899 passed.
  • pre-commit run (ruff-format, ruff, whitespace hooks) on both files: all hooks pass.
  • Side note: test_content_list_alias_handling.py cannot be run on its own on main. Its stub for raganything.parser has no HTML_FILE_EXTENSIONS, which processor.py imports since fix(parser): require Docling for HTML instead of converting it with LibreOffice #418. The stub is only installed when nothing imported the real module first, so the full suite passes and CI stays green. I left that alone here.

format_table_body renders list-shaped table_data as a Markdown table for
prompts and chunks. An empty cell (None) was written as "None", a pipe
inside a cell started a new column, a line break inside a cell ended the
row, and a row shorter than the header shifted nothing into place but
left the table ragged. Cells are now rendered by _table_cell: None is
empty, a pipe is escaped, a line break is a space, and short rows are
padded to the widest row.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant