fix: handle CommonMark fenced code boundaries - #12373
Conversation
|
@adityat210 is attempting to deploy a commit to the deepset Team on Vercel. A member of the Team first needs to authorize it. |
|
Hi @adityat210, thanks a lot for your contribution! 🙏 We noticed that the Contributor License Agreement (CLA) check ( To get your PR reviewed, please sign the CLA via the link in the |
|
Thanks for signing the CLA, @adityat210! 🎉 This PR is now ready for review again and the reviewer has been re-assigned. |
anakin87
left a comment
There was a problem hiding this comment.
Thank you!
I found 2 minor opportunities for improvement.
| fixes: | ||
| - | | ||
| Fixed ``MarkdownHeaderSplitter`` treating hash-prefixed lines inside indented, unclosed, or | ||
| longer-delimiter fenced code blocks as Markdown headers. |
There was a problem hiding this comment.
Let's also specify that now an unclosed fence is treated as extending to the end of the document, so hash lines after it are no longer split into chunks.
| # CommonMark allows up to three spaces before an opening fence. A backtick fence's info | ||
| # string cannot itself contain a backtick; that condition is checked while scanning. | ||
| self._code_block_open_pattern = re.compile(r" {0,3}(?P<fence>`{3,}|~{3,})(?P<info>[^\r\n]*)") | ||
| self._code_block_close_pattern = re.compile(r" {0,3}(?P<fence>`{3,}|~{3,})[ \t]*") |
There was a problem hiding this comment.
| self._code_block_close_pattern = re.compile(r" {0,3}(?P<fence>`{3,}|~{3,})[ \t]*") | |
| self._code_block_close_pattern = re.compile(r" {0,3}(?P<fence>`{3,}|~{3,})\s*") |
I'd keep using \s* as the previous regex: this should work well with documents containing page breaks.
Please also add a test similar to this:
def test_page_break_after_closing_fence(self):
text = "# Real Header\n```python\n# not a header\n```\f\n## Real Sub\nContent.\n"
...
Related Issues
Proposed Changes
MarkdownHeaderSplitterpreviously matched an entire fenced code block with a regex whose closing delimiter had to be identical to the opener. Valid Markdown with a longer closing fence, up to three spaces of fence indentation, or no closing fence therefore exposed hash-prefixed code lines to the header matcher.This PR:
The behavior aligns with the CommonMark fenced code block specification.
Measured on the three minimal reproductions:
Real,fake,NextReal,NextReal,fake,NextReal,NextReal,fakeRealFalse header metadata across these cases drops from 3 to 0. There is no public API change.
How did you test it?
hatch run fmt-check haystack/components/preprocessors/markdown_header_splitter.py test/components/preprocessors/test_markdown_header_splitter.pyhatch run pre-commit run --files haystack/components/preprocessors/markdown_header_splitter.py test/components/preprocessors/test_markdown_header_splitter.py releasenotes/notes/markdown-fence-boundaries-20f1dacc1efec6c8.yamlhatch run reno lintNotes for the reviewer
#lines within code blocks #11011. The adjacent fix in fix: MarkdownHeaderSplitter drops content before an embedded header or code-fence comment #11920 prevents content loss during secondary splitting; it does not change fence boundary detection.MarkdownHeaderSplitter,_code_block_spans,_code_block_pattern, closing/unclosed/longer fence terminology, and fenced-code header variants found no open overlapping issue or PR.Checklist