RustでPDFを弄くろうと思ったのでlopdfというライブラリを利用した。
まず前提として、PDFのフォーマットをちょっとしらないと意味ないので。
PDF 構文 -ファイル 解析手順-
とか
詳細PDF入門 ー 実装して学ぼう!PDFファイルの構造とその書き方読み方 - プログラムモグモグ
を斜め読
PDFのstreamの内容がFlateDecodeされていると面倒なので
pdftk test.pdf output test2.pdf uncompress
を行った
最終的にはテキストを抜き出したい
(pdftotextを試したがうまく行かなかった。)
[dependencies] lopdf = "0.19.0"
extern crate lopdf; use lopdf::content::{Content, Operation}; use lopdf::Object::*; use lopdf::{Document, Object, Stream}; use std::str::from_utf8; fn main() { let doc = Document::load("test2.pdf"); let test = match doc { Ok(a) => a, Err(_) => panic!("load error"), }; let pages = test.get_pages(); let id = pages.get(&1).unwrap(); let contents = test.get_page_contents(*id); println!("Refered from Page 1\n{:?}", contents); }
ページ1から参照されているオブジェクトの番号がVecで得られるが
そのオブジェクトもまたどこかのオブジェクトを参照している可能性がある
pub enum Object { Null, Boolean(bool), Integer(i64), Real(f64), Name(Vec<u8>), String(Vec<u8>, StringFormat), Array(Vec<Object>), Dictionary(Dictionary), Stream(Stream), Reference(ObjectId), }
とのことなので
ObjectのArrayなら順番にその先を見に行って
streamならそれを取り出すように、たぶん再帰的な実装が必要?