Skip to content

Справочник 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

Создание и сохранение 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.

Дальнейшие шаги