textconv: recover Docling captions nested under tables/pictures (1016)
Browse files- app/textconv.py +16 -2
app/textconv.py
CHANGED
|
@@ -77,6 +77,8 @@ def grid_markdown(grid) -> str:
|
|
| 77 |
|
| 78 |
# ---------------------------------------------------------------- Docling (PDF only)
|
| 79 |
|
|
|
|
|
|
|
| 80 |
def convert_docling(pdf: Path):
|
| 81 |
from docling.datamodel.base_models import InputFormat
|
| 82 |
from docling.datamodel.pipeline_options import PdfPipelineOptions
|
|
@@ -107,8 +109,20 @@ def convert_docling(pdf: Path):
|
|
| 107 |
continue
|
| 108 |
label = item.label.value
|
| 109 |
if isinstance(item, (TableItem, PictureItem)):
|
| 110 |
-
for cref in item.captions
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
B.add(one_line(cap.text), "caption", boxes(cap))
|
| 113 |
if isinstance(item, TableItem):
|
| 114 |
md = grid_markdown([[c.text for c in row] for row in item.data.grid])
|
|
|
|
| 77 |
|
| 78 |
# ---------------------------------------------------------------- Docling (PDF only)
|
| 79 |
|
| 80 |
+
CAPTION_START = re.compile(r"(Fig\.?|Figure|FIGURE|Table|TABLE)\s*S?\d+[A-Za-z]?\b")
|
| 81 |
+
|
| 82 |
def convert_docling(pdf: Path):
|
| 83 |
from docling.datamodel.base_models import InputFormat
|
| 84 |
from docling.datamodel.pipeline_options import PdfPipelineOptions
|
|
|
|
| 109 |
continue
|
| 110 |
label = item.label.value
|
| 111 |
if isinstance(item, (TableItem, PictureItem)):
|
| 112 |
+
caps = [cref.resolve(doc) for cref in item.captions]
|
| 113 |
+
# Docling 有时把图注挂在表 / 图的子节点里、不登记进 captions(traverse_pictures=False 会整个跳过), 这里补回(1016)。
|
| 114 |
+
# 只收 label=caption, 或以 "Fig./Figure/Table + 编号" 开头的子节点文字(会被错标成 footnote / text);
|
| 115 |
+
# 图内其余文字(坐标轴、图例)不收。
|
| 116 |
+
seen = {c.self_ref for c in caps}
|
| 117 |
+
for ch, _ in doc.iterate_items(root=item, traverse_pictures=True):
|
| 118 |
+
txt = one_line(getattr(ch, "text", ""))
|
| 119 |
+
if ch is item or ch.self_ref in seen or not txt:
|
| 120 |
+
continue
|
| 121 |
+
if ch.label.value == "caption" or CAPTION_START.match(txt):
|
| 122 |
+
caps.append(ch)
|
| 123 |
+
seen.add(ch.self_ref)
|
| 124 |
+
owned.add(ch.self_ref) # 主循环之后若再遇到同一节点, 不再输出第二遍
|
| 125 |
+
for cap in caps:
|
| 126 |
B.add(one_line(cap.text), "caption", boxes(cap))
|
| 127 |
if isinstance(item, TableItem):
|
| 128 |
md = grid_markdown([[c.text for c in row] for row in item.data.grid])
|