Referencia de la API de Ruby
PDF Oxide incluye bindings nativos de Ruby (la gem pdf_oxide) construidos sobre FFI por encima del ABI de C del cdylib. La gem empaqueta una librería nativa precompilada y reproduce la estructura de 9 clases del binding de Java bajo el espacio de nombres PdfOxide.
gem install pdf_oxide
require 'pdf_oxide'
Para la API de Rust, consulta la Referencia de la API de Rust. Para la API de Python, consulta la Referencia de la API de Python. Para los detalles de tipos, consulta Tipos y enums.
Todos los objetos que poseen un handle (PdfDocument, Pdf, DocumentEditor) son dueños de memoria nativa y deben cerrarse. El patrón idiomático es la forma con bloque, que cierra automáticamente; #close es idempotente.
PdfOxide (módulo)
Puntos de entrada de conveniencia de nivel superior y conmutadores globales del proceso.
PdfOxide.open(source, password: nil) { |doc| ... } -> PdfDocument
Abre un PDF para lectura. Delega en PdfDocument.open. Acepta una ruta de archivo o bytes crudos de PDF; la forma con bloque cierra automáticamente.
PdfOxide.version -> String
Devuelve la cadena de versión de la librería (p. ej. "0.3.69").
PdfOxide.set_max_ops_per_stream(limit) -> Integer
Establece el tope global del proceso para los operadores del flujo de contenido. Un limit negativo restaura el valor por defecto (1 000 000); cualquier valor no negativo se convierte en el tope explícito. Devuelve el tope anterior.
PdfOxide.set_preserve_unmapped_glyphs(preserve) -> Integer
Activa o desactiva el indicador global del proceso de preservación de U+FFFD (glifo sin mapear) que usa la extracción de texto. Un valor verdadero/distinto de cero preserva; uno falso/0 filtra (valor por defecto). Devuelve el valor anterior (0 o 1).
PdfDocument
El punto de entrada principal de solo lectura a un PDF: extracción, búsqueda, conversión, renderizado y acceso a páginas.
doc = PdfOxide::PdfDocument.open('invoice.pdf')
Constructor y métodos de clase
PdfOxide::PdfDocument.open(source, password: nil) { |doc| ... } -> PdfDocument
Abre un PDF desde una ruta del sistema de archivos o bytes crudos de PDF (detectados automáticamente mediante la cabecera mágica %PDF- en una entrada binaria). La forma con bloque cierra automáticamente; la forma sin bloque devuelve el documento. Lanza FileNotFoundError, ParseError o EncryptedError.
PdfOxide::PdfDocument.new(source, password: nil) -> PdfDocument
Construye directamente sin bloque. Prefiere .open.
PdfOxide::PdfDocument.extract_text(source, page: 0) -> String
Atajo en una sola llamada: abre, extrae el texto de una única página y cierra.
Información del documento
doc.page_count -> Integer
Número de páginas del documento.
doc.pdf_version -> String
Cadena de versión del PDF (p. ej. "1.7"), o "unknown" si no está disponible.
doc.encrypted? -> Boolean
Si el PDF lleva un diccionario de cifrado.
doc.path -> String
Ruta absoluta desde la que se abrió el documento (o <in-memory> para documentos abiertos desde bytes).
Autenticación
doc.authenticate(password) -> Boolean
Autentica contra el cifrado de este documento. Devuelve true si tiene éxito o para documentos sin cifrar.
Extracción de texto
doc.extract_text(page_index) -> String
Extrae texto plano de una única página con índice basado en cero (vacío para páginas sin capa de texto).
doc.extract_structured(page) -> Hash
Extrae una representación estructurada de una página como un Hash con page_index, page_width, page_height y regions (cada una con kind, text, bbox, spans, column_index).
doc.extract_text_auto(page_index) -> String
Extracción con enrutado automático: texto nativo donde lo haya, OCR para las regiones escaneadas cuando la característica ocr esté disponible, con un repliegue elegante al texto nativo (nunca lanza “OCR no disponible”).
Conversión
doc.to_markdown(page_index = nil) -> String
Convierte una página a Markdown, o el documento completo cuando page_index es nil.
doc.to_html(page_index = nil) -> String
Convierte una página a HTML, o el documento completo cuando page_index es nil.
Búsqueda
doc.search(query, case_sensitive: false, regex: false) -> Array<Hash>
Busca en el documento. Cada coincidencia es { page:, text:, bbox: { x:, y:, width:, height: } }. Pasa regex: true para interpretar query como una expresión regular (lanza UnsupportedFeatureError si la build no incluye búsqueda con regex).
Formularios
doc.form_fields -> Array<Hash>
Campos de AcroForm como hashes { name:, value:, type:, page: }. Devuelve [] cuando la build no incluye el accesor de extracción de formularios.
Renderizado
doc.render(page_index, dpi: 150) -> String
Renderiza una única página a bytes PNG (BINARY) con el DPI indicado.
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
Renderiza una página con toda la superficie de RenderOptions más el filtrado de capas de grupos de contenido opcional (OCG). format: 0 = PNG, 1 = JPEG; excluded_layers enumera los /Name de OCG que se deben suprimir. Devuelve los bytes de imagen codificados (BINARY).
Acceso a páginas
doc.page(index) -> PdfPage
Una vista ligera PdfPage de la página en index.
doc.pages -> Array<PdfPage>
Todas las páginas del documento (de forma anticipada).
Extracción automática
doc.auto_extractor -> AutoExtractor
El AutoExtractor configurado para este documento (memoizado).
Ciclo de vida
doc.close -> nil
Libera el handle nativo. Idempotente.
doc.open? -> Boolean
doc.closed? -> Boolean
Si el documento sigue abierto / ha sido cerrado.
PdfPage
Una vista ligera por página tomada en préstamo de un PdfDocument. No posee ningún handle nativo propio. Se construye mediante PdfDocument#page o #pages.
page = doc.page(0)
Atributos
page.parent -> PdfDocument
page.index -> Integer
El documento propietario y el índice de página basado en cero.
Geometría
page.width -> Float
page.height -> Float
Ancho y alto de la página en unidades del espacio de usuario del PDF.
page.media_box -> Hash
page.crop_box -> Hash
{ x:, y:, width:, height: } para el media box / crop box (el crop box recurre al media box).
page.rotation -> Integer
Rotación de la página en grados.
Texto
page.text -> String
Extrae el texto de esta página (equivalente a parent.extract_text(index)).
page.to_s -> String
page.inspect -> String
Etiqueta corta de inspección (#<PdfOxide::PdfPage index=N>).
Crea y guarda PDF: fuentes Markdown/HTML/texto/imagen, exportación a bytes y planificación de división por marcadores.
pdf = PdfOxide::Pdf.from_markdown("# Title\n\nBody")
Métodos de fábrica
PdfOxide::Pdf.from_markdown(markdown) { |pdf| ... } -> Pdf
Construye un PDF a partir de Markdown.
PdfOxide::Pdf.from_html(html) { |pdf| ... } -> Pdf
Construye un PDF a partir de HTML (el CSS se respeta mediante la canalización html_css).
PdfOxide::Pdf.from_text(text) { |pdf| ... } -> Pdf
Construye un PDF a partir de texto plano.
PdfOxide::Pdf.from_images(images) { |pdf| ... } -> Pdf
Construye un PDF a partir de un array de blobs de bytes JPEG/PNG (el formato se detecta automáticamente a partir de los bytes mágicos).
PdfOxide::Pdf.create_empty { |pdf| ... } -> Pdf
Crea un PDF en blanco de una sola página.
Auxiliares estáticos
PdfOxide::Pdf.version -> String
La versión de la librería.
PdfOxide::Pdf.prefetch_models(languages) -> String
Precarga los modelos de OCR para las etiquetas de idioma BCP-47/ISO indicadas. Devuelve la ruta del directorio de caché (vacía en builds sin OCR).
PdfOxide::Pdf.prefetch_available? -> Boolean
Si la build admite el aprovisionamiento de modelos de OCR.
PdfOxide::Pdf.plan_split_by_bookmarks_count(source_pdf, level) -> Integer
Cuenta los segmentos de división por marcadores que resultarían de dividir source_pdf (bytes crudos) en level (1 = nivel superior, 0 = todos), sin producir ninguna salida.
Métodos de instancia
pdf.to_bytes -> String
El PDF como bytes con codificación BINARY.
pdf.save(path) -> String
Escribe el PDF en path. Devuelve la ruta absoluta escrita.
pdf.close -> nil
pdf.closed? -> Boolean
Libera el handle nativo (idempotente) / si ya ha sido cerrado.
DocumentEditor
Editor del lado de escritura: redacción destructiva, limpieza de metadatos, relleno de formularios y guardado incremental. Toda operación de redacción falla de forma segura (un retorno distinto de cero lanza una excepción).
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
Constructor
PdfOxide::DocumentEditor.open(source) { |ed| ... } -> DocumentEditor
Abre un editor sobre un PDF en disco o sobre bytes en memoria. La forma con bloque cierra automáticamente.
PdfOxide::DocumentEditor.new(source) -> DocumentEditor
Construye directamente sin bloque.
Redacción
ed.add_redaction(page:, rect:, color: [0.0, 0.0, 0.0]) -> self
Encola un rectángulo de redacción (rect = [x1, y1, x2, y2] en el espacio de usuario del PDF; color = [r, g, b]). No se aplica hasta apply_redactions!.
ed.redaction_count(page) -> Integer
Total de redacciones encoladas para la página.
ed.apply_redactions!(scrub_metadata: false, fill_color: [0.0, 0.0, 0.0]) -> self
Aplica de forma destructiva todas las redacciones encoladas y, opcionalmente, limpia /Info, XMP y JS.
ed.scrub_metadata -> self
Elimina los metadatos sin regiones de redacción.
Formularios
ed.set_form_field(name, value) -> self
Establece un campo de AcroForm por su nombre completo separado por puntos. Un value booleano apunta a una casilla de verificación o un radio; en caso contrario, establece un valor de texto.
Guardado y ciclo de vida
ed.save_to(path) -> String
Guarda el PDF editado. Devuelve la ruta absoluta escrita.
ed.to_bytes -> String
El PDF editado como bytes con codificación BINARY.
ed.close -> nil
ed.closed? -> Boolean
Libera el handle nativo (idempotente) / si ya ha sido cerrado.
AutoExtractor
Extracción automática con motivos tipados (enrutado entre texto y OCR con repliegue elegante al modo nativo). Se construye a partir de un PdfDocument.
ax = PdfOxide::AutoExtractor.new(doc)
result = ax.extract_page(0)
warn "degraded: #{result[:reason]}" unless ax.ok?(result[:reason])
Constructor y atributo
PdfOxide::AutoExtractor.new(document) -> AutoExtractor
Envuelve un PdfDocument para la extracción automática.
ax.document -> PdfDocument
El documento envuelto.
Clasificación
ax.classify_page(page_index) -> Hash
Clasificador por página de bajo coste (sin OCR ni rasterización). Devuelve { reason:, kind:, confidence:, classification: }.
ax.classify_document -> Hash
Clasificador de todo el documento; devuelve el envoltorio JSON decodificado.
Extracción
ax.extract_text(page_index) -> Hash
Extrae el texto de una página mediante el enrutador automático; devuelve { text:, reason:, kind:, confidence:, classification: }.
ax.extract_page(page_index, options: nil) -> Hash
Extracción enriquecida por página que devuelve el envoltorio completo PageExtraction (texto + bbox por región + motivo + confianza) fusionado en un Hash.
Predicados
ax.ok?(reason) -> Boolean
Si reason representa una extracción limpia.
ax.ocr_fallback?(reason) -> Boolean
Si se activó la ruta de repliegue elegante por OCR no disponible.
PdfOxide::AutoExtractor.prefetch_available? -> Boolean
Si la build admite el aprovisionamiento de OCR.
Constantes
AutoExtractor::REASONS — array congelado de símbolos de motivo tipados (:ok, :native_text_high_confidence, :no_text_layer_present, :ocr_requested_but_unavailable, etc.). AutoExtractor::PAGE_KINDS — símbolos de tipo de página (:text_layer, :scanned, :image_text, :mixed, :empty).
MarkdownConverter
Módulo sin estado que convierte un PdfDocument a Markdown o HTML.
PdfOxide::MarkdownConverter.to_markdown(doc, page_index = nil) -> String
Convierte una página (o el documento completo cuando page_index es nil) a Markdown.
PdfOxide::MarkdownConverter.to_html(doc, page_index = nil) -> String
Convierte una página (o el documento completo) a HTML.
PdfPolicy
Política de gobernanza criptográfica global del proceso con semántica de establecimiento único. Llama a .set antes de cualquier otra operación de PDF Oxide.
PdfOxide::PdfPolicy.current -> Symbol
El modo de política actual del proceso (:compat, :strict o :fips_strict).
PdfOxide::PdfPolicy.set(mode) -> Symbol
Establece el modo de política global del proceso. Lanza una excepción si ya está establecido o no lo admite la build.
PdfOxide::PdfPolicy.compat -> Symbol
PdfOxide::PdfPolicy.strict -> Symbol
PdfOxide::PdfPolicy.fips_strict -> Symbol
Símbolos de modo predefinidos: aceptar todos los algoritmos / rechazar los algoritmos heredados / solo FIPS 140-3.
PdfPolicy::MODES — mapeo congelado de símbolos de modo a ordinales del cdylib.
PdfSigner
Firmante de firma digital PAdES B-B / B-T / B-LT / B-LTA. La firma es una operación de seguridad: todo retorno distinto de cero falla de forma segura.
PdfOxide::PdfSigner.new(certificate_handle) -> PdfSigner
Construye un firmante a partir de un handle opaco de credenciales PKCS#12/PEM.
signer.sign(pdf, level:, tsa_url: nil, reason: nil, location: nil) -> String
Firma bytes crudos de PDF en el nivel PAdES solicitado (:b, :t, :lt, :lta). Se requiere un tsa_url para los niveles >= :t. Devuelve los bytes del PDF firmado con codificación BINARY.
PdfOxide::PdfSigner.sign(pdf:, certificate_handle:, level:, tsa_url: nil, reason: nil, location: nil) -> String
Conveniencia estática: firma sin construir una instancia del firmante.
PdfOxide::PdfSigner.pades_level(signature_handle) -> Integer
El ordinal del nivel PAdES de un handle de firma existente.
PdfOxide::PdfSigner.document_has_timestamp?(document_handle) -> Boolean
Si el documento lleva un /DocTimeStamp con alcance de documento.
PdfSigner::LEVELS — mapeo congelado de símbolos de nivel a códigos. PdfSigner::PadesSignOptions — FFI::Struct empaquetado que reproduce la disposición de PadesSignOptionsC en C.
PdfValidator
Validación sin estado del cumplimiento de PDF/A y PDF/UA.
PdfOxide::PdfValidator.pdf_a?(doc, level: :a1b) -> Boolean
Si el documento cumple con PDF/A para level (:a1b, :a1a, :a2b, :a2a, :a2u, :a3b, :a3a, :a3u).
PdfOxide::PdfValidator.pdf_ua?(doc, level: :ua1) -> Boolean
Si el documento cumple con PDF/UA para level (:ua1 o :ua2).
PdfOxide::PdfValidator.validate_pdf_a(doc, level: :a1b) -> Hash
Resultado simplificado de PDF/A: { compliant:, violations: }.
PdfOxide::PdfValidator.validate_pdf_ua(doc, level: :ua1) -> Hash
Resultado simplificado de PDF/UA: { compliant:, violations: }.
PdfValidator::PDF_A_LEVELS y PdfValidator::PDF_UA_LEVELS — mapeos congelados de nivel a ordinal.
Manejo de errores
Todas las excepciones de PDF Oxide derivan de PdfOxide::Error. Los códigos de error nativos se corresponden uno a uno con las subclases siguientes.
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
| Excepción | Causa |
|---|---|
Error |
Clase base de todos los errores de PDF Oxide |
UnsupportedPlatformError |
Plataforma anfitriona no admitida por el cdylib incluido |
ArgumentError |
Un argumento no superó la validación antes de la llamada nativa |
IoError |
Fallo del sistema de archivos / de E/S |
FileNotFoundError |
Archivo inexistente (especializa IoError) |
ParseError |
Cabecera malformada, xref corrupta, fallo de extracción |
StateError |
Orden de operación incorrecto |
InvalidStateError |
Operación sobre un handle ya cerrado (especializa StateError) |
EncryptedError |
Fallo de cifrado / contraseña incorrecta |
PermissionError |
PDF cifrado sin permiso de extracción/firma |
UnsupportedFeatureError |
Característica no compilada en esta build del cdylib |
SignatureError |
Fallo de firma / verificación PAdES |
RedactionError |
Fallo de redacción destructiva (falla de forma segura) |
ComplianceError |
Fallo de validación PDF/A · PDF/UA |
SearchError |
Fallo de búsqueda de texto nativa |
InternalError |
Fallo genérico del lado nativo |
Ejemplo completo
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 ofrece bindings nativos para todos los ecosistemas principales: Rust, Python, Node.js, WASM, C#, Golang, Java, PHP, C++, Swift, Kotlin, Dart, R, Julia, Zig, Scala, Clojure, Objective-C y Elixir.
Próximos pasos
- Tipos y enums — todos los tipos y enums compartidos
- Referencia de la API Page — iteración de página consistente entre bindings
- Primeros pasos con Ruby — tutorial