From 6e5d27c6c321c4ddab2ba7ed19ad08388a704b2f Mon Sep 17 00:00:00 2001 From: John <43506685+Coniferish@users.noreply.github.com> Date: Tue, 15 Aug 2023 11:35:54 -0500 Subject: [PATCH] fix pdf partition of list items being detected as titles in OCR only mode (#1119) Closes Github issue #1010 adds group_bullet_paragraph func to handle grouping of bullet items that are split across multiple lines --- CHANGELOG.md | 13 +++++++ example-docs/list-item-example.pdf | Bin 0 -> 48981 bytes test_unstructured/cleaners/test_core.py | 24 ++++++++++++ .../azure/rfc854.txt.json | 22 +---------- unstructured/__version__.py | 2 +- unstructured/cleaners/core.py | 35 +++++++++++++++++- unstructured/nlp/patterns.py | 3 ++ 7 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 example-docs/list-item-example.pdf diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c08ad94e1..2790c6c274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.9.4-dev0 + + +### Enhancements + + +### Features + + +### Fixes +* fix pdf partition of list items being detected as titles in OCR only mode + ## 0.9.3 ### Enhancements @@ -18,6 +30,7 @@ ### Fixes +* fix pdf partition of list items being detected as titles in OCR only mode * make notion module discoverable * fix emails with `Content-Distribution: inline` and `Content-Distribution: attachment` with no filename * Fix email attachment filenames which had `=` in the filename itself diff --git a/example-docs/list-item-example.pdf b/example-docs/list-item-example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c540662d490042fcb811ec9f5f3f96e2f6bc95d4 GIT binary patch literal 48981 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 O1}0ciQXv^(*#8BCIJ&$5 literal 0 HcmV?d00001 diff --git a/test_unstructured/cleaners/test_core.py b/test_unstructured/cleaners/test_core.py index fa8e29f58c..3f2b7a7775 100644 --- a/test_unstructured/cleaners/test_core.py +++ b/test_unstructured/cleaners/test_core.py @@ -209,6 +209,30 @@ def test_group_broken_paragraphs_non_default_settings(): ) +def test_group_broken_paragraphs_with_bullets(): + text = """○The big red fox +is walking down the lane. + +○At the end of the lane +the fox met a friendly bear.""" + assert core.group_bullet_paragraph(text) == [ + "○The big red fox is walking down the lane. ", + "○At the end of the lane the fox met a friendly bear.", + ] + + +def test_group_bullet_paragraph_with_e_bullets(): + text = """e The big red fox +is walking down the lane. + +e At the end of the lane +the fox met a friendly bear.""" + assert core.group_bullet_paragraph(text) == [ + "· The big red fox is walking down the lane. ", + "· At the end of the lane the fox met a friendly bear.", + ] + + @pytest.mark.parametrize( # NOTE(yuming): Tests combined cleaners ( diff --git a/test_unstructured_ingest/expected-structured-output/azure/rfc854.txt.json b/test_unstructured_ingest/expected-structured-output/azure/rfc854.txt.json index 54e26ec6b6..1570f04bf6 100644 --- a/test_unstructured_ingest/expected-structured-output/azure/rfc854.txt.json +++ b/test_unstructured_ingest/expected-structured-output/azure/rfc854.txt.json @@ -604,30 +604,12 @@ }, { "type": "ListItem", - "element_id": "19d8999a73cdba6f00747d214f1ef31b", + "element_id": "d5bf23fd7f622ba14b5dd626721d0388", "metadata": { "data_source": {}, "filetype": "text/plain" }, - "text": "NOTE: A \"print position\" may contain several characters" - }, - { - "type": "NarrativeText", - "element_id": "85231efbe0f659114b09387f8dfd695f", - "metadata": { - "data_source": {}, - "filetype": "text/plain" - }, - "text": "which are the result of overstrikes, or of sequences such as" - }, - { - "type": "Title", - "element_id": "17548c22a23e66db7798c82919b49bc0", - "metadata": { - "data_source": {}, - "filetype": "text/plain" - }, - "text": " BS ..." + "text": "NOTE: A \"print position\" may contain several characters which are the result of overstrikes, or of sequences such as BS ..." }, { "type": "Title", diff --git a/unstructured/__version__.py b/unstructured/__version__.py index a909ec339b..466b935c2e 100644 --- a/unstructured/__version__.py +++ b/unstructured/__version__.py @@ -1 +1 @@ -__version__ = "0.9.3" # pragma: no cover +__version__ = "0.9.4-dev0" # pragma: no cover diff --git a/unstructured/cleaners/core.py b/unstructured/cleaners/core.py index a32c481d99..49c206844b 100644 --- a/unstructured/cleaners/core.py +++ b/unstructured/cleaners/core.py @@ -8,10 +8,12 @@ ) from unstructured.nlp.patterns import ( DOUBLE_PARAGRAPH_PATTERN_RE, + E_BULLET_PATTERN, LINE_BREAK_RE, PARAGRAPH_PATTERN, PARAGRAPH_PATTERN_RE, UNICODE_BULLETS_RE, + UNICODE_BULLETS_RE_0W, ) @@ -66,6 +68,34 @@ def clean_ordered_bullets(text) -> str: return text_cl +def group_bullet_paragraph(paragraph: str) -> list: + """Groups paragraphs with bullets that have line breaks for visual/formatting purposes. + For example: + + '''○ The big red fox + is walking down the lane. + + ○ At the end of the lane + the fox met a friendly bear.''' + + Gets converted to + + '''○ The big red fox is walking down the lane. + ○ At the end of the land the fox met a bear.''' + """ + clean_paragraphs = [] + # pytesseract converts some bullet points to standalone "e" characters. + # Substitute "e" with bullets since they are later used in partition_text + # to determine list element type. + paragraph = (re.sub(E_BULLET_PATTERN, "·", paragraph)).strip() + + bullet_paras = re.split(UNICODE_BULLETS_RE_0W, paragraph) + for bullet in bullet_paras: + if bullet: + clean_paragraphs.append(re.sub(PARAGRAPH_PATTERN, " ", bullet)) + return clean_paragraphs + + def group_broken_paragraphs( text: str, line_split: re.Pattern = PARAGRAPH_PATTERN_RE, @@ -97,8 +127,9 @@ def group_broken_paragraphs( # http://www.apache.org/licenses/ para_split = line_split.split(paragraph) all_lines_short = all(len(line.strip().split(" ")) < 5 for line in para_split) - if UNICODE_BULLETS_RE.match(paragraph.strip()): - clean_paragraphs.extend(re.split(PARAGRAPH_PATTERN, paragraph)) + # pytesseract converts some bullet points to standalone "e" characters + if UNICODE_BULLETS_RE.match(paragraph.strip()) or E_BULLET_PATTERN.match(paragraph.strip()): + clean_paragraphs.extend(group_bullet_paragraph(paragraph)) elif all_lines_short: clean_paragraphs.extend([line for line in para_split if line.strip()]) else: diff --git a/unstructured/nlp/patterns.py b/unstructured/nlp/patterns.py index c9175e99ea..92bcecba3c 100644 --- a/unstructured/nlp/patterns.py +++ b/unstructured/nlp/patterns.py @@ -59,6 +59,9 @@ ] BULLETS_PATTERN = "|".join(UNICODE_BULLETS) UNICODE_BULLETS_RE = re.compile(f"(?:{BULLETS_PATTERN})(?!{BULLETS_PATTERN})") +# zero-width positive lookahead so bullet characters will not be removed when using .split() +UNICODE_BULLETS_RE_0W = re.compile(f"(?={BULLETS_PATTERN})(?