lib/libis/format/converter/pdf_converter.rb in libis-format-1.3.0 vs lib/libis/format/converter/pdf_converter.rb in libis-format-1.3.2
- old
+ new
@@ -1,11 +1,11 @@
# frozen_string_literal: true
require_relative 'base'
require 'libis/tools/extend/hash'
-require 'libis/format/tool/pdf_copy'
+require 'libis/format/tool/pdf_tool'
require 'libis/format/tool/pdf_to_pdfa'
require 'libis/format/tool/pdfa_validator'
require 'libis/format/tool/pdf_optimizer'
module Libis
@@ -38,26 +38,26 @@
# @param [Hash] values list of metadata values to set
def metadata(values = {})
values.key_strings_to_symbols!
values.each do |k, v|
next unless %i[title author creator keywords subject].include?(k)
-
- @options["md_#{k}"] = v
+ (@options[:metadata] ||= {})[k] = v
end
end
# Select a partial list of pages
# @param [String] selection as described in com.itextpdf.text.pdf.SequenceList: [!][o][odd][e][even]start-end
def range(selection)
- @options[:ranges] = selection
+ @options[:select] = {range: [selection].flatten.compact.join(',')}
end
# Create or use a watermark image.
#
# The watermark options are (use symbols):
# - text: text to create a watermark from
# - file: watermark image to use
+ # - image: same as above
# - rotation: rotation of the watermark text (in degrees; integer number)
# - size: font size of the watermark text
# - opacity: opacity of the watermark (fraction 0.0 - 1.0)
# - gap: size of the gap between watermark instances. Integer value is absolute size in points (1/72 inch).
# Fractions are percentage of widht/height.
@@ -68,109 +68,196 @@
# slanted by 30 degrees counter-clockwise.
#
# @param [Hash] options Hash of options for watermark creation.
def watermark(options = {})
options.key_strings_to_symbols!
- if options[:file] && File.exist?(options[:file])
- @options['wm_image'] = options[:file]
- else
- @options['wm_text'] = (options[:text] || '© LIBIS').split('\n')
- @options['wm_text_rotation'] = options[:rotation] if options[:rotation]
- @options['wm_font_size'] = options[:size] if options[:size]
+ if options[:file] || options[:image]
+ watermark_image(options)
+ elsif options[:text]
+ watermark_text(options)
+ elsif options[:banner]
+ watermark_banner(options)
end
- @options['wm_opacity'] = options[:opacity] || '0.3'
- @options['wm_gap_ratio'] = options[:gap] if options[:gap].to_s =~ /^\s*(0+\.\d+|1\.0+)\s*$/
- @options['wm_gap_size'] = options[:gap] if options[:gap].to_s =~ /^\s*\d+\s*$/
end
+ def watermark_image(options = {})
+ options.key_strings_to_symbols!
+ @options[:watermark] = {command: 'image'}
+ @options[:watermark][:data] = options[:file] || options[:image]
+ @options[:watermark][:opacity] = options[:opacity] || '0.3'
+
+ end
+
+ def watermark_text(options = {})
+ options.key_strings_to_symbols!
+ @options[:watermark] = {command: 'text'}
+ @options[:watermark][:data] = (options[:text] || '© LIBIS').split('\n')
+ @options[:watermark][:rotation] = options[:rotation] if options[:rotation]
+ @options[:watermark][:size] = options[:size] if options[:size]
+ @options[:watermark][:gap] = options[:gap] if options[:gap].to_s =~ /^\s*\d+\s*$/
+ @options[:watermark][:padding] = options[:gap] if options[:gap].to_s =~ /^\s*(0+\.\d+|1\.0+)\s*$/
+ @options[:watermark][:padding] = options[:padding] if options[:padding]
+ @options[:watermark][:opacity] = options[:opacity] || '0.3'
+ end
+
+ # Create a vertical banner to the right side of each page
+ #
+ # The banner options are:
+ # - banner: text to put in the banner
+ # - add_filename: append filename to the text (use any value to enable)
+ # - fontsize: size of the font (in points)
+ # - width: width of the banner
+ # - (background|text)_color_(red|green|blue): color components of background and text
+ def watermark_banner(options = {})
+ options.key_strings_to_symbols!
+ @options[:watermark] = {command: 'banner'}
+ @options[:watermark][:data] = (options[:banner] || '© LIBIS')
+ @options[:watermark][:add_filename] = !!options[:add_filename]
+ @options[:watermark][:size] = options[:fontsize] if options[:fontsize]
+ @options[:watermark][:width] = options[:width] if options[:width]
+ @options[:watermark][:background_red] = options[:background_color_red] if options[:background_color_red]
+ @options[:watermark][:background_green] = options[:background_color_green] if options[:background_color_green]
+ @options[:watermark][:background_blue] = options[:background_color_blue] if options[:background_color_blue]
+ @options[:watermark][:text_red] = options[:text_color_red] if options[:text_color_red]
+ @options[:watermark][:text_green] = options[:text_color_green] if options[:text_color_green]
+ @options[:watermark][:text_blue] = options[:text_color_blue] if options[:text_color_blue]
+ end
+
# Optimize the PDF
#
# This reduces the graphics quality to a level in order to limit file size. This option relies on the
# presence of ghostscript and takes one argument: the quality level. It should be one of:
#
# - 0 : lowest quality (Acrobat Distiller 'Screen Optimized' equivalent)
# - 1 : medium quality (Acrobat Distiller 'eBook' equivalent)
- # - 2 : good quality
+ # - 2 : good quality (Acrobat Distiller 'Default' equivalent)
# - 3 : high quality (Acrobat Distiller 'Print Optimized' equivalent)
# - 4 : highest quality (Acrobat Distiller 'Prepress Optimized' equivalent)
#
# Note that the optimization is intended to be used with PDF's containing high-resolution images.
#
# @param [Integer] setting quality setting. [0-4]
def optimize(setting = 1)
- @options['optimize'] = %w[screen ebook default printer prepress][setting] if (0..4).include?(setting)
+ @options[:optimize] = %w[screen ebook default printer prepress][setting] if (0..4).include?(setting)
end
def convert(source, target, format, opts = {})
super
result = nil
- if (quality = @options.delete('optimize'))
- result = optimize_pdf(source, target, quality)
- return nil unless result
-
+ unless @options.empty?
+ result = convert_pdf(source, target)
source = result
end
- unless @options.empty?
- result = convert_pdf(source, target)
- return nil unless result
-
+ if source && (quality = @options.delete(:optimize))
+ result = optimize_pdf(source, target, quality)
source = result
end
- result = pdf_to_pdfa(source, target) if (format == :PDFA) && source
+ if source && (format == :PDFA)
+ result = pdf_to_pdfa(source, target)
+ end
{
files: [result],
converter: self.class.name
}
end
+ protected
+
def optimize_pdf(source, target, quality)
using_temp(target) do |tmpname|
result = Libis::Format::Tool::PdfOptimizer.run(source, tmpname, quality)
- unless (result[:status]).zero?
+ unless result[:err].empty?
error("Pdf optimization encountered errors:\n%s", (result[:err] + result[:out]).join("\n"))
- next nil
+ return nil
end
tmpname
end
end
def convert_pdf(source, target)
+ result = source
+ result = add_watermark(result, target, @options[:watermark]) if @options[:watermark]
+ result = add_metadata(result, target, @options[:metadata]) if @options[:metadata]
+ result = select_range(result, target, @options[:select]) if @options[:select]
+ return result
+ end
+
+ def options_to_args(options)
+ options.map do |k, v|
+ key = "--#{k.to_s.tr_s('_', '-')}"
+ value = v
+ case value
+ when TrueClass
+ value = nil
+ when FalseClass
+ value = key = nil
+ when Array
+ value = value.map(&:to_s)
+ else
+ value = v.to_s
+ end
+ [key, value]
+ end.flatten.compact
+ end
+
+ def add_watermark(source, target, options)
+ command = options.delete(:command)
+ data = [options.delete(:data)].flatten.compact
+ args = data + options_to_args(options)
+
using_temp(target) do |tmpname|
- result = Libis::Format::Tool::PdfCopy.run(
- source, tmpname,
- @options.map do |k, v|
- if v.nil?
- nil
- else
- ["--#{k}", (v.is_a?(Array) ? v : v.to_s)]
- end
- end.flatten
- )
+ result = Libis::Format::Tool::PdfTool.run(['watermark', command], source, tmpname, *args)
unless result[:err].empty?
- error("Pdf conversion encountered errors:\n%s", result[:err].join(join("\n")))
- next nil
+ error("Pdf watermarking encountered errors:\n%s", result[:err].join(join("\n")))
+ return nil
end
tmpname
end
end
+ def add_metadata(source, target, options)
+ args = options_to_args(options)
+
+ using_temp(target) do |tmpname|
+ result = Libis::Format::Tool::PdfTool.run('metadata', source, tmpname, *args)
+ unless result[:err].empty?
+ error("Pdf metadata encountered errors:\n%s", result[:err].join(join("\n")))
+ return nil
+ end
+ tmpname
+ end
+ end
+
+ def select_range(source, target, options)
+ args = options_to_args(options)
+
+ using_temp(target) do |tmpname|
+ result = Libis::Format::Tool::PdfTool.run('select', source, tmpname, *args)
+ unless result[:err].empty?
+ error("Pdf select encountered errors:\n%s", result[:err].join(join("\n")))
+ return nil
+ end
+ tmpname
+ end
+ end
+
def pdf_to_pdfa(source, target)
using_temp(target) do |tmpname|
result = Libis::Format::Tool::PdfToPdfa.run source, tmpname
- if result[:command][:status] != 0
- error("Pdf/A conversion encountered errors:\n%s", (result[:command][:out] + result[:command][:err]).join("\n"))
- next nil
+ unless result[:status].zero?
+ error("Pdf/A conversion encountered errors:\n%s", (result[:out] + result[:err]).join("\n"))
+ return nil
else
r = Libis::Format::Tool::PdfaValidator.run tmpname
if r[:status] != 0
error "Pdf/A file failed to validate with following errors:\n%s", (r[:err] || r[:out] || []).join("\n")
- next nil
+ return nil
end
end
tmpname
end
end