Class: EPUB::Publication::Package::Manifest::Item

Inherits:
Object
  • Object
show all
Includes:
Inspector
Defined in:
lib/epub/publication/package/manifest.rb

Constant Summary collapse

DUMMY_ROOT_IRI =
Addressable::URI.parse('http://example.net/').freeze

Constants included from Inspector

Inspector::INSTANCE_VARIABLES_OPTION, Inspector::SIMPLE_TEMPLATE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Inspector

#inspect_instance_variables, #inspect_object_id, #inspect_simply

Constructor Details

#initializeItem

Returns a new instance of Item.



102
103
104
105
# File 'lib/epub/publication/package/manifest.rb', line 102

def initialize
  @properties = Set.new
  @full_path = nil
end

Instance Attribute Details

#fallbackItem

Returns the value of attribute fallback

Returns:

  • (Item)

    Returns the value of attribute fallback



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

#hrefAddressable::URI

Returns the value of href, which is relative IRI from rootfile(OPF file)

Returns:

  • (Addressable::URI)

    Returns the value of href, which is relative IRI from rootfile(OPF file)



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

#idString

Returns the value of id

Returns:

  • (String)

    Returns the value of id



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

#manifestManifest

Returns the value of manifest

Returns:

  • (Manifest)

    Returns the value of manifest



98
99
100
# File 'lib/epub/publication/package/manifest.rb', line 98

def manifest
  @manifest
end

#media_overlayString

Returns the value of media_overlay

Returns:

  • (String)

    Returns the value of media_overlay



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

#media_typeString

Returns the value of media_type

Returns:

  • (String)

    Returns the value of media_type



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

#propertiesSet<String>

Returns the value of properties

Returns:

  • (Set<String>)

    Returns the value of properties



98
99
# File 'lib/epub/publication/package/manifest.rb', line 98

attr_accessor :manifest,
:id, :media_type, :fallback, :media_overlay

Instance Method Details

#content_documentObject



202
203
204
205
# File 'lib/epub/publication/package/manifest.rb', line 202

def content_document
  return nil unless %w[application/xhtml+xml image/svg+xml].include? media_type
  @content_document ||= Parser::ContentDocument.new(self).parse
end

#cover_image?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/epub/publication/package/manifest.rb', line 180

def cover_image?
  properties.include? 'cover-image'
end

#entry_nameString

full path in archive

Returns:

  • (String)


133
134
135
# File 'lib/epub/publication/package/manifest.rb', line 133

def entry_name
  Addressable::URI.unencode(full_path)
end

#fallback_chainObject

TODO:

Handle circular fallback chain



116
117
118
# File 'lib/epub/publication/package/manifest.rb', line 116

def fallback_chain
  @fallback_chain ||= traverse_fallback_chain([])
end

#find_item_by_relative_iri(iri) ⇒ Item?

Note:

Algorithm stolen form Rack::Utils#clean_path_info

Parameters:

  • iri (Addressable::URI)

    relative iri

Returns:

  • (Item)
  • (nil)

    when item not found

Raises:

  • ArgumentError when iri is not relative

  • ArgumentError when iri starts with “/”(slash)



219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/epub/publication/package/manifest.rb', line 219

def find_item_by_relative_iri(iri)
  raise ArgumentError, "Not relative: #{iri.inspect}" unless iri.relative?
  raise ArgumentError, "Start with slash: #{iri.inspect}" if iri.path.start_with? Addressable::URI::SLASH
  target_href = href + iri
  segments = target_href.to_s.split(Addressable::URI::SLASH)
  clean_segments = []
  segments.each do |segment|
    next if segment.empty? || segment == '.'
    segment == '..' ? clean_segments.pop : clean_segments << segment
  end
  target_iri = Addressable::URI.parse(clean_segments.join(Addressable::URI::SLASH))
  target_iri.fragment = nil
  manifest.items.find { |item| item.href == target_iri}
end

#full_pathAddressable::URI

full path in archive

Returns:

  • (Addressable::URI)


122
123
124
125
126
127
128
129
# File 'lib/epub/publication/package/manifest.rb', line 122

def full_path
  return @full_path if @full_path
  path = DUMMY_ROOT_IRI + manifest.package.full_path + href
  path.scheme = nil
  path.host = nil
  path.path = path.path[1..-1]
  @full_path = path
end

#inspectObject



234
235
236
237
238
239
240
241
# File 'lib/epub/publication/package/manifest.rb', line 234

def inspect
  "#<%{class}:%{object_id} %{manifest} %{attributes}>" % {
    :class      => self.class,
    :object_id  => inspect_object_id,
    :manifest   => "@manifest=#{@manifest.inspect_simply}",
    :attributes => inspect_instance_variables(exclude: [:@manifest])
  }
end

#itemrefPackage::Spine::Itemref

Returns:



209
210
211
# File 'lib/epub/publication/package/manifest.rb', line 209

def itemref
  manifest.package.spine.itemrefs.find {|itemref| itemref.idref == id}
end

Returns:

  • (Boolean)


176
177
178
# File 'lib/epub/publication/package/manifest.rb', line 176

def nav?
  properties.include? 'nav'
end

#read(detect_encoding: true) ⇒ String

Read content from EPUB archive

Parameters:

  • detect_encoding (Boolean) (defaults to: true)

    Whether #read tries auto-detection of character encoding. The default value will become false in the near future.

Returns:

  • (String)

    Content with encoding: US-ASCII when the content is not in text format such images. UTF-8 when the content is in text format and detect_encoding is false. auto-detected encoding when the content is in text format and detect_encoding is true.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/epub/publication/package/manifest.rb', line 144

def read(detect_encoding: true)
  warn "[#{self.class}##{__method__}]Autodetection of character encoding is deprecated. Pass keyword argument detect_encoding with true explicitly." if detect_encoding

  raw_content = manifest.package.book.container_adapter.read(manifest.package.book.epub_file, entry_name)

  unless media_type.start_with?('text/') or
      media_type.end_with?('xml') or
      ['application/json', 'application/javascript', 'application/ecmascript', 'application/xml-dtd'].include?(media_type)
    return raw_content
  end
  if detect_encoding
    # CharDet.detect doesn't raise Encoding::CompatibilityError
    # that is caused when trying compare CharDet's internal
    # ASCII-8BIT RegExp with a String with other encoding
    # because Zip::File#read returns a String with encoding ASCII-8BIT.
    # So, no need to rescue the error here.
    encoding = CharDet.detect(raw_content)['encoding']
    if encoding
      raw_content.force_encoding(encoding)
    else
      warn "No encoding detected for #{entry_name}. Set to ASCII-8BIT" if $DEBUG || $VERBOSE
      raw_content
    end
  else
    raw_content.force_encoding("UTF-8");
  end
end

#use_fallback_chain(options = {}) ⇒ Object

TODO:

Handle circular fallback chain



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/epub/publication/package/manifest.rb', line 185

def use_fallback_chain(options = {})
  supported = EPUB::MediaType::CORE
  if ad = options[:supported]
    supported = supported | (ad.respond_to?(:to_ary) ? ad : [ad])
  end
  if del = options[:unsupported]
    supported = supported - (del.respond_to?(:to_ary) ? del : [del])
  end

  return yield self if supported.include? media_type
  if (bindings = manifest.package.bindings) && (binding_media_type = bindings[media_type])
    return yield binding_media_type.handler
  end
  return fallback.use_fallback_chain(options) {|fb| yield fb} if fallback
  raise EPUB::MediaType::UnsupportedMediaType
end

#xhtml?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/epub/publication/package/manifest.rb', line 172

def xhtml?
  media_type == 'application/xhtml+xml'
end