Class: BbEPUB::Transform::CoverImage

Inherits:
Bookbinder::Transform
  • Object
show all
Defined in:
lib/bb-epub/transform/cover_image.rb

Overview

The best source of information about wading through the EPUB cover image quagmire has always been Keith’s article on the Threepress blog:

http://blog.safaribooksonline.com/2009/11/20/best-practices-in-epub-cover-images/

He added an update for EPUB3, which follows the spec but is a bit easier to grok:

http://blog.safaribooksonline.com/2011/05/26/covers-in-epub3/

Instance Method Summary collapse

Instance Method Details

#cover_item_from_component(package, cmpt) ⇒ Object

TODO: support SVG images too.



100
101
102
103
104
105
106
107
108
109
# File 'lib/bb-epub/transform/cover_image.rb', line 100

def cover_item_from_component(package, cmpt)
  package.if_file(cmpt['path']) { |cmpt_file|
    return  unless cmpt_doc = cmpt_file.document('r')
    return  unless img_tag = cmpt_doc.find('body img')
    opf_doc = package.file(:opf).document('r')
    opf_doc.find('opf|manifest > opf|item[href="'+img_tag['src']+'"]')
  }
rescue
  nil
end

#cover_item_from_cover_page(package) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/bb-epub/transform/cover_image.rb', line 89

def cover_item_from_cover_page(package)
  if (nav = package.map['nav']) && (landmarks = nav['landmarks'])
    if landmark = landmarks.detect { |it| it['type'] == 'cover' }
      return package.map['spine'].detect { |c| c['path'] == landmark['path'] }
    end
  end
end

#cover_item_from_manifest(package, opf_doc) ⇒ Object



73
74
75
76
77
# File 'lib/bb-epub/transform/cover_image.rb', line 73

def cover_item_from_manifest(package, opf_doc)
  opf_doc.find('opf|manifest > opf|item[properties~="cover-image"]') ||
    opf_doc.find('opf|manifest > opf|item[id="cover-image"]') ||
    opf_doc.find('opf|manifest > opf|item[id="cover_image"]')
end

#cover_item_from_metadata(package, opf_doc) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/bb-epub/transform/cover_image.rb', line 80

def (package, opf_doc)
  cover_meta_props = (package.map['metadata'] || {}).delete('cover')
  if cover_meta_props && cover_meta_props.any?
    cover_image_id = cover_meta_props.first['content']['@']
    opf_doc.find('opf|manifest > opf|item[id="'+cover_image_id+'"]')
  end
end

#cover_resource_from_item(package, cover_item) ⇒ Object



112
113
114
115
116
117
118
119
120
121
# File 'lib/bb-epub/transform/cover_image.rb', line 112

def cover_resource_from_item(package, cover_item)
  return nil  unless cover_item && cover_item['id']
  if cmpt = package.map['spine'].detect { |c| c['id'] == cover_item['id'] }
    unless cover_item = cover_item_from_component(package, cmpt)
      package.warn("Did not discover cover image in #{cmpt['path']}. SVG?")
      return nil
    end
  end
  package.map['resources'].detect { |r| r['id'] == cover_item['id'] }
end

#dependenciesObject



14
15
16
17
18
19
# File 'lib/bb-epub/transform/cover_image.rb', line 14

def dependencies
  [
    BbEPUB::Transform::Metadata,
    BbEPUB::Transform::CoverPage
  ]
end

#from_map(package) ⇒ Object

Belt and braces: give the manifest item a property of ‘cover-image’, an ‘id’ of ‘cover-image’ (updating any idrefs) and create a meta tag with ‘name’=‘cover’ and ‘content’=‘cover-image’.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bb-epub/transform/cover_image.rb', line 50

def from_map(package)
  return  unless package.map['cover'] && cover = package.map['cover']['front']
  opf_doc = package.file(:opf).document

  opf_doc.new_node('item', :append => 'opf|manifest') { |manifest_item_tag|
    manifest_item_tag['href'] = package.make_href(cover['path'])
    manifest_item_tag['media-type'] = cover['media-type']
    manifest_item_tag['id'] = 'cover-image'
    manifest_item_tag['properties'] = 'cover-image'
  }

  cover_id = package.make_id(cover['path'])
  opf_doc.each('[idref="'+cover_id+'"]') { |idref|
    idref['idref'] = cover_id
  }

  opf_doc.new_node('meta', :append => 'opf|metadata') { |cover_meta_tag|
    cover_meta_tag['name'] = 'cover'
    cover_meta_tag['content'] = 'cover-image'
  }
end

#to_map(package) ⇒ Object

If it’s EPUB3, the cover will be in the ‘properties’ attribute of the manifest item: ‘cover-image’

Otherwise, look for a manifest item with an ‘id’ of ‘cover-image’.

Or, look for a meta tag with a ‘name’ of ‘cover’, then find the manifest item that has the ‘id’ that matches meta’s ‘content’.

Set map to this item (and remove it from map).



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/bb-epub/transform/cover_image.rb', line 32

def to_map(package)
  package.map['cover'] = {}
  opf_doc = package.file(:opf).document('r')
  cover_item = cover_item_from_manifest(package, opf_doc) ||
    (package, opf_doc) ||
    cover_item_from_cover_page(package)
  if cover_resource = cover_resource_from_item(package, cover_item)
    package.map['resources'].delete(cover_resource)
    package.map['cover'].update("front" => cover_resource)
  end
end