Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for PDF/A-1b #1029

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
language: ruby
env:
- VERAPDF_VERSION=1.6.3 VERAPDF_VERSION_SHORT=1.6
before_install:
- gem update --system
- gem install bundler
- bundle --version
- wget http://software.verapdf.org/rel/${VERAPDF_VERSION_SHORT}/verapdf-${VERAPDF_VERSION}-installer.zip
- unzip verapdf-${VERAPDF_VERSION}-installer.zip
- java -jar -DINSTALL_PATH=${PWD}/verapdf verapdf-${VERAPDF_VERSION}/verapdf-izpack-installer-${VERAPDF_VERSION}.jar -options-system
- export PATH=$PATH:$PWD/verapdf
- verapdf --version
rvm:
- 2.1.0-p0
- 2.1.10
Expand Down
3 changes: 2 additions & 1 deletion lib/prawn/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class Document
:page_size, :page_layout, :margin, :left_margin,
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
:compress, :background, :info,
:text_formatter, :print_scaling
:text_formatter, :print_scaling,
:enable_pdfa_1b
].freeze

# Any module added to this array will be included into instances of
Expand Down
48 changes: 48 additions & 0 deletions spec/extensions/vera_pdf_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require 'rexml/document'
require 'open3'

module VeraPdfHelpers
VERA_PDF_EXECUTABLE = 'verapdf'.freeze
VERA_PDF_COMMAND = "#{VERA_PDF_EXECUTABLE} --flavour 1b --format xml".freeze

def which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe)
end
end
return nil
end

def vera_pdf_available?
which VERA_PDF_EXECUTABLE
end

def valid_pdfa_1b?(pdf_data)
stdout, stderr, status = Open3.capture3(VERA_PDF_COMMAND, stdin_data: pdf_data)
raise Exception, "VeraPDF could not be run. #{stderr}" unless status.success?

reported_as_compliant? stdout.lines[4..-1].join
end

def reported_as_compliant?(xml_data)
xml_doc = REXML::Document.new xml_data
xml_doc.elements.each('/processorResult/validationResult/ns2:assertions/ns2:assertion') do |element|
message = element.elements.to_a('ns2:message').first.text
clause = element.elements.to_a('ns2:ruleId').first.attributes['clause']
test = element.elements.to_a('ns2:ruleId').first.attributes['testNumber']
context = element.elements.to_a('ns2:location/ns2:context').first.text
url = 'https://github.com/veraPDF/veraPDF-validation-profiles/wiki/PDFA-Part-1-rules'
url_anchor = "rule-#{clause.delete('.')}-#{test}"
puts
puts 'PDF/A-1b VIOLATION'
puts " Message: #{message}"
puts " Context: #{context}"
puts " Details: #{url}##{url_anchor}"
puts
end
xml_doc.elements.to_a('/processorResult/validationResult').first.attributes['isCompliant'] == 'true'
end
end
2 changes: 1 addition & 1 deletion spec/manual_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
MANUAL_HASH =
case RUBY_ENGINE
when 'ruby'
'b55f154c9093c60f38051c75920c8157c775b946b0c77ffafc0a8a634ad5401e8ceafd0b96942839f82bacd726a690af3fdd1fd9e185616f67c6c0edfcfd0460'
'9b2fde84364fdde4d879c4a29072bab38dfb89e3397923ae7a5a430e96fe7fb3c5dd59962152f47940b854a2d0806c555010258e03e8d462ae2feace8637c653'
when 'jruby'
'd2eb71ea3ddc35acb185de671a6fa48862ebad5727ce372e3a742f45d31447765c4004fbe5fbfdc1f5a32903ac87182c75e6abe021ab003c8af6e6cc33e0d01e'
end
Expand Down
10 changes: 10 additions & 0 deletions spec/prawn/pdfa_1b_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'spec_helper'

include VeraPdfHelpers

if vera_pdf_available?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice to let developers know whats's wrong. But please make sure CI has all tools installed to actually run the specs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

require_relative 'pdfa_1b_spec_impl'
else
puts 'NOTICE: Specs for PDF/A-1b are not run, because veraPDF ' \
'binary was not found in path.'
end
30 changes: 30 additions & 0 deletions spec/prawn/pdfa_1b_spec_impl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'spec_helper'

describe Prawn::Document do
include VeraPdfHelpers

let(:pdf) { described_class.new(enable_pdfa_1b: true) }

describe 'PDF/A 1b conformance' do
it 'empty document' do
expect(valid_pdfa_1b?(pdf.render)).to be true
end

it 'document with some text' do
pdf.font_families.update(
'DejaVuSans' => {
normal: "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
}
)
pdf.font 'DejaVuSans' do
pdf.text_box 'Some text', at: [100, 100]
end
expect(valid_pdfa_1b?(pdf.render)).to be true
end

it 'document with some image' do
pdf.image "#{Prawn::DATADIR}/images/pigs.jpg"
expect(valid_pdfa_1b?(pdf.render)).to be true
end
end
end