class HexaPDF::Document::Files

specifications that are indirect file specification dictionaries with the /Type key set.
specification is only a string. Therefore this module can only handle those file
Note that for a given PDF file not all file specifications may be found, e.g. when a file
This class provides methods for managing file specifications of a PDF file.

def add(file_or_io, name: nil, description: nil, mime_type: nil, embed: true)

See: HexaPDF::Type::FileSpecification

only a reference to it is stored.
When a filename is given and this option is +true+, then the file is embedded. Otherwise

When an IO object is given, it is always embedded and this option is ignored.
embed::

The MIME type that should be set for embedded files (so only used if +embed+ is +true+).
mime_type::

A description of the file.
description::

is not specified.
When a filename is given, the basename of the file is used by default for +name+ if it

the file in the EmbeddedFiles name tree.
The name that should be used for the file path. This name is also used for registering
name::

Options:

object.
Adds the file or IO to the PDF document and returns the corresponding file specification

files.add(io, name:, description: nil) -> file_spec
files.add(filename, name: nil, description: nil, embed: true) -> file_spec
:call-seq:
def add(file_or_io, name: nil, description: nil, mime_type: nil, embed: true)
  name ||= File.basename(file_or_io) if file_or_io.kind_of?(String)
  if name.nil?
    raise ArgumentError, "The name argument is mandatory when given an IO object"
  end
  spec = @document.add({Type: :Filespec})
  spec.path = name
  spec[:Desc] = description if description
  if embed || !file_or_io.kind_of?(String)
    spec.embed(file_or_io, name: name, mime_type: mime_type, register: true)
  end
  spec
end

def each(search: false)

be much slower.
+true+, then all indirect objects are searched for file specification dictionaries which can
EmbeddedFiles name tree and in the page annotations, are returned. If the +search+ option is
By default, only the file specifications in their standard locations, i.e. in the

Iterates over indirect file specification dictionaries of the PDF.

files.each(search: false) -> Enumerator
files.each(search: false) {|file_spec| block } -> files
:call-seq:
def each(search: false)
  return to_enum(__method__, search: search) unless block_given?
  if search
    @document.each do |obj|
      yield(obj) if obj.type == :Filespec
    end
  else
    seen = {}
    tree = @document.catalog[:Names] && @document.catalog[:Names][:EmbeddedFiles]
    tree&.each_entry do |_, spec|
      seen[spec] = true
      yield(spec)
    end
    @document.pages.each do |page|
      page.each_annotation do |annot|
        next unless annot[:Subtype] == :FileAttachment
        spec = annot[:FS]
        yield(spec) unless seen.key?(spec)
        seen[spec] = true
      end
    end
  end
  self
end

def initialize(document)

Creates a new Files object for the given PDF document.
def initialize(document)
  @document = document
end