Skip to content

PDF Oxide をはじめる(Julia)

PDF Oxide は Julia 向けで最速の PDF ライブラリです。テキスト抽出は平均 0.8ms、3,830 件の PDF で 100% のパス率を達成しています。PdfOxide.jl パッケージは Rust コアを C ABI 経由で直接ラップしているため、ネイティブの速度とイディオマティックな Julia API を両立できます。ページインデックスは 0 始まりです。

インストール

Julia の REPL パッケージマネージャーからパッケージを追加します。

using Pkg
Pkg.add("PdfOxide")

ネイティブライブラリ(libpdf_oxide)は実行時に読み込まれます。システムのローダーパス上に存在しない場合は、PdfOxide.jl が確認する次の環境変数のいずれかでその場所を指定してください。確認される順番は、PDF_OXIDE_LIB_PATH(ファイルへのフルパス)、PDF_OXIDE_LIB_DIR(ディレクトリ)、最後にローカルの target/release ビルドディレクトリです。

export PDF_OXIDE_LIB_DIR=/path/to/pdf_oxide/target/release

クイックスタート

PDF を開いて最初のページからテキストを抽出します。extract_text は 0 始まりのページインデックスを受け取ります。

using PdfOxide

doc = open_document("report.pdf")

println("pages:   ", page_count(doc))
v = version(doc)
println("version: ", v.major, ".", v.minor)

# Plain text from the first page (0-based index)
println(extract_text(doc, 0))

メモリ上でドキュメントを組み立てて、バイト列から開くこともできます。ディスクに一切触れないテストやパイプラインで便利です。

using PdfOxide

pdf = from_markdown("# Hello pdf_oxide\n\nThis is the **Julia** binding.\n")
doc = open_from_bytes(to_bytes(pdf))

println("pages: ", page_count(doc))
println(extract_text(doc, 0))

ドキュメントの調査

抽出を始める前に、いくつかの軽量な呼び出しで何を扱っているのかを把握できます。

using PdfOxide

doc = open_document("report.pdf")

@show page_count(doc)        # number of pages
@show version(doc).major     # PDF spec version
@show is_encrypted(doc)      # true if the file is password-protected

Markdown と HTML への変換

1 ページ単位でも、ドキュメント全体を一度にでも変換できます。Markdown は見出し・リスト・強調を保持し、_all の付くバリアントは全ページを連結します。

using PdfOxide

doc = open_document("paper.pdf")

# One page (0-based)
md = to_markdown(doc, 0)
println(md)

# Whole document
println(to_markdown_all(doc))

# HTML for a single page
html = to_html(doc, 0)
println(html)

# Plain text without any markup
println(to_plain_text(doc, 0))

単語単位の抽出

extract_wordsWord 値のベクターを返します。それぞれがテキスト、バウンディングボックス、フォントサイズ、太字フラグを保持します。バウンディングボックスは widthheight、位置のフィールドを持つ Bbox です。

using PdfOxide

doc = open_document("paper.pdf")
words = extract_words(doc, 0)

for w in first(words, 10)
    println(rpad(w.text, 20),
            " size=", w.font_size,
            " bold=", w.bold,
            " width=", round(w.bbox.width; digits = 1))
end

行単位のレイアウトを扱う場合は、extract_text_linesTextLine 値を返します。それぞれにテキスト、word_countbbox が含まれます。

using PdfOxide

doc = open_document("paper.pdf")
lines = extract_text_lines(doc, 0)

for line in lines
    println(line.word_count, " words: ", line.text)
end

検索

1 ページだけ、あるいはドキュメント全体を検索できます。3 番目の引数は大文字・小文字を区別するかどうかのフラグです(区別しない場合は false)。各ヒットは、その text、見つかった page、そして bbox を報告します。

using PdfOxide

doc = open_document("manual.pdf")

# Search one page (case-insensitive)
hits = search(doc, 0, "configuration", false)
for h in hits
    println("page ", h.page, ": ", h.text)
end

# Search every page
all_hits = search_all(doc, "configuration", false)
println(length(all_hits), " total matches")
for h in all_hits
    println("page ", h.page, " at (",
            round(h.bbox.x; digits = 0), ", ",
            round(h.bbox.y; digits = 0), ")")
end

PDF の作成

from_* ファクトリ関数は、Markdown、HTML、プレーンテキストから Pdf を組み立てます。生のバイト列を取得するには to_bytes を、ファイルに直接書き出すには save を呼び出します。

using PdfOxide

# From Markdown
pdf = from_markdown("# Invoice\n\nAmount due: **\$42**\n")
save(pdf, "invoice.pdf")

# From HTML
html_pdf = from_html("<h1>Report</h1><p>Quarterly results.</p>")
save(html_pdf, "report.pdf")

# From plain text — grab the bytes instead of writing a file
text_pdf = from_text("Plain text body.")
bytes = to_bytes(text_pdf)
println("generated ", length(bytes), " bytes")

エラー処理

操作に失敗すると PdfOxideError が送出されます。信頼できない入力を扱う呼び出しは try/catch で囲んでください。

using PdfOxide

try
    doc = open_document("missing.pdf")
    println(extract_text(doc, 0))
catch e
    e isa PdfOxideError || rethrow()
    println("PDF error: ", e)
end

次のステップ