書いたこと
PDFファイルの解析にあたって、PDF.jsの実装をまとめる。
PDF.jsの解析手順
- streamオブジェクトの生成
- ヘッダーを解析
- startxrefの値の読み取り
- 相互参照テーブルの取得
- カタログ辞書の取得
0. streamオブジェクトの生成
物理的なPDFファイルデータはstreamオブジェクトとして抽象化されている。
これによってデータが必要になった際にファイルデータを随時取得が行えるようになっている。
1-4. ドキュメントのグラフ階層の生成
src/core/worker.js
async function loadDocument(recoveryMode) {
await pdfManager.ensureDoc("checkHeader"); // 1. ヘッダー情報の取得
await pdfManager.ensureDoc("parseStartXRef"); // 2. startxrefの解析
await pdfManager.ensureDoc("parse", [recoveryMode]); // 3-4. 相互参照テーブルとカタログ情報の取得
if (!recoveryMode) {
// Check that at least the first page can be successfully loaded,
// since otherwise the XRef table is definitely not valid.
await pdfManager.ensureDoc("checkFirstPage");
}
const [numPages, fingerprint] = await Promise.all([
pdfManager.ensureDoc("numPages"),
pdfManager.ensureDoc("fingerprint"),
]);
return { numPages, fingerprint };
}
PDF.jsの構文解析と字句解析
<< /Type /Annot
/Subtype /Link
/F 4
/Border [0 0 0]
/Rect [255.99998 189.7099 467.49997 206.2099]
/A <</Type /Action
/S /URI
/URI (https://doc.rust-lang.org/stable/book/)
>>
>>
字句解析
字句解析にかけることによって以下のトークン列に変換する
src/core/perser.js
getObj() {
// Start reading a token.
switch (ch | 0) {
case 0x30: // '0'
case 0x31: // '1'
case 0x32: // '2'
case 0x33: // '3'
case 0x34: // '4'
case 0x35: // '5'
case 0x36: // '6'
case 0x37: // '7'
case 0x38: // '8'
case 0x39: // '9'
case 0x2b: // '+'
case 0x2d: // '-'
case 0x2e: // '.'
return this.getNumber(); // 数字トークンを取得
case 0x28: // '('
return this.getString(); // 文字列トークンを取得
case 0x2f: // '/'
return this.getName(); // 名前トークンを取得
// array punctuation
case 0x5b: // '[
this.nextChar();
return Cmd.get("["); // Cmd("[") トークンを取得
case 0x5d: // ']'
構文解析
トークン列からプログラミング言語の型に変換する
-
<<
から辞書を生成する -
>>
までキーと値を交互に設定していく
2を繰り返すことで、トークン列から辞書インスタンスを得ることが出来る。
構文解析結果.js
{
Name("Type"): Name("Annotate"),
Name("SubType"): Name("Link"),
Name("F"): 4,
Name("Border"): [0, 0, 0],
Name("Rect"): [255.99998, 189.7099, 467.49997, 206.2099],
Name("A"): {
Name("Type"): Name("Action"),
Name("S"): Name("URI"),
Name("URI"): "https://doc.rust-lang.org/stable/book/",
}
}