Library / SDK
yob/pdf-reader avatar
yob/pdf-reader

yob/pdf-reader for Ruby PDF parsing

The PDF::Reader library implements a PDF parser conforming as much as possible to the PDF specification from Adobe.

1,931 stars290 forksRubyMIT

At a glance

What is it?
pdf-reader is a low-level Ruby library for inspecting PDF files, reading document metadata, iterating pages, extracting text and walking page content. It fits applications that need structured PDF access rather than rendered pages or a complete PDF production engine.
Who is it for?
Adopt pdf-reader when a Ruby application needs structured access to existing PDFs and can handle unsupported features or malformed files. Do not choose it for rendering, a complete visual image pipeline, or complete PDF 1.7 coverage.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 71 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What pdf-reader solves for Ruby applications

pdf-reader addresses the problem of reading PDF files programmatically without treating them as opaque binary data. The README describes the project as a parser that conforms as closely as possible to the Adobe PDF specification. It is aimed primarily at developers who need a foundation for higher-level Ruby functionality, including document inspection, indexing, metadata handling and text processing.

The library does not render a PDF. That boundary is explicit in the README. It can read document information, iterate pages, extract common text and expose page content for interpretation, but it is not presented as a viewer, rasterizer or PDF authoring tool. The distinction matters when selecting dependencies. A service that needs searchable text or metadata can use pdf-reader directly. A product that needs page thumbnails, screenshots or visual equivalence requires a different rendering layer.

The API operates at several levels. Document information is available through the main reader object, including the PDF version, document information, metadata and page count. Pages expose fonts, extracted text and raw content. The page walking API exposes operations from the page program to a receiver. At the lowest level, the object hash gives direct access to objects in the PDF file. This range makes the library suitable for both straightforward extraction and custom inspection code, although the caller remains responsible for interpreting low-level structures.

How pdf-reader exposes document and page data

A reader can be constructed from a filename or an IO stream. The filename form is the simplest path for local files. The stream form supports data supplied by an application, such as a download or an in-memory source. Once constructed, the reader represents the document and provides access to document-level data.

PDF documents are page based, so most visible information is reached through `reader.pages`. Each page can return its fonts, extracted text and raw content. Text is converted to UTF-8 before it is returned, according to the README, which gives applications a consistent string encoding even when the PDF stores text using another encoding. Binary strings such as font blobs remain marked as binary data.

For lower-level inspection, `PDF::Reader::Page#walk` traverses the page's complete rendering program. A receiver receives operations as they are encountered. The README's example handles `set_rgb_color_for_nonstroking`, showing that an application can observe drawing instructions. This mechanism is useful for analyzing a page or implementing specialized handling, but the library still does not turn those instructions into a rendered page. For direct access to the PDF object model, `reader.objects` returns the `ObjectHash`.

The architecture therefore separates document parsing, page access and page-program inspection. Callers can choose the level of detail they need, although custom code that reaches the object hash must account for PDF-specific structures itself.

Installing pdf-reader and performing a first text read

The README recommends installing the gem through RubyGems. This installs the library in the local Ruby environment. The following command is the documented installation method:

bash
gem install pdf-reader

After installation, create a reader for a PDF file and request document information. This example uses the filename accepted by `PDF::Reader.new`:

ruby
reader = PDF::Reader.new("somefile.pdf")

puts reader.pdf_version
puts reader.info
puts reader.metadata
puts reader.page_count

The first real text-oriented use is page iteration. The following reads each page's fonts, extracted text and raw content:

ruby
reader = PDF::Reader.new("somefile.pdf")

reader.pages.each do |page|
  puts page.fonts
  puts page.text
  puts page.raw_content
end

The README also gives an IO example. When opening a file directly, it strongly recommends binary mode because Ruby can otherwise alter PDF bytes, particularly on Windows and MRI 1.9.2 or later:

ruby
File.open("somefile.pdf", "rb") do |io|
  reader = PDF::Reader.new(io)
  puts reader.info
end

For a remote resource, the README uses `open-uri` and passes the resulting stream to the reader:

ruby
require 'open-uri'

io     = open('http://example.com/somefile.pdf')
reader = PDF::Reader.new(io)
puts reader.info

The examples use placeholder filenames and URLs. They demonstrate the API shape rather than a specific document.

Unsupported PDFs and extraction failures in pdf-reader

PDF::Reader explicitly states that not every aspect of the PDF 1.7 specification is supported. A PDF can therefore be valid in the broader PDF ecosystem while using a feature that this library cannot process. In that case, the documented exception is `UnsupportedFeatureError`. This is an important operational distinction from a corrupt file. A caller may need to handle unsupported features separately from malformed input.

The library also defines `MalformedPDFError` for files that appear corrupt. It has subclasses for finer-grained detection, while rescuing the parent exception catches those subclasses too. The README asks users to report files that should be valid but fail to raise an error, and also welcomes files that expose unsupported features. That request indicates that compatibility is extended through real-world PDF examples rather than through a claim of complete specification coverage.

Text extraction has a separate limitation. Some text may be stored in a way that cannot be reconstructed, or a file may contain invalid bytes. In those cases, the README says PDF::Reader outputs a little UTF-8 friendly box to indicate an unrecognizable character. Applications that compare extracted text, index it or use it for search should treat that output as a signal to inspect the source PDF rather than assuming that every result is reliable.

A final integration detail concerns streams and file modes. The README warns against using text mode for PDF input because byte conversion can damage the document. This is especially relevant for applications that receive uploads from untrusted or varied sources, since parsing failures may reflect input handling as well as the parser itself.

pdf-reader compared with a PDF renderer

The clearest alternative is a PDF rendering or conversion tool that produces page images or converts a document into another document format. The difference is the output contract. pdf-reader parses an existing PDF and exposes metadata, pages, text, raw content and drawing operations through Ruby APIs. A renderer interprets the page program for visual output, which may require much more handling than observing individual operations.

This difference affects suitability. For search indexing or document metadata extraction, pdf-reader is a direct fit because the README documents page iteration and UTF-8 text conversion. For a preview service or image thumbnail generator, the library's lack of rendering is a functional gap. The `walk` method can supply information about page operations, but it does not promise to reproduce the page.

The repository also lists examples for extracting fonts, images, Bates values, metadata, page counts and text. Those examples indicate that custom extraction workflows are an intended use. They do not change the low-level positioning of the main library. An application should inspect the relevant example files before assuming that an operation has a higher-level API.

For Ascii85 streams, the README identifies `ascii85_native` as an optional decoder. If the gem is detected, pdf-reader automatically uses it. Installing and requiring that gem is an explicit path to increased decoding performance, although the documented behavior still belongs to the parsing layer rather than page rendering.

Licensing, maintenance and upgrade considerations for pdf-reader

pdf-reader is distributed under the MIT License. The repository includes `MIT-LICENSE`, and the README points readers to that file for the applicable terms. The library is therefore intended for use under the stated MIT licensing model. This review does not replace reviewing the license text or checking how the library fits a particular distribution.

The repository is not archived, and the last push was on 2026-08-13. The repository has no GitHub releases, so release history is not represented by GitHub release entries in the available repository information. That distinction matters when planning upgrades: consumers cannot rely on a GitHub release entry to identify the installed version. The README also notes a major API change. Version 1.0.0 introduced the page-based API, the pre-1.0 API was deprecated during the 1.x series, and it was removed in 2.0.0. An upgrade across that boundary can require code changes even when the replacement page API is familiar.

The optional `ascii85_native` dependency is another operational choice. It is not required for basic installation according to the README, but it can change decoding behavior for applicable streams. A project should keep dependency and runtime assumptions explicit. The documented integrity command `rake fix_integrity` addresses CRLF-related issues in specification files on Windows, not malformed user PDFs encountered during application processing.

What to verify before adopting pdf-reader

The first verification point is feature coverage for the PDFs the application expects to receive. The README does not claim complete PDF 1.7 support, so a sample set from the target environment is more informative than the specification summary. Run the intended extraction path and observe whether it raises `UnsupportedFeatureError` or `MalformedPDFError`.

The second point is text fidelity. The library converts returned text to UTF-8, but it can emit a replacement box when text storage or invalid bytes prevent recognition. Applications that require exact characters, especially for legal or financial documents, need to inspect the output for these cases and define their own failure handling.

The third point is the required abstraction. Use `reader.pages` for common page text and font access. Use `page.walk` only when the application can interpret the page program. Use `reader.objects` when it needs low-level PDF objects. If the requirement is visual rendering, none of those documented interfaces should be treated as a replacement for a renderer.

Finally, verify upgrade boundaries and dependency behavior. The former API was removed in 2.0.0, and `ascii85_native` can be added for Ascii85 decoding. The project-specific judgement is that pdf-reader is suitable for Ruby applications that need parsed PDF structure or common text extraction, while it is not suitable as a standalone PDF rendering solution or a guarantee of complete PDF 1.7 compatibility.

Editorial conclusion

Adopt pdf-reader when a Ruby application needs structured access to existing PDFs and can handle unsupported features or malformed files. Do not choose it for rendering, a complete visual image pipeline, or complete PDF 1.7 coverage. Verify first that the library parses your target files, supports the required page and font features, and extracts text with the accuracy your application requires.

Frequently asked questions

How do I install pdf-reader in Ruby?

The README recommends RubyGems and gives `gem install pdf-reader` as the installation command.

How do I extract text from a PDF with pdf-reader?

Create a `PDF::Reader` with a filename or IO stream, then iterate through `reader.pages` and call `page.text` for each page. Returned text is converted to UTF-8.

Does pdf-reader render PDF pages?

No. The README describes pdf-reader as a low-level parser and says it does not render a PDF. It can expose raw content and walk page operations for custom interpretation.

What should I do when pdf-reader reports an unsupported PDF feature?

Handle `UnsupportedFeatureError` as an unsupported document feature. The README notes that not all aspects of PDF 1.7 are supported and asks users to contribute files that expose unsupported features.

Why can some extracted PDF text contain replacement boxes?

The README says that text may not be recoverable when it was stored in a difficult form or when invalid bytes are present. PDF::Reader then outputs a UTF-8 friendly box for the unrecognizable character.

Can pdf-reader use a native Ascii85 decoder?

Yes, according to the README. Install `ascii85_native`, then require it alongside pdf-reader or declare `gem 'ascii85_native'` in the Gemfile. When detected, pdf-reader automatically uses it for Ascii85 streams.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. yob/pdf-reader on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yob-pdf-reader.svg)](https://hysenlabs.com/projects/yob-pdf-reader)

Was this useful?