Class: HexaPDF::Dictionary
- Includes:
- DictionaryFields
- Defined in:
- lib/hexapdf/dictionary.rb
Overview
Implementation of the PDF dictionary type.
Subclasses should use the available class method ::define_field to create fields according to the PDF specification. This allows, among other things, automatic type checking and basic validation.
Fields defined in superclasses are inherited by their subclasses. This avoids duplicating basic field information.
See: PDF1.7 s7.3.7
Direct Known Subclasses
Encryption::EncryptionDictionary, NameTreeNode, NumberTreeNode, Stream, Type::Catalog, Type::EmbeddedFile::MacInfo, Type::EmbeddedFile::Parameters, Type::FileSpecification, Type::FileSpecification::EFDictionary, Type::Font, Type::FontDescriptor, Type::GraphicsStateParameter, Type::Info, Type::Names, Type::Page, Type::PageTreeNode, Type::Resources, Type::Trailer, Type::ViewerPreferences
Constant Summary
Constants included from DictionaryFields
HexaPDF::DictionaryFields::Boolean, HexaPDF::DictionaryFields::PDFByteString, HexaPDF::DictionaryFields::PDFDate
Constants inherited from Object
Object::NOT_DUPLICATABLE_CLASSES
Instance Attribute Summary
Attributes inherited from Object
#data, #document, #must_be_indirect
Class Method Summary collapse
-
.define_field(name, type:, required: false, default: nil, indirect: nil, version: '1.2') ⇒ Object
Defines an entry for the field
name
and returns the initalized HexaPDF::DictionaryFields::Field object. -
.each_field(&block) ⇒ Object
:call-seq: class.each_field {|name, data| block } -> class class.each_field -> Enumerator.
-
.field(name) ⇒ Object
Returns the field entry for the given field name.
Instance Method Summary collapse
-
#[](name) ⇒ Object
Returns the value for the given dictionary entry.
-
#[]=(name, data) ⇒ Object
Stores the data under name in the dictionary.
-
#delete(name) ⇒ Object
Deletes the name-value pair from the dictionary and returns the value.
-
#each ⇒ Object
:call-seq: dict.each {|name, value| block} -> dict dict.each -> Enumerator.
-
#empty? ⇒ Boolean
Returns
true
if the dictionary contains no entries. -
#key?(key) ⇒ Boolean
Returns
true
if the given key is present in the dictionary. -
#to_hash ⇒ Object
(also: #to_h)
Returns a dup of the underlying hash.
-
#type ⇒ Object
Returns the value of the /Type field or, if not set, the result of Object#type.
Methods inherited from Object
#<=>, #==, deep_copy, #deep_copy, #document?, #eql?, #gen, #gen=, #hash, #indirect?, #initialize, #inspect, #must_be_indirect?, #null?, #oid, #oid=, #validate, #value, #value=
Constructor Details
This class inherits a constructor from HexaPDF::Object
Class Method Details
.define_field(name, type:, required: false, default: nil, indirect: nil, version: '1.2') ⇒ Object
Defines an entry for the field name
and returns the initalized HexaPDF::DictionaryFields::Field object. A suitable converter module (see HexaPDF::DictionaryFields::Field#converter) is selected based on the type argument.
Options:
- type
-
The class (or an array of classes) that a value of this field must have. Here is a mapping from PDF object types to classes:
- Boolean
-
[TrueClass, FalseClass] (or use the Boolean constant)
- Integer
-
Integer
- Real
-
Float
- String
-
String (for text strings), PDFByteString (for binary strings)
- Date
-
PDFDate
- Name
-
Symbol
- Array
-
Array
- Dictionary
-
Dictionary (or any subclass) or Hash
- Stream
-
Stream (or any subclass)
- Null
-
NilClass
If an array of classes is provided, the value can be an instance of any of these classes.
If a Symbol object instead of a class is provided, the class is looked up using the ‘object.type_map’ global configuration option when necessary to support lazy loading.
- required
-
Specifies whether this field is required.
- default
-
Specifies the default value for the field, if any.
- indirect
-
Specifies whether the value (or the values in the array value) of this field has to be an indirect object (
true
), a direct object (false
) or if it doesn’t matter (unspecified ornil
). - version
-
Specifies the minimum version of the PDF specification needed for this value.
90 91 92 93 94 |
# File 'lib/hexapdf/dictionary.rb', line 90 def self.define_field(name, type:, required: false, default: nil, indirect: nil, version: '1.2') @fields ||= {} @fields[name] = Field.new(type, required, default, indirect, version) end |
.each_field(&block) ⇒ Object
:call-seq:
class.each_field {|name, data| block } -> class
class.each_field -> Enumerator
Calls the block once for each field defined either in this class or in one of the ancestor classes.
114 115 116 117 118 |
# File 'lib/hexapdf/dictionary.rb', line 114 def self.each_field(&block) # :yields: name, data return to_enum(__method__) unless block_given? superclass.each_field(&block) if self != Dictionary && superclass != Dictionary @fields.each(&block) if defined?(@fields) end |
.field(name) ⇒ Object
Returns the field entry for the given field name.
The ancestor classes are also searched for such a field entry if none is found for the current class.
100 101 102 103 104 105 106 |
# File 'lib/hexapdf/dictionary.rb', line 100 def self.field(name) if defined?(@fields) && @fields.key?(name) @fields[name] elsif superclass.respond_to?(:field) superclass.field(name) end end |
Instance Method Details
#[](name) ⇒ Object
Returns the value for the given dictionary entry.
This method should be used instead of direct access to the value because it provides numerous advantages:
-
References are automatically resolved.
-
Returns the native Ruby object for values with class HexaPDF::Object. However, all subclasses of HexaPDF::Object are returned as is (it makes no sense, for example, to return the hash that describes the Catalog instead of the Catalog object).
-
Automatically wraps hash values in specific subclasses of this class if field information is available (see ::define_field).
-
Returns the default value if one is specified and no value is available.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/hexapdf/dictionary.rb', line 136 def [](name) field = self.class.field(name) data = if key?(name) value[name] elsif field && field.default? value[name] = field.default end value[name] = data = document.deref(data) if data.kind_of?(HexaPDF::Reference) if data.class == HexaPDF::Object || (data.kind_of?(HexaPDF::Object) && data.value.nil?) data = data.value end self[name] = data = field.convert(data, document) if field && field.convert?(data) data end |
#[]=(name, data) ⇒ Object
Stores the data under name in the dictionary. Name has to be a Symbol object.
If the current value for this name has the class HexaPDF::Object (and only this, no subclasses) and the given value has not (including subclasses), the value is stored inside the HexaPDF::Object.
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/hexapdf/dictionary.rb', line 156 def []=(name, data) unless name.kind_of?(Symbol) raise ArgumentError, "Only Symbol (Name) keys are allowed to be used in PDF dictionaries" end if value[name].class == HexaPDF::Object && !data.kind_of?(HexaPDF::Object) && !data.kind_of?(HexaPDF::Reference) value[name].value = data else value[name] = data end end |
#delete(name) ⇒ Object
Deletes the name-value pair from the dictionary and returns the value. If such a pair does not exist, nil
is returned.
176 177 178 |
# File 'lib/hexapdf/dictionary.rb', line 176 def delete(name) value.delete(name) { nil } end |
#each ⇒ Object
:call-seq:
dict.each {|name, value| block} -> dict
dict.each -> Enumerator
Calls the given block once for every name-value entry that is stored in the dictionary.
Note that the yielded value is already preprocessed like in #[].
187 188 189 190 191 |
# File 'lib/hexapdf/dictionary.rb', line 187 def each return to_enum(__method__) unless block_given? value.each_key {|name| yield(name, self[name])} self end |
#empty? ⇒ Boolean
Returns true
if the dictionary contains no entries.
199 200 201 |
# File 'lib/hexapdf/dictionary.rb', line 199 def empty? value.empty? end |
#key?(key) ⇒ Boolean
Returns true
if the given key is present in the dictionary.
170 171 172 |
# File 'lib/hexapdf/dictionary.rb', line 170 def key?(key) value.key?(key) end |
#to_hash ⇒ Object Also known as: to_h
Returns a dup of the underlying hash.
204 205 206 |
# File 'lib/hexapdf/dictionary.rb', line 204 def to_hash value.dup end |
#type ⇒ Object
Returns the value of the /Type field or, if not set, the result of Object#type.
194 195 196 |
# File 'lib/hexapdf/dictionary.rb', line 194 def type self[:Type] || super end |