diff --git a/.travis.yml b/.travis.yml index bc519ec61..a4ad149e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/lib/prawn/document.rb b/lib/prawn/document.rb index 247be8eba..c3d1b55b7 100644 --- a/lib/prawn/document.rb +++ b/lib/prawn/document.rb @@ -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 diff --git a/spec/extensions/vera_pdf_helpers.rb b/spec/extensions/vera_pdf_helpers.rb new file mode 100644 index 000000000..74a85aefc --- /dev/null +++ b/spec/extensions/vera_pdf_helpers.rb @@ -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 diff --git a/spec/manual_spec.rb b/spec/manual_spec.rb index 3245e2db3..000546936 100644 --- a/spec/manual_spec.rb +++ b/spec/manual_spec.rb @@ -5,7 +5,7 @@ MANUAL_HASH = case RUBY_ENGINE when 'ruby' - 'b55f154c9093c60f38051c75920c8157c775b946b0c77ffafc0a8a634ad5401e8ceafd0b96942839f82bacd726a690af3fdd1fd9e185616f67c6c0edfcfd0460' + '9b2fde84364fdde4d879c4a29072bab38dfb89e3397923ae7a5a430e96fe7fb3c5dd59962152f47940b854a2d0806c555010258e03e8d462ae2feace8637c653' when 'jruby' 'd2eb71ea3ddc35acb185de671a6fa48862ebad5727ce372e3a742f45d31447765c4004fbe5fbfdc1f5a32903ac87182c75e6abe021ab003c8af6e6cc33e0d01e' end diff --git a/spec/prawn/pdfa_1b_spec.rb b/spec/prawn/pdfa_1b_spec.rb new file mode 100644 index 000000000..580ce85bf --- /dev/null +++ b/spec/prawn/pdfa_1b_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +include VeraPdfHelpers + +if vera_pdf_available? + 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 diff --git a/spec/prawn/pdfa_1b_spec_impl.rb b/spec/prawn/pdfa_1b_spec_impl.rb new file mode 100644 index 000000000..049e369ab --- /dev/null +++ b/spec/prawn/pdfa_1b_spec_impl.rb @@ -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