_pdf_converter.py — PDF 轉換器

pdfminer 抽文字、pdfplumber 抽表格、外加一段「版面後處理」
檔案:packages/markitdown/src/markitdown/converters/_pdf_converter.py

大方向

PDF 沒有語意結構,所以這檔最「工程導向」:先嘗試用 pdfplumber 抽表格, 再與 pdfminer 的文字抽取互補;最後有一段 post-process 把「MasterFormat 風格的部分編號」 (.1.2…)與下一行合併,避免被版面切碎。


1. 後處理工具函數

_merge_partial_numbering_lines(text) post-process.1 等部分編號與後續文字合併回同一行。

MasterFormat 文件用 .1 The intent of this RFP... 這種部分編號; pdfminer 常把它切成 .1 換行再接內文。此函數用 regex 偵測並黏回。

_to_markdown_table(table) / fmt_row(row) 工具把二維 list 轉成 Markdown 表格(含分隔列)。

輸出 | c1 | c2 | + | --- | --- | 分隔列,處理格內換行與空值。

_extract_form_content_from_words(page) 工具依 word 座標重組「表單式」版面文字。

對非標準表格的 PDF,從 pdfplumber page 的 word 物件按座標(行/列)重建內容, 補救 pdfminer 的抽取順序問題。

extract_cells(info) / _extract_tables_from_words(page) 表格從 pdfplumber 的 tables/lines 或 word 座標抽出儲存格。

先嘗試 pdfplumber page.extract_tables();對「無邊框表格」則退回 _extract_tables_from_words——用 word 的 x/y 座標聚類成欄與列。

2. PdfConverter 主體

accepts() / convert() PDFmimetype application/pdf 或副檔名 .pdf 即接受。

convertpdfplumber.open 逐頁處理:對每頁先試表格抽取、再疊加 文字抽取(兩者都會跑),最後跑 _merge_partial_numbering_lines 後處理。掃描版(無文字層) 或複雜版面是已知弱點——官方建議高品質抽取改用 Azure Content Understanding。