Skip to content

メタデータ & XMP

PDF Oxide は、複数のソースからドキュメントレベルのメタデータを読み取ります。PDF ヘッダー(バージョン)、トレーラーおよびカタログ辞書、XMP メタデータストリーム(ISO 16684)、そしてページラベル定義です。XmpExtractor は Dublin Core、XMP Core、PDF、XMP Rights の各名前空間とカスタムプロパティを解析します。

基本的なドキュメントプロパティには version()catalog()、リッチメタデータには XmpExtractor::extract()、ページ番号スキームには PageLabelExtractor を使用してください。

クイック例

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
major, minor = doc.version()
print(f"PDF {major}.{minor}, {doc.page_count()} pages")

Node.js

const { PdfDocument } = require("pdf-oxide");

const doc = new PdfDocument("report.pdf");
const { major, minor } = doc.getVersion();
console.log(`PDF ${major}.${minor}, ${doc.pageCount()} pages`);
doc.close();

Go

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
major, minor, _ := doc.Version()
pages, _ := doc.PageCount()
fmt.Printf("PDF %d.%d, %d pages\n", major, minor, pages)

C#

using PdfOxide.Core;

using var doc = PdfDocument.Open("report.pdf");
var (major, minor) = doc.Version;
Console.WriteLine($"PDF {major}.{minor}, {doc.PageCount} pages");

WASM

const doc = new WasmPdfDocument(bytes);
const version = doc.version();
console.log(`PDF ${version}, ${doc.pageCount()} pages`);

Rust

use pdf_oxide::PdfDocument;

let mut doc = PdfDocument::open("report.pdf")?;
let (major, minor) = doc.version();
println!("PDF {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);

PHP

use PdfOxide\PdfDocument;

$doc = PdfDocument::open("report.pdf");
$v = $doc->version(); // ['major' => int, 'minor' => int]
echo "PDF {$v['major']}.{$v['minor']}, {$doc->pageCount()} pages\n";
$doc->close();

Ruby

require "pdf_oxide"

PdfOxide::PdfDocument.open("report.pdf") do |doc|
  puts "PDF #{doc.pdf_version}, #{doc.page_count} pages"
end

C++

#include <pdf_oxide/pdf_oxide.hpp>

auto doc = pdf_oxide::Document::open("report.pdf");
auto v = doc.version();
std::cout << "PDF " << static_cast<int>(v.major) << "."
          << static_cast<int>(v.minor) << ", " << doc.page_count() << " pages\n";

Swift

import PdfOxide

let doc = try Document.open("report.pdf")
let v = try doc.version()
print("PDF \(v.major).\(v.minor), \(try doc.pageCount()) pages")

Dart

import 'package:pdf_oxide/pdf_oxide.dart';

final doc = PdfDocument.open('report.pdf');
final v = doc.version;
print('PDF ${v.major}.${v.minor}, ${doc.pageCount} pages');
doc.close();

R

library(pdfoxide)

doc <- pdf_open("report.pdf")
v <- pdf_version(doc)
cat(sprintf("PDF %d.%d, %d pages\n", v$major, v$minor, pdf_page_count(doc)))

Julia

using PdfOxide

doc = open_document("report.pdf")
v = version(doc)
println("PDF $(v.major).$(v.minor), $(page_count(doc)) pages")

Zig

const pdf_oxide = @import("pdf_oxide");

var doc = try pdf_oxide.Document.open("report.pdf");
const v = doc.version();
std.debug.print("PDF {d}.{d}, {d} pages\n", .{ v.major, v.minor, try doc.pageCount() });

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
POXVersion v = [doc version];
printf("PDF %d.%d, %ld pages\n", v.major, v.minor, (long)[doc pageCountError:&err]);

Elixir

{:ok, doc} = PdfOxide.open("report.pdf")
%{major: maj, minor: min} = PdfOxide.version(doc)
{:ok, pages} = PdfOxide.page_count(doc)
IO.puts("PDF #{maj}.#{min}, #{pages} pages")

API リファレンス

version() -> (u8, u8)

ファイルヘッダーから PDF バージョンを取得します。

戻り値: (major, minor) のタプル。例: PDF 1.7 は (1, 7)、PDF 2.0 は (2, 0)


catalog() -> Result<Object>

ドキュメントカタログ辞書を取得します。カタログは PDF オブジェクト階層のルートであり、ページツリー、アウトライン、名前、その他のドキュメントレベル構造への参照を含みます。

Rust

let mut doc = PdfDocument::open("report.pdf")?;
let catalog = doc.catalog()?;
if let Some(dict) = catalog.as_dict() {
    for (key, _) in dict {
        println!("Catalog key: {}", key);
    }
}

trailer() -> &Object

ドキュメントトレーラー辞書を取得します。トレーラーには、相互参照テーブルの場所、ドキュメント ID、暗号化辞書の参照、および Info 辞書の参照が含まれます。

Rust

let doc = PdfDocument::open("report.pdf")?;
let trailer = doc.trailer();
println!("Trailer: {:?}", trailer);

XmpExtractor::extract(doc) -> Result<Option<XmpMetadata>>

ドキュメントのメタデータストリームから XMP(Extensible Metadata Platform)メタデータを抽出します。XMP は標準的な XML 名前空間を使用し、従来の Info 辞書よりも豊富なメタデータを提供します。

パラメータ 説明
doc &mut PdfDocument PDF ドキュメント

戻り値: XMP データが存在する場合は Some(XmpMetadata)、それ以外は None

XmpMetadata フィールド

Dublin Core 名前空間 (dc:)

フィールド 説明
dc_title Option<String> ドキュメントタイトル
dc_creator Vec<String> 著者・作成者リスト
dc_description Option<String> ドキュメントの説明
dc_subject Vec<String> 件名キーワード
dc_language Option<String> ドキュメントの言語(例: "en-US"
dc_rights Option<String> 著作権表示
dc_format Option<String> MIME フォーマット(例: "application/pdf"

XMP Core 名前空間 (xmp:)

フィールド 説明
xmp_creator_tool Option<String> ドキュメント作成に使用したツール
xmp_create_date Option<String> 作成日時(ISO 8601)
xmp_modify_date Option<String> 最終更新日時
xmp_metadata_date Option<String> メタデータの更新日時

PDF 名前空間 (pdf:)

フィールド 説明
pdf_producer Option<String> PDF 生成アプリケーション
pdf_keywords Option<String> キーワード文字列
pdf_version Option<String> XMP の PDF バージョン(ヘッダーと異なる場合あり)
pdf_trapped Option<String> トラッピング状態

XMP Rights 名前空間 (xmpRights:)

フィールド 説明
xmp_rights_usage_terms Option<String> 利用規約
xmp_rights_marked Option<bool> 権利マークの有無
xmp_rights_web_statement Option<String> Web 上の権利表示 URL

その他

フィールド 説明
custom HashMap<String, String> カスタムプロパティ(名前空間:プロパティ → 値)
raw_xml Option<String> 元の XMP XML パケット

Rust

use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    if let Some(title) = &xmp.dc_title {
        println!("Title: {}", title);
    }
    for creator in &xmp.dc_creator {
        println!("Author: {}", creator);
    }
    if let Some(tool) = &xmp.xmp_creator_tool {
        println!("Created with: {}", tool);
    }
    if let Some(date) = &xmp.xmp_create_date {
        println!("Created: {}", date);
    }
    if let Some(producer) = &xmp.pdf_producer {
        println!("Producer: {}", producer);
    }
}

WASM

const doc = new WasmPdfDocument(bytes);
const xmp = doc.xmpMetadata();

if (xmp) {
  console.log(`Title: ${xmp.dc_title}`);
  console.log(`Authors: ${xmp.dc_creator}`);
  console.log(`Created with: ${xmp.xmp_creator_tool}`);
  console.log(`Created: ${xmp.xmp_create_date}`);
  console.log(`Producer: ${xmp.pdf_producer}`);
}
doc.free();

Python

doc = PdfDocument("report.pdf")
xmp = doc.xmp_metadata()

if xmp:
    print(f"Title: {xmp.get('dc_title')}")
    print(f"Authors: {xmp.get('dc_creator')}")
    print(f"Created with: {xmp.get('xmp_creator_tool')}")
    print(f"Created: {xmp.get('xmp_create_date')}")
    print(f"Producer: {xmp.get('pdf_producer')}")

<!-- Node.js: no equivalent on PdfDocumentImpl — xmp metadata not exposed in js/src/index.ts -->

Go

doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
xmp, _ := doc.XmpMetadata() // returns JSON string
fmt.Println(xmp)

C#

using var doc = PdfDocument.Open("report.pdf");
var xmp = doc.GetXmpMetadata(); // returns JSON string
Console.WriteLine(xmp);

C++

auto doc = pdf_oxide::Document::open("report.pdf");
std::string xmp = doc.get_xmp_metadata(); // raw XMP XML packet
std::cout << xmp << "\n";

Swift

let doc = try Document.open("report.pdf")
let xmp = try doc.xmpMetadata() // raw XMP XML packet
print(xmp)

Dart

final doc = PdfDocument.open('report.pdf');
final xmp = doc.getXmpMetadata(); // raw XMP XML packet
print(xmp);
doc.close();

R

doc <- pdf_open("report.pdf")
xmp <- pdf_get_xmp_metadata(doc) # XMP metadata as JSON
cat(xmp, "\n")

Julia

doc = open_document("report.pdf")
xmp = get_xmp_metadata(doc) # XMP metadata string
println(xmp)

Zig

var doc = try pdf_oxide.Document.open("report.pdf");
const xmp = try doc.xmpMetadata(a); // caller owns the slice
defer a.free(xmp);
std.debug.print("{s}\n", .{xmp});

Objective-C

POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
NSString *xmp = [doc xmpMetadataWithError:&err];
printf("%s\n", xmp.UTF8String);

Elixir

{:ok, doc} = PdfOxide.open("report.pdf")
xmp = PdfOxide.xmp_metadata(doc) # XMP metadata as an XML/JSON string
IO.puts(xmp)

Pdf 便利メソッド

高レベルの Pdf API は、よく使うメタデータクエリのショートカットメソッドを提供します。

xmp_metadata() -> Result<Option<XmpMetadata>>

XMP メタデータオブジェクト全体を取得します。

xmp_title() -> Result<Option<String>>

XMP からドキュメントタイトルのみを取得します。

xmp_creators() -> Result<Vec<String>>

XMP から作成者・著者のリストを取得します。

Rust

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("report.pdf")?;

if let Some(title) = pdf.xmp_title()? {
    println!("Title: {}", title);
}

let creators = pdf.xmp_creators()?;
for creator in &creators {
    println!("Author: {}", creator);
}

PageLabelExtractor::extract(doc) -> Result<Vec<PageLabelRange>>

ドキュメントからページラベル定義を抽出します。ページラベルは、ページ番号の表示方法を定義します(例: 前付けにローマ数字、本文にアラビア数字)。

パラメータ 説明
doc &mut PdfDocument PDF ドキュメント

戻り値: PageLabelRange 定義のベクター。

PageLabelRange フィールド

フィールド 説明
start_page usize この範囲が適用される最初のページインデックス
style PageLabelStyle 番号付けスタイル
prefix Option<String> ラベルのプレフィックス文字列
start_number u32 この範囲の開始番号

PageLabelStyle バリアント

バリアント 説明
DecimalArabic アラビア数字 1, 2, 3
UppercaseRoman 大文字ローマ数字 I, II, III
LowercaseRoman 小文字ローマ数字 i, ii, iii
UppercaseLetters 大文字アルファベット A, B, C
LowercaseLetters 小文字アルファベット a, b, c
None 番号なし(プレフィックスのみ)

Pdf ページラベル便利メソッド

page_labels() -> Result<Vec<PageLabelRange>>

すべてのページラベル範囲定義を取得します。

page_label(page) -> Result<String>

特定のページインデックスの表示ラベルを取得します。

Rust

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("book.pdf")?;

// Get all label ranges
let ranges = pdf.page_labels()?;
for range in &ranges {
    println!(
        "Pages from {}: {:?} style, prefix={:?}, start={}",
        range.start_page, range.style, range.prefix, range.start_number
    );
}

// Get label for a specific page
let label = pdf.page_label(0)?;
println!("Page 0 label: {}", label); // e.g., "i" or "Cover"

WASM

const doc = new WasmPdfDocument(bytes);
const labels = doc.pageLabels();

for (const range of labels) {
  console.log(`Pages from ${range.start_page}: style=${range.style}, prefix=${range.prefix}`);
}
doc.free();

Python

doc = PdfDocument("book.pdf")
labels = doc.page_labels()

for range in labels:
    print(f"Pages from {range['start_page']}: style={range['style']}, prefix={range['prefix']}")

<!-- Node.js: no equivalent on PdfDocumentImpl — pageLabels not exposed on class, only via properties mixin -->

Go

doc, _ := pdfoxide.Open("book.pdf")
defer doc.Close()
labels, _ := doc.PageLabels() // returns JSON string
fmt.Println(labels)

C#

using var doc = PdfDocument.Open("book.pdf");
var labels = doc.GetPageLabels(); // returns JSON string
Console.WriteLine(labels);

C++

auto doc = pdf_oxide::Document::open("book.pdf");
std::string labels = doc.get_page_labels(); // JSON string
std::cout << labels << "\n";

Swift

let doc = try Document.open("book.pdf")
let labels = try doc.pageLabels() // JSON string
print(labels)

Dart

final doc = PdfDocument.open('book.pdf');
final labels = doc.getPageLabels(); // JSON string
print(labels);
doc.close();

R

doc <- pdf_open("book.pdf")
labels <- pdf_get_page_labels(doc) # JSON string
cat(labels, "\n")

Julia

doc = open_document("book.pdf")
labels = get_page_labels(doc) # JSON string
println(labels)

Zig

var doc = try pdf_oxide.Document.open("book.pdf");
const labels = try doc.pageLabels(a); // JSON string; caller owns the slice
defer a.free(labels);
std.debug.print("{s}\n", .{labels});

Objective-C

POXDocument *doc = [POXDocument openPath:@"book.pdf" error:&err];
NSString *labels = [doc pageLabelsWithError:&err];
printf("%s\n", labels.UTF8String);

Elixir

{:ok, doc} = PdfOxide.open("book.pdf")
labels = PdfOxide.page_labels(doc) # JSON string
IO.puts(labels)

get_producer — ドキュメントのプロデューサー

プロデューサーは PDF を生成したツールです(/Info.Producer)。エディターサーフェスでは読み書き可能なアクセサーとして公開されています。get_producer / Producer で読み取り、対応するセッター(保存時に /Info.Producer に永続化)で書き込みます。XMP 上の同等フィールドは上記 XmpMetadatapdf_producer です。

このアクセサーは C ABI 関数 document_editor_get_producer によって実装されています。

char *document_editor_get_producer(DocumentEditor *handle, int32_t *error_code);

呼び出し元が所有する C 文字列(free_string で解放)を返します。プロデューサーが設定されていない場合は null

Rust

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("report.pdf")?;
if let Some(producer) = editor.producer()? {
    println!("Producer: {}", producer);
}

Go

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

editor, _ := pdfoxide.OpenEditor("report.pdf")
defer editor.Close()
producer, _ := editor.Producer()
fmt.Printf("Producer: %s\n", producer)

C#

using PdfOxide.Core;

using var editor = DocumentEditor.Open("report.pdf");
Console.WriteLine($"Producer: {editor.Producer}");

Swift

import PdfOxide

let editor = try DocumentEditor.open("report.pdf")
let producer = try editor.getProducer()
print("Producer: \(producer)")

PHP

use PdfOxide\DocumentEditor;

$editor = DocumentEditor::open("report.pdf");
echo "Producer: " . $editor->getProducer() . "\n";

C++

auto editor = pdf_oxide::DocumentEditor::open("report.pdf");
std::cout << "Producer: " << editor.get_producer() << "\n";

Dart

final editor = DocumentEditor.open('report.pdf');
print('Producer: ${editor.getProducer()}');

R

editor <- pdf_editor_open("report.pdf")
cat("Producer:", pdf_editor_get_producer(editor), "\n")

Julia

editor = open_editor("report.pdf")
println("Producer: ", get_producer(editor))

Zig

var editor = try pdf_oxide.Document.openEditor("report.pdf");
const producer = try editor.getProducer(a); // caller owns the slice
defer a.free(producer);
std.debug.print("Producer: {s}\n", .{producer});

Objective-C

POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"report.pdf" error:&err];
NSString *producer = [editor producerError:&err];
printf("Producer: %s\n", producer.UTF8String);

Elixir

{:ok, editor} = PdfOxide.open_editor("report.pdf")
producer = PdfOxide.get_producer(editor)
IO.puts("Producer: #{producer}")

バインディングの対応状況。 get_producer はエディター(DocumentEditor)上に存在し、読み取り専用の PdfDocument には属しません。Rust (editor.producer())、Go (editor.Producer())、C# (editor.Producer プロパティ)、Swift (editor.getProducer())、C ABI (document_editor_get_producer) で公開されています。セッター(set_producer / SetProducer / Producer = ...)は保存時に変更を永続化します。このアクセサーは WASM ターゲットではコンパイルされません。


embedded_fonts — ページで使用されているフォント

embedded_fonts は、ページのコンテンツストリームで参照されているフォントを列挙し、ページのテキストスパンからフォント名、埋め込みステータス、サブセットステータスを導出します。(サブセットフォントは標準の 6 文字プレフィックス++ の命名規則で検出されます。例: ABCDEF+Helvetica。)C ABI 関数 pdf_document_get_embedded_fontspdf_oxide_font_* アクセサーファミリーによって実装されています。

Go

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()

fonts, _ := doc.Fonts(0) // []pdfoxide.Font
for _, f := range fonts {
    fmt.Printf("%s (%s) embedded=%v subset=%v\n",
        f.Name, f.Encoding, f.IsEmbedded, f.IsSubset)
}

Swift

import PdfOxide

let doc = try Document.open("report.pdf")
let fonts = try doc.embeddedFonts(0) // [Font]
for f in fonts {
    print("\(f.name) (\(f.encoding)) embedded=\(f.embedded) subset=\(f.subset)")
}

C ABI

#include "pdf_oxide.h"

int32_t err = 0;
FfiFontList *fonts = pdf_document_get_embedded_fonts(doc, /*page=*/0, &err);
int32_t n = pdf_oxide_font_count(fonts);
for (int32_t i = 0; i < n; i++) {
    char *name = pdf_oxide_font_get_name(fonts, i, &err);
    int32_t embedded = pdf_oxide_font_is_embedded(fonts, i, &err);
    int32_t subset = pdf_oxide_font_is_subset(fonts, i, &err);
    printf("%s embedded=%d subset=%d\n", name, embedded, subset);
    free_string(name);
}
pdf_oxide_font_list_free(fonts);

C++

auto doc = pdf_oxide::Document::open("report.pdf");
for (const auto& f : doc.embedded_fonts(0)) { // std::vector<Font>
    std::cout << f.name << " (" << f.encoding << ") embedded="
              << f.embedded << " subset=" << f.subset << "\n";
}

Dart

final doc = PdfDocument.open('report.pdf');
for (final f in doc.embeddedFonts(0)) { // List<Font>
  print('${f.name} (${f.encoding}) embedded=${f.embedded} subset=${f.subset}');
}
doc.close();

R

doc <- pdf_open("report.pdf")
for (f in pdf_embedded_fonts(doc, 0)) { # list of Font records
  cat(sprintf("%s (%s) embedded=%s subset=%s\n",
              f$name, f$encoding, f$embedded, f$subset))
}

Julia

doc = open_document("report.pdf")
for f in embedded_fonts(doc, 0) # Vector{Font}
    println("$(f.name) ($(f.encoding)) embedded=$(f.embedded) subset=$(f.subset)")
end

Zig

var doc = try pdf_oxide.Document.open("report.pdf");
const fonts = try doc.embeddedFonts(a, 0); // []Font
defer pdf_oxide.Document.freeFonts(a, fonts);
for (fonts) |f| {
    std.debug.print("{s} ({s}) embedded={} subset={}\n",
        .{ f.name, f.encoding, f.embedded, f.subset });
}

Objective-C

POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
for (POXFont *f in [doc embeddedFonts:0 error:&err]) {
    printf("%s (%s) embedded=%d subset=%d\n",
        f.name.UTF8String, f.encoding.UTF8String, f.embedded, f.subset);
}

Elixir

{:ok, doc} = PdfOxide.open("report.pdf")
for f <- PdfOxide.embedded_fonts(doc, 0) do # list of %Font{}
  IO.puts("#{f.name} (#{f.encoding}) embedded=#{f.embedded} subset=#{f.subset}")
end

フォントアクセサーフィールド

フィールド (Go / Swift) 説明
Name / name string フォントリソース名(例: "ABCDEF+Helvetica"
Type / type string フォントサブタイプ
Encoding / encoding string フォントエンコーディング
IsEmbedded / embedded bool フォントプログラムが埋め込まれているか
IsSubset / subset bool フォントがサブセット化されているか
Size (Go) float32 フォントサイズ(取得可能な場合)

バインディングの対応状況。 embedded_fontsGo (doc.Fonts(page))、Swift (doc.embeddedFonts(page))、および C ABI (pdf_document_get_embedded_fonts) で公開されています。WASM ターゲットではコンパイルされません。


fonts_to_json — ページのフォントをシリアライズ

fonts_to_json は、embedded_fonts から取得したフォントリスト全体を、1 回の FFI 呼び出しで JSON 配列にシリアライズします。Go バインディングは内部的にこれを使用して []Font を生成し、Swift では fontsToJson として直接公開されています。C ABI シグネチャ:

char *pdf_oxide_fonts_to_json(const FfiFontList *fonts, int32_t *error_code);

返される UTF-8 文字列は呼び出し元が所有します(free_string で解放)。スキーマ:

[{"name": "...", "type": "...", "encoding": "...",
  "isEmbedded": true, "isSubset": false, "size": 0}]

Swift

import PdfOxide

let doc = try Document.open("report.pdf")
let json = try doc.fontsToJson(0) // String of JSON
print(json)

C ABI

#include "pdf_oxide.h"

int32_t err = 0;
FfiFontList *fonts = pdf_document_get_embedded_fonts(doc, /*page=*/0, &err);
char *json = pdf_oxide_fonts_to_json(fonts, &err);
printf("%s\n", json);
free_string(json);
pdf_oxide_font_list_free(fonts);

C++

auto doc = pdf_oxide::Document::open("report.pdf");
std::string json = doc.fonts_to_json(0); // JSON array string
std::cout << json << "\n";

Dart

final doc = PdfDocument.open('report.pdf');
final json = doc.embeddedFontsJson(0); // JSON array string
print(json);
doc.close();

R

doc <- pdf_open("report.pdf")
json <- pdf_fonts_to_json(doc, 0) # JSON array string
cat(json, "\n")

Julia

doc = open_document("report.pdf")
json = fonts_to_json(doc, 0) # JSON array string
println(json)

Zig

var doc = try pdf_oxide.Document.open("report.pdf");
var fl = try doc.fontList(0); // owned FontList handle
defer fl.deinit();
const json = try fl.toJson(a); // JSON array string; caller owns the slice
defer a.free(json);
std.debug.print("{s}\n", .{json});

Objective-C

POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
NSString *json = [doc embeddedFontsJson:0 error:&err]; // JSON array string
printf("%s\n", json.UTF8String);

Elixir

{:ok, doc} = PdfOxide.open("report.pdf")
json = PdfOxide.fonts_to_json(doc, 0) # JSON array string
IO.puts(json)

バインディングの対応状況。 fonts_to_jsonSwift (doc.fontsToJson(page)) と C ABI (pdf_oxide_fonts_to_json) で直接公開されています。Go バインディングは内部的にこれを呼び出して doc.Fonts(page) を型付き構造体にデコードします。WASM ターゲットではコンパイルされません。


応用例

ドキュメントメタデータの完全表示

use pdf_oxide::PdfDocument;
use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;

// Basic info
let (major, minor) = doc.version();
println!("PDF Version: {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);

// XMP metadata
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    println!("\nXMP Metadata:");
    println!("  Title:       {:?}", xmp.dc_title);
    println!("  Authors:     {:?}", xmp.dc_creator);
    println!("  Description: {:?}", xmp.dc_description);
    println!("  Keywords:    {:?}", xmp.pdf_keywords);
    println!("  Creator:     {:?}", xmp.xmp_creator_tool);
    println!("  Producer:    {:?}", xmp.pdf_producer);
    println!("  Created:     {:?}", xmp.xmp_create_date);
    println!("  Modified:    {:?}", xmp.xmp_modify_date);
    println!("  Language:    {:?}", xmp.dc_language);
    println!("  Rights:      {:?}", xmp.dc_rights);

    if !xmp.custom.is_empty() {
        println!("\n  Custom properties:");
        for (key, value) in &xmp.custom {
            println!("    {}: {}", key, value);
        }
    }
}

生の XMP XML へのアクセス

use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    if let Some(xml) = &xmp.raw_xml {
        std::fs::write("metadata.xml", xml)?;
        println!("Raw XMP saved ({} bytes)", xml.len());
    }
}

ページ番号の表示文字列を生成する

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("thesis.pdf")?;
let page_count = pdf.page_count()?;

for i in 0..page_count {
    let label = pdf.page_label(i)?;
    println!("Physical page {} -> display label '{}'", i + 1, label);
}
// Example output:
//   Physical page 1 -> display label 'i'
//   Physical page 2 -> display label 'ii'
//   Physical page 3 -> display label 'iii'
//   Physical page 4 -> display label '1'
//   Physical page 5 -> display label '2'

よくある質問

get_producer はどこから読み取りますか? ドキュメント Info 辞書の /Info.Producer エントリから読み取ります。DocumentEditor(読み書き可能)上に存在し、対応するセッターは保存時に /Info.Producer に変更を永続化します。XMP の pdf:Producer の値は、XmpMetadatapdf_producer として別途取得できます。

embedded_fonts がテキストに現れるフォントしか返さないのはなぜですか? フォントリストはページのレンダリング済みテキストスパンから導出されるため、そのページでグリフを描画するために実際に使用されたフォントが反映されます。サブセット検出は PDF の規約に従い、6 文字タグ++(例: ABCDEF+Helvetica)で行われます。

fonts_to_json が返す JSON スキーマはどのようなものですか? nametypeencodingisEmbeddedisSubsetsize フィールドを持つオブジェクトの JSON 配列です。Go バインディングが Font 構造体にアンマーシャルするのと同じ形式です。

メタデータ抽出は高速ですか? はい。PDF Oxide の抽出コアは、ベンチマークコーパスで平均約 0.8 ms、p99 で 9 ms、合格率 100% で動作します。


関連ページ