메타데이터 & 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()?);
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, 암호화 딕셔너리 참조, 정보 딕셔너리 참조를 포함합니다.
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> |
웹 명세 URL |
기타
| 필드 | 타입 | 설명 |
|---|---|---|
custom |
HashMap<String, String> |
커스텀 속성 (namespace:property → 값) |
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);
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);
고급 예제
전체 문서 메타데이터 표시
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'