PDF から表を抽出して Markdown にする
PDF をよく変換する人に、いちばんよく壊れるのは何かと尋ねると、答えはほぼいつも同じです。表です。見出し、段落、リストは安定して変換できますが、表だけは毎回目視での確認が欠かせません。
この記事では、PDF 形式で表が構造的に難しい理由、最新のコンバーターが表を Markdown の pipe table に再構築する仕組み、Markdown ではまったく表現できない表の機能、そして変換後の表を盲信せず検証する方法を説明します。
PDF に「表」は存在しない――それが問題のすべてです
Word 文書、HTML ページ、スプレッドシートには、行・列・セル・結合を持つ本物の表オブジェクトがあります。PDF 形式にはそれが一切ありません。PDF で表に見えるものは、座標に配置されたテキスト断片の集まりに、任意で描かれた近くの線や矩形が加わったものにすぎません。
つまり、表の抽出は「取り出し」ではなく「推論」です。コンバーターは、どの断片が同じ行に属するか、それぞれがどの列に属するか、近くの罫線がセルの境界なのかページの装飾なのか、表がどこで終わり次の段落がどこから始まるかを判断しなければなりません。
同じ表がある PDF では完璧に、別の PDF ではひどく変換されるのもこのためです。違いは表の複雑さではなく、文書がどれだけの証拠を持っているかです。明確な罫線と一貫した整列は検出器の手がかりになり、それがなければ推測に頼るしかありません。
罫線ありの表と空白整列の表
セル間に見える線がある罫線ありの表は、扱いやすいケースです。線がページを領域に分割し、各領域に 1 つのセルのテキストが収まるため、構造認識の問題は「既知のグリッド内での読み順」にまで単純化されます。このサイトのコンバーターを含め、ほとんどのコンバーターはこれをうまく処理します。
罫線なし・空白で整列された表はその逆です。分割の手がかりとなる線がないため、検出器は座標でテキスト断片をクラスタリングします。ベースラインが揃う断片が行になり、x 座標が集まる断片が列になります。わずかにずれた整列――セルが列から 2 ポイントずれているだけでも――値の割り当てミスへと波及しかねません。
レポートソフトからエクスポートされた財務諸表は罫線があることが多く、きれいに変換されます。スライドから貼り付けた表、余白だけで組まれた表、ページをまたいで分割されヘッダーが繰り返される表は、罫線なし・断片化のケースであり、目視確認は絶対に省略できません。
構造認識がグリッドを再構築する仕組み
このサイトのコンバーターを支える PDF エンジンは、抽出処理の一環として表構造認識を行います。ページ上の表領域を検出し、行と列に分割し、各テキスト断片をセルに割り当て、結果を GitHub 風 Markdown の pipe table として出力します。
この出力は、正直で、不可逆だが有用な共通分母です。pipe table は「どの値がどの行ヘッダー・列ヘッダーに対応するか」という本質的な意味を保ちつつ、列幅、セルの網掛け、整列といった Markdown では記録しようのない視覚的詳細を捨てます。
公開されている表抽出ベンチマークでの認識精度は近年劇的に向上し、この種のエンジンは「PDF をコピーして貼り付ける」素朴な方法を大きく上回るスコアを出します。ただしベンチマークのスコアは平均値であり、あなたの表は平均以下かもしれません。検証のアドバイスは後述しますが、それには理由があります。
Markdown 側に届くもの
きれいに変換された結果は、人間が手で書くものとまったく同じ見た目です。ヘッダー行、区切り行、データ行ごとの pipe 行。空のセルは空のまま、数値列は値を保ち、GitHub、Obsidian、あらゆる主要 Markdown レンダラーで正しい表として表示されます。
周囲のコンテキストも生き残ります。表の上の段落、通常のテキストとして組まれた表のキャプション、下の脚注は通常のコンテンツとして変換されるため、表は説明なく浮くのではなく、文脈を保ったままになります。
残らないのは、行と列を超えた二次元構造です。列グループ、表全体にまたがる集計行、入れ子のサブヘッダーは、すべて追加の行に平坦化されるか、セルのテキストに吸収されます。データは残っていますが、元の形は失われます。
結合セルと GFM の限界
GitHub 風 Markdown の pipe table は意図的に最小限に設計されています。ヘッダー行はちょうど 1 行、セルの結合も行の結合もなく、整列も列ごとの左・中央・右のみです。元の PDF にそれ以上のリッチな構造があれば、収まるように平坦化しなければなりません。
3 列にまたがる結合セルは、先頭のセルにテキストが入り後続が空になるか、各セルにテキストが繰り返されます。2 段のヘッダーは 1 行のヘッダーになり、階層が区切り文字などで連結されます。その平坦化が許容できるかどうかは、次に何をするか次第です。文書で読む分には問題なく、スプレッドシートへのインポートでは情報が欠落します。
出力先が本当に結合構造を必要とするなら、その表はコンバーターではなく Markdown の枠を超えています。その 1 枚の表には、元のソースからの CSV エクスポートや、スプレッドシートツール自身の PDF インポートが適しています。コンバーターに意味が生き残ったふりを強いるべきではありません。
数字は必ずスポットチェックを
表変換の失敗は本質的に静かです。列がずれても、普通の表として表示され、値が 1 つ間違った場所にあるだけです。改ページで分かれた行は 2 行になることがあります。マイナス記号がハイフンと読み取られれば、見た目を変えずに負の数が正の数になります。
だから、影響の大きさに比例して検証してください。ブログ記事の表なら、レンダリング結果をざっと見るだけで十分です。レポートに使う財務・科学の表なら、行数、列の合計、ランダムに選んだセルを原本と照合します。モデルやデータベースに流し込むものなら、このチェックは任意のステップではなく、パイプラインの一部です。
コンバーターはできる範囲で助けます。確認が必要そうな表があるページは、黙って見過ごすのではなく、変換時の警告でフラグが立てられます。そのフラグは、まず確認すべき行への道標として扱ってください。
Pandoc で表を次へ送る
表が Markdown の pipe table になれば、このサイトの他の出力形式を支える Pandoc エンジンの第一級市民です。HTML 出力を選べば本物の <table> マークアップに、LaTeX を選べば tabular に、RST を選べば grid 構文になります。
この第 2 段階は、Pandoc が書き出す前に pipe table を文書モデルにパースするため、列の整列やヘッダー構造がすべての形式で保持されるという意味で無損失です。PDF→Markdown の時点で失われたものは戻りませんが、それ以上失われることもありません。
多くのワークフローでは、出力先が Markdown を話すため、チェーンは Markdown で止まります。LaTeX の論文や Sphinx のサイトのようにそうでない場合でも、変換パスはすでに用意されており、同じローカルでプライベートなパイプライン上を、ドロップダウン 1 つで進めます。