Справочник Ruby API
PDF Oxide поставляет нативные привязки для Ruby (gem pdf_oxide), построенные на FFI поверх C ABI cdylib. Gem включает готовую нативную библиотеку и повторяет структуру из 9 классов привязки для Java в пространстве имён PdfOxide.
gem install pdf_oxide
require 'pdf_oxide'
Справочник по Rust API см. в разделе Справочник Rust API. Справочник по Python API см. в разделе Справочник Python API. Подробности о типах см. в разделе Типы и перечисления.
Все объекты, владеющие дескриптором (PdfDocument, Pdf, DocumentEditor), владеют нативной памятью и должны быть закрыты. Идиоматичный приём — блочная форма, которая закрывает их автоматически; метод #close идемпотентен.
PdfOxide (модуль)
Удобные точки входа верхнего уровня и переключатели уровня процесса.
PdfOxide.open(source, password: nil) { |doc| ... } -> PdfDocument
Открыть PDF для чтения. Делегирует вызов PdfDocument.open. Принимает путь к файлу или сырые байты PDF; блочная форма закрывает документ автоматически.
PdfOxide.version -> String
Вернуть строку версии библиотеки (например, "0.3.69").
PdfOxide.set_max_ops_per_stream(limit) -> Integer
Установить общий для процесса предел числа операторов потока содержимого. Отрицательное значение limit восстанавливает значение по умолчанию (1 000 000); любое неотрицательное значение становится явным пределом. Возвращает предыдущий предел.
PdfOxide.set_preserve_unmapped_glyphs(preserve) -> Integer
Переключить общий для процесса флаг сохранения U+FFFD (несопоставленных глифов), используемый при извлечении текста. Истинное/ненулевое значение сохраняет их; ложное/0 — отфильтровывает (значение по умолчанию). Возвращает предыдущее значение (0 или 1).
PdfDocument
Основная точка входа для чтения PDF: извлечение, поиск, конвертация, рендеринг и доступ к страницам.
doc = PdfOxide::PdfDocument.open('invoice.pdf')
Конструктор и методы класса
PdfOxide::PdfDocument.open(source, password: nil) { |doc| ... } -> PdfDocument
Открыть PDF по пути в файловой системе или из сырых байтов PDF (распознаются автоматически по магической сигнатуре %PDF- в бинарных данных). Блочная форма закрывает документ автоматически; форма без блока возвращает документ. Возбуждает FileNotFoundError, ParseError или EncryptedError.
PdfOxide::PdfDocument.new(source, password: nil) -> PdfDocument
Создать напрямую, без блока. Предпочтительнее использовать .open.
PdfOxide::PdfDocument.extract_text(source, page: 0) -> String
Вспомогательный метод за один вызов: открыть, извлечь текст одной страницы и закрыть.
Информация о документе
doc.page_count -> Integer
Число страниц в документе.
doc.pdf_version -> String
Строка версии PDF (например, "1.7") или "unknown", если она недоступна.
doc.encrypted? -> Boolean
Содержит ли PDF словарь шифрования.
doc.path -> String
Абсолютный путь, из которого открыт документ (или <in-memory> для документов, открытых из байтов).
Аутентификация
doc.authenticate(password) -> Boolean
Аутентифицироваться относительно шифрования этого документа. Возвращает true при успехе или для незашифрованных документов.
Извлечение текста
doc.extract_text(page_index) -> String
Извлечь обычный текст с одной страницы (нумерация с нуля; пусто для страниц без текстового слоя).
doc.extract_structured(page) -> Hash
Извлечь структурированное представление страницы в виде Hash с ключами page_index, page_width, page_height и regions (у каждого — kind, text, bbox, spans, column_index).
doc.extract_text_auto(page_index) -> String
Извлечение с автоматической маршрутизацией: нативный текст там, где он есть, OCR для отсканированных регионов, если доступна feature ocr, с корректным откатом к нативному тексту (никогда не возбуждает «OCR unavailable»).
Конвертация
doc.to_markdown(page_index = nil) -> String
Конвертировать одну страницу в Markdown или весь документ, когда page_index равен nil.
doc.to_html(page_index = nil) -> String
Конвертировать одну страницу в HTML или весь документ, когда page_index равен nil.
Поиск
doc.search(query, case_sensitive: false, regex: false) -> Array<Hash>
Поиск по документу. Каждое совпадение — { page:, text:, bbox: { x:, y:, width:, height: } }. Передайте regex: true, чтобы интерпретировать query как регулярное выражение (возбуждает UnsupportedFeatureError, если в сборке нет поиска по регулярным выражениям).
Формы
doc.form_fields -> Array<Hash>
Поля AcroForm в виде хешей { name:, value:, type:, page: }. Возвращает [], если в сборке нет аксессора извлечения форм.
Рендеринг
doc.render(page_index, dpi: 150) -> String
Отрендерить одну страницу в байты PNG (BINARY) с заданным DPI.
doc.render_with_layers(page_index, dpi: 150, format: 0,
background: [1.0, 1.0, 1.0, 1.0], transparent: false,
render_annotations: true, jpeg_quality: 90,
excluded_layers: []) -> String
Отрендерить страницу с полным набором RenderOptions и фильтрацией слоёв Optional-Content-Group (OCG). format: 0 = PNG, 1 = JPEG; excluded_layers перечисляет /Name групп OCG, которые нужно скрыть. Возвращает закодированные байты изображения (BINARY).
Доступ к страницам
doc.page(index) -> PdfPage
Облегчённое представление PdfPage страницы с индексом index.
doc.pages -> Array<PdfPage>
Каждая страница документа (вычисляется немедленно).
Авто-извлечение
doc.auto_extractor -> AutoExtractor
Настроенный AutoExtractor для этого документа (мемоизируется).
Жизненный цикл
doc.close -> nil
Освободить нативный дескриптор. Идемпотентно.
doc.open? -> Boolean
doc.closed? -> Boolean
Открыт ли документ ещё / был ли он закрыт.
PdfPage
Облегчённое представление отдельной страницы, заимствованное у PdfDocument. Не владеет собственным нативным дескриптором. Создаётся через PdfDocument#page или #pages.
page = doc.page(0)
Атрибуты
page.parent -> PdfDocument
page.index -> Integer
Документ-владелец и индекс страницы (нумерация с нуля).
Геометрия
page.width -> Float
page.height -> Float
Ширина и высота страницы в единицах пользовательского пространства PDF.
page.media_box -> Hash
page.crop_box -> Hash
{ x:, y:, width:, height: } для media box / crop box (crop box откатывается к media box).
page.rotation -> Integer
Поворот страницы в градусах.
Текст
page.text -> String
Извлечь текст этой страницы (эквивалент parent.extract_text(index)).
page.to_s -> String
page.inspect -> String
Краткая метка для инспекции (#<PdfOxide::PdfPage index=N>).
Создание и сохранение PDF: источники Markdown/HTML/текст/изображения, экспорт в байты и планирование разбиения по закладкам.
pdf = PdfOxide::Pdf.from_markdown("# Title\n\nBody")
Фабричные методы
PdfOxide::Pdf.from_markdown(markdown) { |pdf| ... } -> Pdf
Построить PDF из Markdown.
PdfOxide::Pdf.from_html(html) { |pdf| ... } -> Pdf
Построить PDF из HTML (CSS учитывается через конвейер html_css).
PdfOxide::Pdf.from_text(text) { |pdf| ... } -> Pdf
Построить PDF из обычного текста.
PdfOxide::Pdf.from_images(images) { |pdf| ... } -> Pdf
Построить PDF из массива байтовых блобов JPEG/PNG (формат распознаётся автоматически по магическим байтам).
PdfOxide::Pdf.create_empty { |pdf| ... } -> Pdf
Создать пустой PDF из одной страницы.
Статические вспомогательные методы
PdfOxide::Pdf.version -> String
Версия библиотеки.
PdfOxide::Pdf.prefetch_models(languages) -> String
Предзагрузить OCR-модели для заданных языковых тегов BCP-47/ISO. Возвращает путь к каталогу кэша (пусто в сборках без OCR).
PdfOxide::Pdf.prefetch_available? -> Boolean
Поддерживает ли сборка предоставление OCR-моделей.
PdfOxide::Pdf.plan_split_by_bookmarks_count(source_pdf, level) -> Integer
Подсчитать число сегментов разбиения по закладкам, которое получилось бы при разбиении source_pdf (сырые байты) на уровне level (1 = верхний уровень, 0 = все), не создавая вывода.
Методы экземпляра
pdf.to_bytes -> String
PDF в виде байтов с кодировкой BINARY.
pdf.save(path) -> String
Записать PDF по пути path. Возвращает абсолютный путь записанного файла.
pdf.close -> nil
pdf.closed? -> Boolean
Освободить нативный дескриптор (идемпотентно) / был ли он закрыт.
DocumentEditor
Редактор для записи: необратимое удаление данных (redaction), очистка метаданных, заполнение форм и инкрементное сохранение. Каждая операция удаления данных работает по принципу fail-closed (ненулевой результат возбуждает исключение).
PdfOxide::DocumentEditor.open('source.pdf') do |ed|
ed.add_redaction(page: 0, rect: [100, 200, 300, 250])
ed.apply_redactions!
ed.save_to('redacted.pdf')
end
Конструктор
PdfOxide::DocumentEditor.open(source) { |ed| ... } -> DocumentEditor
Открыть редактор над PDF на диске или из байтов в памяти. Блочная форма закрывает автоматически.
PdfOxide::DocumentEditor.new(source) -> DocumentEditor
Создать напрямую, без блока.
Удаление данных (redaction)
ed.add_redaction(page:, rect:, color: [0.0, 0.0, 0.0]) -> self
Поставить в очередь прямоугольник удаления (rect = [x1, y1, x2, y2] в пользовательском пространстве PDF; color = [r, g, b]). Не применяется до вызова apply_redactions!.
ed.redaction_count(page) -> Integer
Общее число удалений, поставленных в очередь для страницы.
ed.apply_redactions!(scrub_metadata: false, fill_color: [0.0, 0.0, 0.0]) -> self
Применить все поставленные в очередь удаления необратимо, при желании очистив /Info, XMP и JS.
ed.scrub_metadata -> self
Удалить метаданные без областей удаления данных.
Формы
ed.set_form_field(name, value) -> self
Установить поле AcroForm по полному имени, разделённому точками. Значение типа Boolean адресует чекбокс/радиокнопку; иначе устанавливается текстовое значение.
Сохранение и жизненный цикл
ed.save_to(path) -> String
Сохранить отредактированный PDF. Возвращает абсолютный путь записанного файла.
ed.to_bytes -> String
Отредактированный PDF в виде байтов с кодировкой BINARY.
ed.close -> nil
ed.closed? -> Boolean
Освободить нативный дескриптор (идемпотентно) / был ли он закрыт.
AutoExtractor
Авто-извлечение с типизированными причинами (маршрутизация «текст vs OCR» с корректным откатом к нативному тексту). Создаётся из PdfDocument.
ax = PdfOxide::AutoExtractor.new(doc)
result = ax.extract_page(0)
warn "degraded: #{result[:reason]}" unless ax.ok?(result[:reason])
Конструктор и атрибут
PdfOxide::AutoExtractor.new(document) -> AutoExtractor
Обернуть PdfDocument для авто-извлечения.
ax.document -> PdfDocument
Обёрнутый документ.
Классификация
ax.classify_page(page_index) -> Hash
Дешёвый постраничный классификатор (без OCR/растеризации). Возвращает { reason:, kind:, confidence:, classification: }.
ax.classify_document -> Hash
Классификатор всего документа; возвращает декодированный JSON-конверт.
Извлечение
ax.extract_text(page_index) -> Hash
Извлечь текст страницы через авто-маршрутизатор; возвращает { text:, reason:, kind:, confidence:, classification: }.
ax.extract_page(page_index, options: nil) -> Hash
Подробное постраничное извлечение, возвращающее полный конверт PageExtraction (текст + bbox по регионам + причина + уверенность), слитый в Hash.
Предикаты
ax.ok?(reason) -> Boolean
Представляет ли reason чистое извлечение.
ax.ocr_fallback?(reason) -> Boolean
Сработал ли путь корректного отката при недоступности OCR.
PdfOxide::AutoExtractor.prefetch_available? -> Boolean
Поддерживает ли сборка предоставление OCR.
Константы
AutoExtractor::REASONS — замороженный массив типизированных символов-причин (:ok, :native_text_high_confidence, :no_text_layer_present, :ocr_requested_but_unavailable и т. д.). AutoExtractor::PAGE_KINDS — символы видов страниц (:text_layer, :scanned, :image_text, :mixed, :empty).
MarkdownConverter
Модуль без состояния, конвертирующий PdfDocument в Markdown или HTML.
PdfOxide::MarkdownConverter.to_markdown(doc, page_index = nil) -> String
Конвертировать страницу (или весь документ, когда page_index равен nil) в Markdown.
PdfOxide::MarkdownConverter.to_html(doc, page_index = nil) -> String
Конвертировать страницу (или весь документ) в HTML.
PdfPolicy
Общая для процесса политика управления криптографией с семантикой «устанавливается один раз». Вызывайте .set до любой другой операции PDF Oxide.
PdfOxide::PdfPolicy.current -> Symbol
Текущий режим политики процесса (:compat, :strict или :fips_strict).
PdfOxide::PdfPolicy.set(mode) -> Symbol
Установить общий для процесса режим политики. Возбуждает исключение, если режим уже установлен или не поддерживается сборкой.
PdfOxide::PdfPolicy.compat -> Symbol
PdfOxide::PdfPolicy.strict -> Symbol
PdfOxide::PdfPolicy.fips_strict -> Symbol
Символы предустановленных режимов: принимать все алгоритмы / отклонять устаревшие алгоритмы / только FIPS 140-3.
PdfPolicy::MODES — замороженное сопоставление символов режимов с порядковыми номерами cdylib.
PdfSigner
Программа цифровой подписи PAdES B-B / B-T / B-LT / B-LTA. Подпись — операция безопасности: каждый ненулевой результат работает по принципу fail-closed.
PdfOxide::PdfSigner.new(certificate_handle) -> PdfSigner
Создать программу подписи из непрозрачного дескриптора учётных данных PKCS#12/PEM.
signer.sign(pdf, level:, tsa_url: nil, reason: nil, location: nil) -> String
Подписать сырые байты PDF на запрошенном уровне PAdES (:b, :t, :lt, :lta). Для уровней >= :t требуется tsa_url. Возвращает подписанные байты PDF с кодировкой BINARY.
PdfOxide::PdfSigner.sign(pdf:, certificate_handle:, level:, tsa_url: nil, reason: nil, location: nil) -> String
Статический удобный метод: подписать без создания экземпляра программы подписи.
PdfOxide::PdfSigner.pades_level(signature_handle) -> Integer
Порядковый номер уровня PAdES существующего дескриптора подписи.
PdfOxide::PdfSigner.document_has_timestamp?(document_handle) -> Boolean
Содержит ли документ метку времени уровня документа /DocTimeStamp.
PdfSigner::LEVELS — замороженное сопоставление символов уровней с кодами. PdfSigner::PadesSignOptions — упакованная FFI::Struct, повторяющая C-раскладку PadesSignOptionsC.
PdfValidator
Проверка соответствия PDF/A и PDF/UA без состояния.
PdfOxide::PdfValidator.pdf_a?(doc, level: :a1b) -> Boolean
Соответствует ли документ PDF/A для уровня level (:a1b, :a1a, :a2b, :a2a, :a2u, :a3b, :a3a, :a3u).
PdfOxide::PdfValidator.pdf_ua?(doc, level: :ua1) -> Boolean
Соответствует ли документ PDF/UA для уровня level (:ua1 или :ua2).
PdfOxide::PdfValidator.validate_pdf_a(doc, level: :a1b) -> Hash
Упрощённый результат PDF/A: { compliant:, violations: }.
PdfOxide::PdfValidator.validate_pdf_ua(doc, level: :ua1) -> Hash
Упрощённый результат PDF/UA: { compliant:, violations: }.
PdfValidator::PDF_A_LEVELS и PdfValidator::PDF_UA_LEVELS — замороженные сопоставления уровней с порядковыми номерами.
Обработка ошибок
Все исключения PDF Oxide наследуются от PdfOxide::Error. Нативные коды ошибок отображаются один к одному на подклассы ниже.
begin
doc = PdfOxide::PdfDocument.open('file.pdf')
text = doc.extract_text(0)
rescue PdfOxide::FileNotFoundError
warn 'file not found'
rescue PdfOxide::ParseError => e
warn "malformed PDF: #{e.message}"
rescue PdfOxide::Error => e
warn "PDF error: #{e.message}"
ensure
doc&.close
end
| Исключение | Причина |
|---|---|
Error |
Базовый класс для всех ошибок PDF Oxide |
UnsupportedPlatformError |
Платформа хоста не поддерживается встроенной cdylib |
ArgumentError |
Аргумент не прошёл проверку до нативного вызова |
IoError |
Сбой файловой системы / ввода-вывода |
FileNotFoundError |
Отсутствующий файл (специализация IoError) |
ParseError |
Некорректный заголовок, повреждённый xref, сбой извлечения |
StateError |
Неверный порядок операций |
InvalidStateError |
Операция над уже закрытым дескриптором (специализация StateError) |
EncryptedError |
Сбой шифрования / неверный пароль |
PermissionError |
Зашифрованный PDF без права на извлечение/подпись |
UnsupportedFeatureError |
Функция не скомпилирована в эту сборку cdylib |
SignatureError |
Сбой подписи / проверки PAdES |
RedactionError |
Сбой необратимого удаления данных (fail-closed) |
ComplianceError |
Сбой проверки PDF/A · PDF/UA |
SearchError |
Сбой нативного текстового поиска |
InternalError |
Общий сбой на нативной стороне |
Полный пример
require 'pdf_oxide'
# --- Extraction ---
PdfOxide::PdfDocument.open('input.pdf') do |doc|
puts "Pages: #{doc.page_count}"
doc.page_count.times do |i|
puts "Page #{i + 1}: #{doc.extract_text(i).length} characters"
end
# Search
doc.search('configuration', case_sensitive: false).each do |m|
puts "Page #{m[:page] + 1}: '#{m[:text]}' at (#{m[:bbox][:x]}, #{m[:bbox][:y]})"
end
# Render page 1 to PNG
File.binwrite('page1.png', doc.render(0, dpi: 150))
end
# --- Creation ---
PdfOxide::Pdf.from_markdown("# Report\n\nGenerated by PDF Oxide.") do |pdf|
pdf.save('report.pdf')
end
# --- Redaction ---
PdfOxide::DocumentEditor.open('source.pdf') do |ed|
ed.add_redaction(page: 0, rect: [100, 200, 300, 250])
ed.apply_redactions!(scrub_metadata: true)
ed.save_to('redacted.pdf')
end
# --- Validation ---
PdfOxide::PdfDocument.open('archive.pdf') do |doc|
puts "PDF/A-1b compliant: #{PdfOxide::PdfValidator.pdf_a?(doc, level: :a1b)}"
end
Other Language Bindings
PDF Oxide предоставляет нативные привязки для всех основных экосистем: Rust, Python, Node.js, WASM, C#, Golang, Java, PHP, C++, Swift, Kotlin, Dart, R, Julia, Zig, Scala, Clojure, Objective-C, и Elixir.
Дальнейшие шаги
- Типы и перечисления — все общие типы и перечисления
- Справочник Page API — единообразная постраничная итерация для всех привязок
- Начало работы с Ruby — учебное руководство