Repository navigation
fix: split Markdown lines like markdown-it does - #191
Open
OsamaAnsar wants to merge 1 commit into
Open
OsamaAnsar wants to merge 1 commit into
OsamaAnsar wants to merge 1 commit into
Conversation
markdown_sentence_boundaries and markdown_chunklet_boundaries convert the line numbers in markdown-it's `token.map` into character offsets by splitting the document into lines with `str.splitlines`. That method also splits on the vertical tab, form feed, file/group/record separators, NEL, U+2028 and U+2029, whereas markdown-it only treats LF, CRLF and CR as line endings. A document containing any of those characters (e.g., a form feed in text extracted from a PDF) therefore got shifted line offsets, so heading spans and paragraph boundary probabilities landed on the wrong sentences. Split lines with a regex that only recognises LF, CRLF and CR instead. For documents that only contain those line endings the result is identical to `str.splitlines(keepends=True)`.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
markdown_sentence_boundaries(_split_sentences.py) andmarkdown_chunklet_boundaries(_split_chunklets.py) turn markdown-it'stoken.mapline numbers into character offsets by splitting the document withdoc.splitlines(keepends=True).markdown-it only treats LF, CRLF and CR as line endings (it normalises CRLF/CR to LF and nothing else), but
str.splitlinesalso splits on\x0b,\x0c,\x1c-\x1e,\x85,\u2028and\u2029. If a document contains any of these characters (for example a form feed in text extracted from a PDF), the line index built fromsplitlineshas more entries than markdown-it's, so everytoken.mapline after that point is converted to the wrong character offset. Heading spans and paragraph/heading boundary probabilities then land on the wrong text.Reproduction (on
main, markdown-it-py 4.2.0, Python 3.12, Windows)Heading span marked by
markdown_sentence_boundariesfor"Intro paragraph one." + sep + "Intro paragraph two continues here.\n\n# Real Heading\n\nBody text after the heading.\n":markdown_chunklet_boundaries(["intro\x0c", "para2\n\n", "# Real Heading\n\n", "body"]):Fix
Split lines with
re.findall(r"[^\r\n]*(?:\r\n|\r|\n)|[^\r\n]+", doc), which recognises exactly the line endings that markdown-it does. For text that only contains LF, CRLF and CR this returns the same list asdoc.splitlines(keepends=True)(checked against 200,000 random strings overa,b, space,\n,\r,\r\n,#, and a non-ASCII letter, plus the empty string), so normal documents are unaffected._markdown.py:175also callssplitlines, but on a regex match of ATX heading lines and not on anything tied totoken.map, so I left it alone.I found nothing in the open or closed issues/PRs about this specific cause. #81 touched the same function (heading boundary probabilities) for an out-of-bounds problem; this is a separate misalignment.
Tests
New parametrized tests in
tests/test_split_sentences.pyandtests/test_split_chunklets.pycover LF, CRLF, CR and each of the other separators listed above, without needing the sentence splitter model.src/restored tomain): 16 of the 22 new cases fail (all the exotic separators); the LF/CRLF/CR cases pass, as expected.What I ran
pytest tests/test_split_chunklets.py tests/test_split_sentences.py tests/test_markdown.py tests/test_import.py tests/test_split_chunks.py: 50 passed (Python 3.12.10, Windows 11).pytest src testswithCI=1(skipsslow) andHF_HUB_OFFLINE=1: 68 passed (46 onmain, +22 new). The same 9 failures and 30 errors occur onmainand on this branch; all of them are tests that need to download the Qwen3/bge-m3 llama.cpp models (OfflineModeIsEnabled). 97 tests were skipped (PostgreSQL / OpenAI key not available).pre-commit runon the changed files (ruff check, ruff format, mypy, commitizen, the other hooks): passed.pre-commit run --all-filesfails onmainand on this branch alike withICN001insrc/raglite/_database.pyunder ruff 0.17.1 (the version I had installed); I did not touch that.lowest-directresolution were not tested, nor was PostgreSQL.