Class: EPUB::Parser::Publication

Inherits:
Object
  • Object
show all
Includes:
Metadata
Defined in:
lib/epub/parser/publication.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Metadata

#build_model, #build_unsupported_model

Constructor Details

#initialize(opf) ⇒ Publication

Returns a new instance of Publication.

[View source]

20
21
22
# File 'lib/epub/parser/publication.rb', line 20

def initialize(opf)
  @doc = XMLDocument.new(opf)
end

Class Method Details

.parse(container, file) ⇒ Object

[View source]

13
14
15
16
17
# File 'lib/epub/parser/publication.rb', line 13

def parse(container, file)
  opf = container.read(Addressable::URI.unencode(file))

  new(opf).parse
end

Instance Method Details

#parseObject

[View source]

24
25
26
27
28
29
30
31
32
# File 'lib/epub/parser/publication.rb', line 24

def parse
  package = parse_package(@doc)
  (EPUB::Publication::Package::CONTENT_MODELS - [:bindings]).each do |model|
    package.__send__ "#{model}=",  __send__("parse_#{model}", @doc)
  end
  package.bindings = parse_bindings(@doc, package.manifest)

  package
end

#parse_bindings(doc, handler_map) ⇒ Object

[View source]

110
111
112
113
114
115
116
117
118
119
120
# File 'lib/epub/parser/publication.rb', line 110

def parse_bindings(doc, handler_map)
  bindings = EPUB::Publication::Package::Bindings.new
  doc.each_element_by_xpath '/opf:package/opf:bindings/opf:mediaType', EPUB::NAMESPACES do |elem|
    media_type = EPUB::Publication::Package::Bindings::MediaType.new
    media_type.media_type = elem.attribute_with_prefix('media-type')
    media_type.handler = handler_map[elem.attribute_with_prefix('handler')]
    bindings << media_type
  end

  bindings
end

#parse_guide(doc) ⇒ Object

[View source]

96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/epub/parser/publication.rb', line 96

def parse_guide(doc)
  guide = EPUB::Publication::Package::Guide.new
  doc.each_element_by_xpath '/opf:package/opf:guide/opf:reference', EPUB::NAMESPACES do |ref|
    reference = EPUB::Publication::Package::Guide::Reference.new
    %w[type title].each do |attr|
      reference.__send__ "#{attr}=", ref.attribute_with_prefix(attr)
    end
    reference.href = ref.attribute_with_prefix('href')
    guide << reference
  end

  guide
end

#parse_manifest(doc) ⇒ Object

[View source]

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/epub/parser/publication.rb', line 50

def parse_manifest(doc)
  manifest = EPUB::Publication::Package::Manifest.new
  elem = doc.each_element_by_xpath('/opf:package/opf:manifest', EPUB::NAMESPACES).first
  manifest.id = elem.attribute_with_prefix('id')

  fallback_map = {}
  elem.each_element_by_xpath('./opf:item', EPUB::NAMESPACES).each do |e|
    item = EPUB::Publication::Package::Manifest::Item.new
    %w[id media-type media-overlay].each do |attr|
      item.__send__ "#{attr.gsub(/-/, '_')}=", e.attribute_with_prefix(attr)
    end
    item.href = e.attribute_with_prefix('href')
    fallback = e.attribute_with_prefix('fallback')
    fallback_map[fallback] = item if fallback
    properties = e.attribute_with_prefix('properties')
    item.properties = properties.split(' ') if properties
    manifest << item
  end
  fallback_map.each_pair do |id, from|
    from.fallback = manifest[id]
  end

  manifest
end

#parse_metadata(doc) ⇒ Object

[View source]

46
47
48
# File 'lib/epub/parser/publication.rb', line 46

def (doc)
  super(doc.each_element_by_xpath('/opf:package/opf:metadata', EPUB::NAMESPACES).first, doc.root.attribute_with_prefix('unique-identifier'), 'opf')
end

#parse_package(doc) ⇒ Object

[View source]

34
35
36
37
38
39
40
41
42
43
44
# File 'lib/epub/parser/publication.rb', line 34

def parse_package(doc)
  package = EPUB::Publication::Package.new
  elem = doc.root
  %w[version xml:lang dir id].each do |attr|
    package.__send__ "#{attr.gsub(/\:/, '_')}=", elem.attribute_with_prefix(attr)
  end
  package.prefix = parse_prefix(elem.attribute_with_prefix('prefix'))
  EPUB::Publication.__send__ :include, EPUB::Publication::FixedLayout if package.prefix.key? EPUB::Publication::FixedLayout::PREFIX_KEY

  package
end

#parse_prefix(str) ⇒ Object

[View source]

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/epub/parser/publication.rb', line 122

def parse_prefix(str)
  prefixes = {}
  return prefixes if str.nil? or str.empty?
  scanner = StringScanner.new(str)
  scanner.scan /\s*/
  while prefix = scanner.scan(/[^\:\s]+/)
    scanner.scan /[\:\s]+/
    iri = scanner.scan(/[^\s]+/)
    if iri.nil? or iri.empty?
      warn "no IRI detected for prefix `#{prefix}`"
    else
      prefixes[prefix] = iri
    end
    scanner.scan /\s*/
  end
  prefixes
end

#parse_spine(doc) ⇒ Object

[View source]

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/epub/parser/publication.rb', line 75

def parse_spine(doc)
  spine = EPUB::Publication::Package::Spine.new
  elem = doc.each_element_by_xpath('/opf:package/opf:spine', EPUB::NAMESPACES).first
  %w[id toc page-progression-direction].each do |attr|
    spine.__send__ "#{attr.gsub(/-/, '_')}=", elem.attribute_with_prefix(attr)
  end

  elem.each_element_by_xpath('./opf:itemref', EPUB::NAMESPACES).each do |e|
    itemref = EPUB::Publication::Package::Spine::Itemref.new
    %w[idref id].each do |attr|
      itemref.__send__ "#{attr}=", e.attribute_with_prefix(attr)
    end
    itemref.linear = (e.attribute_with_prefix('linear') != 'no')
    properties = e.attribute_with_prefix('properties')
    itemref.properties = properties.split(' ') if properties
    spine << itemref
  end

  spine
end