Majorsilence PDF — Ruby Wrapper
Ruby bindings for Majorsilence PDF — generate PDF documents in-process via an AOT-compiled native shared library (pdfnative), accessed through Fiddle FFI. No subprocess is spawned and no .NET runtime is required at runtime.
Ruby 3.0 or later is recommended (# frozen_string_literal: true and endless method definitions are used throughout; Fiddle is part of the standard library through Ruby 3.x).
Features
- Text with font size, bold, italic, underline, strikethrough, colour, and alignment
- Shapes: rectangles, lines, circles, and custom strokes
- Images (embedded or from disk)
- Tables with header colours, alternating row colours, borders, and cell padding
- Multi-page documents
- Custom and system fonts, Unicode / RTL text
- Password-protected PDFs with fine-grained permission flags
- PDF merging
- Annotations and hyperlinks
- Page sizes: A3, A4, A5, Letter, Legal, Tabloid
Installation
Install from RubyGems:
gem install majorsilence_pdf
Or add it to your Gemfile:
gem 'majorsilence_pdf'
The gem itself has no dependency beyond fiddle (Ruby's standard FFI library). You still need the pdfnative shared library, described below.
Install Ruby
-
Linux (Debian/Ubuntu):
sudo apt-get update && sudo apt-get install -y ruby ruby --version -
macOS (via Homebrew):
brew install ruby ruby --version -
Windows — download the installer from rubyinstaller.org or use winget:
winget install RubyInstallerTeam.Ruby ruby --version
Get the pdfnative shared library
Download the native library from a Majorsilence Reporting release (majorsilence-pdf-pdfnative-linux.zip, -osx.zip, or -windows.zip) and extract it. The directory contains the shared library and all its sibling libraries.
| Platform | Library filename |
|---|---|
| Linux | libpdfnative.so |
| macOS | libpdfnative.dylib |
| Windows | pdfnative.dll |
Quick start
require 'majorsilence_pdf'
lib = PdfLibrary.load('/path/to/libpdfnative.so')
doc = PdfDocument.new(lib)
doc.set_title('Hello World')
doc.('My App')
canvas = doc.add_page(*PAGE_A4)
heading = PdfStyle.new(lib)
heading.set_size(24).set_bold
canvas.draw_text('Hello, PDF!', 72, 80, heading.handle)
heading.close
body = PdfStyle.new(lib)
body.set_size(12)
canvas.draw_text('Created with majorsilence_pdf -- no .NET runtime required.', 72, 120, body.handle)
body.close
canvas.close
doc.save('hello.pdf')
doc.close
Tables
require 'majorsilence_pdf'
lib = PdfLibrary.load('/path/to/libpdfnative.so')
doc = PdfDocument.new(lib)
canvas = doc.add_page(*PAGE_A4)
table = PdfTable.new(lib, [180, 80, 90, 90])
table.set_header_bg(26, 86, 160)
.set_alternate_bg(240, 245, 252)
.set_border(200, 200, 200, 0.5)
.set_cell_padding(5)
.add_row('Product', 'Qty', 'Unit Price', 'Total')
.add_row('PDF Library Pro', '3', '$400.00', '$1,200.00')
.add_row('Report Designer', '1', '$250.00', '$250.00')
canvas.draw_table(table.handle, 72, 92)
table.close
canvas.close
doc.save('report.pdf')
doc.close
Or write to memory instead of a file with doc.save_to_memory, which returns the PDF as a binary String.
On Linux, pre-load the library directory before starting Ruby:
export LD_LIBRARY_PATH=/path/to/pdfnative-dir:$LD_LIBRARY_PATH
ruby your_script.rb
More examples
See the Examples/ directory for 18 ready-to-run scripts covering text styles, shapes, images, custom fonts, Unicode/RTL text, invoices, dashboards, password protection, table layout, and PDF merging. Each expects PDFNATIVE_LIB set to the path of the shared library:
PDFNATIVE_LIB=/path/to/libpdfnative.so ruby Examples/example_01_hello_world.rb
Releasing (maintainers)
Releases are published to RubyGems by .github/workflows/publish.yml using Trusted Publishing (OIDC) -- no API key is stored in this repo.
One-time setup on rubygems.org, under Profile -> Trusted publishers (or "Pending trusted publishers" before the gem's first release):
| Field | Value |
|---|---|
| Gem name | majorsilence_pdf |
| Repository owner | majorsilence |
| Repository name | pdf-ruby |
| Workflow filename | publish.yml |
| Environment | release |
To cut a release:
# Bump the version
$EDITOR lib/majorsilence_pdf/version.rb
git commit -am "Release vX.Y.Z"
git tag vX.Y.Z
git push origin main --tags
Pushing the vX.Y.Z tag triggers the workflow, which runs the test suite and then uses rubygems/release-gem to build and push the gem.
License
Triple-licensed under MIT, Apache-2.0, and BSD-2-Clause. Choose whichever suits your project.