Skip to content

fix(rag): escape Excel Markdown table cells - #2528

Merged
DavdGao merged 2 commits into
agentscope-ai:mainfrom
MaxFreedomPollard:fix/excel-markdown-table-cells
Sep 7, 2026
Merged

DavdGao merged 2 commits into
agentscope-ai:mainfrom
MaxFreedomPollard:fix/excel-markdown-table-cells

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

AgentScope Version

2.0.8 (main, base commit 41ba021)

Description

ExcelParser renders a sheet through its own cell formatter, _fmt at src/agentscope/rag/_parser/_excel.py:419, which escapes the pipe character and nothing else. Two ordinary kinds of spreadsheet cell corrupt the table it produces.

A cell containing a line break (alt+enter in Excel) ends the Markdown row early. _extract_table_data normalises CRLF to LF at _excel.py:74 and keeps the break, so the text after it lands on its own physical line and the row is cut short there.

A cell containing a backslash in front of a pipe loses a column. Path \| label is escaped to Path \\| label, and Markdown reads \\ as a literal backslash and the | after it as an unescaped column separator, so one cell renders as two.

WordParser and PPTParser are not affected: both render through the shared _format_markdown_table_cell in src/agentscope/rag/_parser/_utils.py:50, which escapes backslashes and pipes and turns line breaks into <br>. The Excel path predates that helper and was never switched over to it.

Repro on main, with a sheet whose cells are A|B, Path \| label, 1|2 and Line 1\nLine 2:

| A\|B | Path \\| label |
| --- | --- |
| 1\|2 | Line 1
Line 2 |

After this change:

| A\|B | Path \\\| label |
| --- | --- |
| 1\|2 | Line 1<br>Line 2 |

Change

_fmt calls _format_markdown_table_cell instead of its own single replace. The [A1] cell-coordinate prefix and the table_format="json" path are untouched, and cells with no pipe, backslash or line break render exactly as before.

Tests

Added ExcelParserTest.test_markdown_table_escapes_special_cells, which mirrors the Word and PPT tests of the same name and asserts the whole parsed Section dump. It fails on main (Path \\| label and the split row) and passes with the change.

python -m pytest tests/rag_parser_test.py -q
# 44 passed

python -m pytest tests/ -k rag -q
# 228 passed, 1 skipped

pre-commit run --files src/agentscope/rag/_parser/_excel.py tests/rag_parser_test.py
# all hooks passed

Run on macOS with Python 3.11, pandas 3.0.5 and openpyxl 3.1.5. The new test uses only _make_xlsx_simple, the helper the existing Excel tests already build workbooks with, so it needs nothing that CI does not already install.

Checklist

Please check the following items before code is ready to be reviewed.

  • An issue has been created for this PR
  • I have read the CONTRIBUTING.md
  • Docstrings are in Google style
  • Related documentation has been updated (e.g. links, examples, etc.) in documentation repository
  • Code is ready for review

MaxFreedomPollard and others added 2 commits September 6, 2026 11:32
ExcelParser._table_to_markdown has its own cell formatter
(src/agentscope/rag/_parser/_excel.py:428) that escapes only the pipe
character. Two kinds of cell content therefore corrupt the rendered
pipe-table:

- A cell containing a line break. _extract_table_data normalises CRLF to
  LF and keeps it, so the row is emitted across two physical lines and
  the table row is truncated at the break.
- A cell containing a backslash. "\|" is escaped to "\\|", which
  Markdown reads as a literal backslash followed by an unescaped column
  separator, so one cell becomes two.

WordParser and PPTParser render through the shared
_format_markdown_table_cell in _parser/_utils.py, which escapes
backslashes and pipes and renders line breaks as <br>. The Excel path
predates that helper and was never switched over.

Render Excel cells through the same helper. The cell-coordinate prefix
and the JSON table format are unchanged.
Inline the single-use XLSX builder into the test and drop the docstring
additions unrelated to the fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019vGQfv7bHuvpthdkdmmBAg

@DavdGao DavdGao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@DavdGao
DavdGao merged commit d8629a9 into agentscope-ai:main Sep 7, 2026
6 checks passed
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.

2 participants