Chemical Notation OCR#
Chemical notation — including molecular formulas, structural diagrams, and reaction equations — is a known area of reduced OCR accuracy in Docling, with the sharpest failures occurring when chemical structure images appear alongside text in table cells. The problems split into two categories:
- General misrecognition of chemical symbols by the underlying OCR engine (EasyOCR, RapidOCR)
- Table-context failures where a chemical structure image in one cell causes content to bleed into adjacent cells
The canonical issue is docling #1299: Multi-line cell table with image fails to OCR correctly.
Table Cell Bleeding: The Primary Failure Mode#
The most impactful failure is cell content bleeding: a chemical structure image in one table column contaminates the OCR output of a neighboring text column. Documented examples from pharmaceutical tables :
| Expected | Actual (OCR off) | Actual (OCR on) |
|---|---|---|
1-45C | 1 - HO_ 45€ | 1 - HO 45c |
1-72F | Full adjacent chemical name bleeds in | 1- (truncated) |
Root cause: TableFormer's cell-grid binding requires a ≥30% bounding-box overlap (textcell_overlap = 0.3) between a predicted table cell and a page text region . When a cell contains an embedded chemical structure image, the image bbox and the text bbox overlap ambiguously, causing misassignment of content across cells.
Switching between RapidOCR and EasyOCR shifts which cells are wrong but does not eliminate the errors . Toggling do_code_enrichment and do_formula_enrichment also does not resolve the issue .
How Docling Handles Chemical Content#
Docling does have explicit chemical notation support, but it applies to standalone chemical elements detected by the layout model — not to chemical structures embedded inside table cells.
- The Chandra OCR parser recognizes
"Chemical-Block"as a distinct layout label and maps it toDocItemLabel.FORMULA. - VLM prompts use
<chem>...</chem>tags with reactive SMILES notation, and<chem>is an explicitly whitelisted tag inCHANDRA_ALLOWED_TAGS. - The
do_formula_enrichmentpipeline option (default:False) enables VLM-based formula recognition via theCodeFormulaVlmModel. Enabling this processesDocItemLabel.FORMULAelements, not table-cell-embedded structures.
There are no chemical-notation-specific OCR models in Docling today; the <chem> handling is VLM-prompt-level post-processing, not a dedicated chemistry OCR layer.
Open Issues and In-Progress Work#
Several tracked issues and PRs are relevant to the long-term resolution of these limitations:
- docling-core #172 — Requests nesting support (inline formulas, images) in table cells and captions. A maintainer explicitly noted the need for image support inside table cells.
- PR: feat: enable rich tables — Introduces
RichTableCelltype allowing table cells to hold images and other nested content. Merged 2025-08-27. - PR: feat: add get_cell_image method to TableItem — Adds an API to extract individual table cell images as crops. Open (as of 2026-07).
- PR #3107: fix: Use OCR cells with TableFormer v2 — Improves how OCR-derived cells are consumed in TableFormer V2, reducing some cell-matching failures. Merged 2026-03-11.
keep_empty_clustersoption (commita436be7) — Adds aLayoutOptions.keep_empty_clustersflag (defaultFalse) that controls retention of empty clusters during layout postprocessing, which may help with empty-cell edge cases.
Workarounds#
Until rich table cell support and improved cell-image binding land fully:
- Use an external OCR service — AWS Textract correctly handles the pharmaceutical table cases that Docling misreads . Docling has an OCR plugin architecture; substituting a more capable backend may reduce errors.
- Image-based extraction — Export the page as a high-resolution image (
generate_page_images=True,images_scale≥ 2.0) and crop cells using their bounding-box provenance. This bypasses the text-cell binding step entirely. TableFormerMode.ACCURATE— Usetable_structure_options.mode = TableFormerMode.ACCURATEwithdo_cell_matching=True; it is the best available mode even though it does not fully resolve the issue.- Post-process with
get_cell_image— Once PR #652 is merged, use the newTableItem.get_cell_image()method to retrieve visual crops of individual cells for downstream chemistry OCR tools (e.g., OSRA, MolScribe).
Key Source References#
| Resource | Purpose |
|---|---|
| docling #1299 | Primary bug report with reproduction case |
| docling-core #172 | Inline formula/image nesting in table cells |
chandra_utils.py | Chemical-Block → FORMULA label mapping |
vlm_prompts.py | <chem> / SMILES VLM prompt definition |
table_structure_model_v2.py | 30% overlap threshold for cell binding |
pipeline_options.py | do_formula_enrichment option |