marker icon indicating copy to clipboard operation
marker copied to clipboard

Help to identify why some of the text is missing in markdown output

Open kozer opened this issue 10 months ago • 2 comments

I have noticed that somehow, part of the text does not make it in the text output, in the following document.

test.pdf

Note, that the language used in this doc, is Greek.

Output

## ΒΙΟΛΟΓΙΑ Α' ΛΥΚΕΙΟΥ

![](_page_0_Picture_1.jpeg)

Το λεμφικό σύστημα αποτελείται από τα λεμφαγγεία, τη λέμφο και τους λεμφαδένες. Οι λεμφαδένες είναι δομές που αποτελούνται από εξειδικευμένη μορφή συνδετικού ιστού, το λεμφικό ιστό, και περιέχουν πολλά λεμφοκύτταρα και μακροφάγα. Στο λεμφικό σύστημα περιλαμβάνονται ο σπλήνας και ο θύμος αδένας (εικ.4.1). Το λεμφικό σύστημα είναι πολύ ση-
**TEXT IS MISSING IN THE LINE ABOVE, after ση-**

εικ. 4.1 Λεμφικό σύστημα του ανθρώπου

- παραλαμβάνει το πλεόνασμα του μεσοκυττάριου υγρού και το επαναφέρει στο καρδιαγγειακό σύ-
**TEXT IS MISSING IN THE LINE ABOVE, after συ-**
- μεταφέρει τις λιπαρές ουσίες από το λεπτό έντερο στο αίμα.
- συμβάλλει στην άμυνα του οργανισμού με την καταστροφή παθογόνων μικροοργανισμών και καρκινικών κυττάρων.

I used pdfium2 by it's own, and the text is extracted just fine using it.

The code I used to produce this markdown is the following:


def create_processor_config():
    """Creates a flat configuration dictionary with correct block type mappings for all processors."""
    from marker.schema import BlockTypes

    return {
        # Builder params
        "lowres_image_dpi": 600,
        "highres_image_dpi": 600,
        "disable_ocr": False,
        "layout_batch_size": None,
        "layout_coverage_min_lines": 1,
        "layout_coverage_threshold": 0.25,
        "document_ocr_threshold": 0.8,
        "excluded_for_coverage": (
            BlockTypes.Figure,
            BlockTypes.Picture,
            BlockTypes.Table,
            BlockTypes.FigureGroup,
            BlockTypes.TableGroup,
            BlockTypes.PictureGroup,
        ),
        "force_layout_block": None,
        "recognition_batch_size": None,
        "detection_batch_size": None,
        "languages": None,
        "enable_table_ocr": True,
        # Individual processor block_types
        "order_processor_block_types": tuple(),
        "blockquote_processor_block_types": (
            BlockTypes.Text,
            BlockTypes.TextInlineMath,
        ),
        "code_processor_block_types": (BlockTypes.Code,),
        "document_toc_processor_block_types": (BlockTypes.SectionHeader,),
        "equation_processor_block_types": (BlockTypes.Equation,),
        "footnote_processor_block_types": (BlockTypes.Footnote,),
        "ignore_text_processor_block_types": (
            BlockTypes.Text,
            BlockTypes.SectionHeader,
            BlockTypes.TextInlineMath,
        ),
        "line_numbers_processor_block_types": (
            BlockTypes.Text,
            BlockTypes.TextInlineMath,
        ),
        "list_processor_block_types": (BlockTypes.ListGroup,),
        "page_header_processor_block_types": (BlockTypes.PageHeader,),
        "section_header_processor_block_types": (BlockTypes.SectionHeader,),
        "table_processor_block_types": (
            BlockTypes.Table,
            BlockTypes.TableOfContents,
            BlockTypes.Form,
        ),
        "llm_table_processor_block_types": (
            BlockTypes.Table,
            BlockTypes.TableOfContents,
        ),
        "llm_table_merge_processor_block_types": (
            BlockTypes.Table,
            BlockTypes.TableOfContents,
        ),
        "llm_form_processor_block_types": (BlockTypes.Form,),
        "text_processor_block_types": (BlockTypes.Text, BlockTypes.TextInlineMath),
        "llm_text_processor_block_types": (BlockTypes.TextInlineMath,),
        "llm_complex_region_processor_block_types": (BlockTypes.ComplexRegion,),
        "llm_image_description_processor_block_types": (
            BlockTypes.Picture,
            BlockTypes.Figure,
        ),
        "llm_equation_processor_block_types": (BlockTypes.Equation,),
        "llm_handwriting_processor_block_types": (
            BlockTypes.Handwriting,
            BlockTypes.Text,
        ),
        "reference_processor_block_types": None,
        "debug_processor_block_types": tuple(),
        # Other processor-specific params
        "min_x_indent": 0.05,
        "x_start_tolerance": 0.01,
        "x_end_tolerance": 0.01,
        "model_max_length": 768,
        "texify_batch_size": None,
        "token_buffer": 256,
        "common_element_threshold": 0.2,
        "common_element_min_blocks": 3,
        "max_streak": 3,
        "text_match_threshold": 90,
        "strip_numbers_threshold": 0.6,
        "min_lines_in_block": 4,
        "min_line_length": 10,
        "gap_threshold": 0.05,
        "list_gap_threshold": 0.1,
        "ignored_block_types": (BlockTypes.PageHeader, BlockTypes.PageFooter),
        # LLM params
        "google_api_key": "",
        "model_name": "gemini-2.0-flash",
        "max_retries": 1,
        "max_concurrency": 3,
        "timeout": 15,
        "image_expansion_ratio": 0.01,
        "use_llm": False,
        "disable_tqdm": False,
        # LLM processor specific params
        "min_equation_height": 0.08,
        "equation_image_expansion_ratio": 0.05,
        "max_rows_per_batch": 60,
        "max_table_rows": 175,
        "table_image_expansion_ratio": 0.0,
        "table_height_threshold": 0.6,
        "table_start_threshold": 0.2,
        "vertical_table_height_threshold": 0.25,
        "vertical_table_distance_threshold": 20,
        "horizontal_table_width_threshold": 0.25,
        "horizontal_table_distance_threshold": 10,
        "column_gap_threshold": 50,
        # Debug params
        "debug_data_folder": "debug_data",
        "debug_layout_images": False,
        "debug_pdf_images": False,
        "debug_json": False,
        "render_font": "",
        "font_dl_path": "https://github.com/satbyy/go-noto-universal/releases/download/v7.0",
        # Section header params
        "level_count": 4,
        "merge_threshold": 0.25,
        "default_level": 2,
        "height_tolerance": 0.99,
        # Table params
        "detect_boxes": False,
        "table_rec_batch_size": None,
        "pdftext_workers": 4,
        "row_split_threshold": 0.5,
        "contained_block_types": (BlockTypes.Text, BlockTypes.TextInlineMath),
        # Text processor params
        "column_gap_ratio": 0.02,
        # PDF provider params
        "page_range": None,
        "flatten_pdf": True,
        "force_ocr": True,
        "ocr_invalid_chars": ("�", "�"),
        "ocr_space_threshold": 0.7,
        "ocr_newline_threshold": 0.6,
        "ocr_alphanum_threshold": 0.3,
        "image_threshold": 0.65,
        "strip_existing_ocr": False,
        "disable_links": False,
        # Renderer params
        "image_blocks": (BlockTypes.Picture, BlockTypes.Figure),
        "page_blocks": (BlockTypes.Page,),
        "extract_images": True,
        "image_extraction_mode": "highres",
        "paginate_output": False,
        "page_separator": "-" * 48,
        "inline_math_delimiters": ("$", "$"),
        "block_math_delimiters": ("$$", "$$"),
    }

        config = {
            "output_format": "markdown",
        }

        config_parser = ConfigParser(config)

        converter = PdfConverter(
            config=create_processor_config(),
            artifact_dict=create_model_dict(),
            processor_list=config_parser.get_processors(),
            renderer=config_parser.get_renderer(),
        )

Can you:

  • Help me to identify why I have the above problem?
  • Is there a way to use pdfium2 to extract the text instead of relying to the models?
  • Can you pinpoint me to the place where this extraction is happening, and maybe a high level overview to dig more?
  • Is there a way to use pdfium2 for text, and let the models only worry about tables, images, equations etc?

Thanks a lot!

kozer avatar Feb 17 '25 09:02 kozer

I triaged the issue a bit, and I think I see how it happens. Focusing on the - παραλαμβάνει το πλεόνασμα του μεσοκυττάριου υγρού και το επαναφέρει στο καρδιαγγειακό σύ- omission: with convert_pdf_to_markdown() as the entry point, the string "στημα" is missing after the call to PdfConverter.build_document(filepath). Looking at the LineBuilder in DocumentBuilder, the "στημα" is indeed present in provider_lines. So it is not a pdftext/pdfium2 issue. But it is missing after LineBuilder.merge_blocks()

The omitted block is index 36 of 44 in the provider outputs. Looking at PageGroup.compute_line_block_intersections, the bbox is assigned to a Figure. With Figures, I know that the default strategy is to ignore text spans assigned to Figures (as observed, the labels do not appear). Indeed, the other omitted text, μαντικό γιατί:\n, also heavily overlaps with the figure bbox.

To fix the issue, maybe an idea is to have PageGroup.compute_line_block_intersections prioritize Text and ListItem over Figure? Or perhaps, the first pass could assign text spans to text blocks, and the second pass assigns text spans to figures.

A possible fix is 50b4b4f96021a16bdf25dfc3e476df6046481d9a.

I get this output:

Κεφάλαιο 4

**4. ΛΕΜΦΙΚΟ ΣΥΣΤΗΜΑ**

![](_page_0_Figure_2.jpeg)

*εικ. 4.1 Λεμφικό σύστημα του ανθρώπου*

BIBLIO MA8HTH.indd 71 9/5/2013 11:39:57 πμ

Το λεμφικό σύστημα αποτελείται από τα λεμφαγγεία, τη λέμφο και τους λεμφαδένες. Οι λεμφαδένες είναι δομές που αποτελούνται από εξειδικευμένη μορφή συνδετικού ιστού, το λεμφικό ιστό, και περιέχουν πολλά λεμφοκύτταρα και μακροφάγα. Στο λεμφικό σύστημα περιλαμβάνονται ο σπλήνας και ο θύμος αδένας (εικ.4.1).

Το λεμφικό σύστημα είναι πολύ σημαντικό γιατί:

- παραλαμβάνει το πλεόνασμα του μεσοκυττάριου υγρού και το επαναφέρει στο καρδιαγγειακό σύστημα.
- μεταφέρει τις λιπαρές ουσίες από το λεπτό έντερο στο αίμα.
- συμβάλλει στην άμυνα του οργανισμού με την καταστροφή παθογόνων μικροοργανισμών και καρκινικών κυττάρων.

Note that the newer version also includes BIBLIO MA8HTH.indd 71 9/5/2013 11:39:57 πμ, so that is not a regression.

conjuncts avatar Feb 20 '25 03:02 conjuncts

I triaged the issue a bit, and I think I see how it happens. Focusing on the - παραλαμβάνει το πλεόνασμα του μεσοκυττάριου υγρού και το επαναφέρει στο καρδιαγγειακό σύ- omission: with convert_pdf_to_markdown() as the entry point, the string "στημα" is missing after the call to PdfConverter.build_document(filepath). Looking at the LineBuilder in DocumentBuilder, the "στημα" is indeed present in provider_lines. So it is not a pdftext/pdfium2 issue. But it is missing after LineBuilder.merge_blocks()

The omitted block is index 36 of 44 in the provider outputs. Looking at PageGroup.compute_line_block_intersections, the bbox is assigned to a Figure. With Figures, I know that the default strategy is to ignore text spans assigned to Figures (as observed, the labels do not appear). Indeed, the other omitted text, μαντικό γιατί:\n, also heavily overlaps with the figure bbox.

To fix the issue, maybe an idea is to have PageGroup.compute_line_block_intersections prioritize Text and ListItem over Figure? Or perhaps, the first pass could assign text spans to text blocks, and the second pass assigns text spans to figures.

A possible fix is 50b4b4f.

I get this output:

Κεφάλαιο 4

**4. ΛΕΜΦΙΚΟ ΣΥΣΤΗΜΑ**

![](_page_0_Figure_2.jpeg)

*εικ. 4.1 Λεμφικό σύστημα του ανθρώπου*

BIBLIO MA8HTH.indd 71 9/5/2013 11:39:57 πμ

Το λεμφικό σύστημα αποτελείται από τα λεμφαγγεία, τη λέμφο και τους λεμφαδένες. Οι λεμφαδένες είναι δομές που αποτελούνται από εξειδικευμένη μορφή συνδετικού ιστού, το λεμφικό ιστό, και περιέχουν πολλά λεμφοκύτταρα και μακροφάγα. Στο λεμφικό σύστημα περιλαμβάνονται ο σπλήνας και ο θύμος αδένας (εικ.4.1).

Το λεμφικό σύστημα είναι πολύ σημαντικό γιατί:

- παραλαμβάνει το πλεόνασμα του μεσοκυττάριου υγρού και το επαναφέρει στο καρδιαγγειακό σύστημα.
- μεταφέρει τις λιπαρές ουσίες από το λεπτό έντερο στο αίμα.
- συμβάλλει στην άμυνα του οργανισμού με την καταστροφή παθογόνων μικροοργανισμών και καρκινικών κυττάρων.

Note that the newer version also includes BIBLIO MA8HTH.indd 71 9/5/2013 11:39:57 πμ, so that is not a regression.

This totally fixes the issue! However, the current master branch doesn't. Thanks a lot!

kozer avatar Feb 20 '25 06:02 kozer