=begin This file is part of Origami, PDF manipulation framework for Ruby Copyright (C) 2016 Guillaume Delugré. Origami is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Origami is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Origami. If not, see . =end require 'rexml/document' module Origami class PDF # # Returns true if the document has a document information dictionary. # def document_info? trailer_key? :Info end # # Returns the document information dictionary if present. # def document_info trailer_key :Info end def title; get_document_info_field(:Title) end def author; get_document_info_field(:Author) end def subject; get_document_info_field(:Subject) end def keywords; get_document_info_field(:Keywords) end def creator; get_document_info_field(:Creator) end def producer; get_document_info_field(:Producer) end def creation_date; get_document_info_field(:CreationDate) end def mod_date; get_document_info_field(:ModDate) end # # Returns true if the document has a catalog metadata stream. # def metadata? self.Catalog.Metadata.is_a?(Stream) end # # Returns a Hash of the information found in the metadata stream # def metadata metadata_stm = self.Catalog.Metadata if metadata_stm.is_a?(Stream) doc = REXML::Document.new(metadata_stm.data) info = {} doc.elements.each('*/*/rdf:Description') do |description| description.attributes.each_attribute do |attr| case attr.prefix when 'pdf','xap' info[attr.name] = attr.value end end description.elements.each('*') do |element| value = (element.elements['.//rdf:li'] || element).text info[element.name] = value.to_s end end info end end # # Modifies or creates a metadata stream. # def create_metadata(info = {}) skeleton = <<-XMP XMP xml = if self.Catalog.Metadata.is_a?(Stream) self.Catalog.Metadata.data else skeleton end doc = REXML::Document.new(xml) desc = doc.elements['*/*/rdf:Description'] info.each do |name, value| elt = REXML::Element.new "pdf:#{name}" elt.text = value desc.elements << elt end xml = ""; doc.write(xml, 4) if self.Catalog.Metadata.is_a?(Stream) self.Catalog.Metadata.data = xml else self.Catalog.Metadata = Stream.new(xml) end self.Catalog.Metadata end private def get_document_info_field(field) #:nodoc: if self.document_info? doc_info = self.document_info if doc_info.key?(field) case obj = doc_info[field].solve when String then obj.value when Stream then obj.data end end end end end # # Class representing an information Dictionary, containing title, author, date of creation and the like. # class Metadata < Dictionary include StandardObject field :Title, :Type => String, :Version => "1.1" field :Author, :Type => String field :Subject, :Type => String, :Version => "1.1" field :Keywords, :Type => String, :Version => "1.1" field :Creator, :Type => String field :Producer, :Type => String field :CreationDate, :Type => String field :ModDate, :Type => String, :Version => "1.1" field :Trapped, :Type => Name, :Default => :Unknown, :Version => "1.3" end # # Class representing a metadata Stream. # This stream can contain the same information as the Metadata dictionary, but is storing in XML data. # class MetadataStream < Stream include StandardObject field :Type, :Type => Name, :Default => :Metadata, :Required => true field :Subtype, :Type => Name, :Default =>:XML, :Required => true end end