Class: EPUB::Parser::Publication

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Metadata

#build_model, #build_unsupported_model

Methods included from Utils

extract_attribute

Constructor Details

#initialize(opf) ⇒ Publication

Returns a new instance of Publication.



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

def initialize(opf)
  @doc = Nokogiri.XML(opf)
end

Class Method Details

.parse(container, file) ⇒ Object



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

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

  new(opf).parse
end

Instance Method Details

#parseObject



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

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



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

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

  bindings
end

#parse_guide(doc) ⇒ Object



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

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

  guide
end

#parse_manifest(doc) ⇒ Object



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

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

  fallback_map = {}
  elem.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(/-/, '_')}=", extract_attribute(e, attr)
    end
    item.href = extract_attribute(e, 'href')
    fallback = extract_attribute(e, 'fallback')
    fallback_map[fallback] = item if fallback
    properties = extract_attribute(e, '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



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

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

#parse_package(doc) ⇒ Object



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

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(/\:/, '_')}=", extract_attribute(elem, attr)
  end
  package.prefix = parse_prefix(extract_attribute(elem, 'prefix'))
  EPUB::Publication.__send__ :include, EPUB::Publication::FixedLayout if package.prefix.key? EPUB::Publication::FixedLayout::PREFIX_KEY

  package
end

#parse_prefix(str) ⇒ Object



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

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



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

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

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

  spine
end