gepub 0.6.9.2 → 0.7.0beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6790c94431137225f634825b8bb31fa4c17bf9fa
4
- data.tar.gz: 6b8b2480b8892406e07f33a36563dc7448b20330
3
+ metadata.gz: da95a78f54f7a71d249dd06e76e9b18adacc7239
4
+ data.tar.gz: 7f50cc69320fbdb6664821690836dbdd3b2fddf5
5
5
  SHA512:
6
- metadata.gz: 3f61337779cffc792a6d186fad5df3998437ec4a5f2785db9cce502af72c58d323037b63ccc0e102b9e9fe70514080056f35afe21a797646fd3d2c9a43c0d1b4
7
- data.tar.gz: cffa739c71bbb81dddd083b03d5c2dedb4d203bd35d3f511cbdf96c1b288b70e30ab488462f38b9096a17b268d22ddb6af2f19c780cc04fa967f6899f78f960b
6
+ metadata.gz: 2de76d9b67b24bcd553a58a09efdbf9a1692831ccf44925ce06e863d0f1e1b826b5aeae5fb71545861a1bd2d6f5eab79af6a25358aee8bdac83a71de4e8bc3b7
7
+ data.tar.gz: 87688508687b17fadf099f34b8d6a83ce4d3f8c22d7bcc47052e40a1de12399e91c1ecd011091f010a922b89a6910438b73360625e3257b05481028ea8e0e574
data/.gitignore CHANGED
@@ -26,3 +26,6 @@ example_test*.epub
26
26
  Gemfile.lock
27
27
  vendor/**
28
28
  .bundle/**
29
+
30
+ # rdoc
31
+ rdoc/**
data/.travis.yml CHANGED
@@ -3,4 +3,4 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.0
6
- script: bundle exec rspec spec
6
+ script: bundle exec rake spec
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # gepub
2
- [<img src="https://secure.travis-ci.org/skoji/gepub.png" />](http://travis-ci.org/skoji/gepub) [![Coverage Status](https://coveralls.io/repos/skoji/gepub/badge.png?branch=master)](https://coveralls.io/r/skoji/gepub?branch=master)
2
+ [<img src="https://secure.travis-ci.org/skoji/gepub.png" />](http://travis-ci.org/skoji/gepub)
3
+ [![Coverage Status](https://coveralls.io/repos/skoji/gepub/badge.png?branch=master)](https://coveralls.io/r/skoji/gepub?branch=master)
4
+ [![Dependency Status](https://gemnasium.com/skoji/gepub.png)](https://gemnasium.com/skoji/gepub)
5
+ [![Gem Version](https://badge.fury.io/rb/gepub.png)](http://badge.fury.io/rb/gepub)
3
6
 
4
- * http://en.skoji.jp/category/gepub/
7
+ * http://rdoc.info/github/skoji/gepub/master/frames
5
8
 
6
9
  ## DESCRIPTION:
7
10
 
@@ -15,6 +18,7 @@ a generic EPUB parser/generator library.
15
18
 
16
19
  * See [issues](https://github.com/skoji/gepub/issues/) for known problems.
17
20
 
21
+ **GEPUB::Builder will be obsolete in gepub 0.7. GEPUB::Book#new will be enhanced instead of Builder DSL. **
18
22
 
19
23
  ## SYNOPSIS:
20
24
 
data/Rakefile CHANGED
@@ -1 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'rdoc/task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.main = "README.md"
11
+ rdoc.rdoc_dir = "rdoc"
12
+ rdoc.rdoc_files.include("README.md", "lib/**/*.rb")
13
+ end
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'gepub'
3
+
4
+ GEPUB::Book.new do |book|
5
+ book.set_unique_identifier 'http:/example.jp/bookid_in_url', 'BookID', 'URL'
6
+ book.set_title 'GEPUB Sample Book'
7
+ book.set_subtitle 'GEPUB Sample Book'
8
+ book.set_creator 'KOJIMA Satoshi'
9
+ book.set_contributors '電書部', 'アサガヤデンショ', '電子雑誌トルタル'
10
+
11
+ book.ordered {
12
+ book.add_item('name') do
13
+ |item|
14
+ item.content = StringIO.new()
15
+ end
16
+ }
17
+ end
18
+
19
+
20
+
data/gepub.gemspec CHANGED
@@ -18,7 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_development_dependency "rspec", "~> 2.14"
22
21
  s.add_runtime_dependency "nokogiri", "~> 1.6.1"
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "rspec"
23
24
  s.add_runtime_dependency "rubyzip", ">= 1.1.1"
24
25
  end
data/lib/gepub/book.rb CHANGED
@@ -72,8 +72,10 @@ module GEPUB
72
72
  # === Book#contributors_list (delegated to Metadata)
73
73
  # returns contributors list by display-seq or defined order.
74
74
  # the contributors without display-seq is appear after contributors with display-seq.
75
- # === Book#set_lastmodified(date=nil) (delegated to Metadata#set_lastmodified)
76
- # set last modified date.if date is nil, it sets current time.
75
+ # === Book#lastmodified(date) (delegated to Metadata#lastmodified)
76
+ # set last modified date.
77
+ # === Book#modified_now (delegated to Metadata#modified_now)
78
+ # set last modified date to current time.
77
79
  # === Book#lastmodified (delegated to Metadata#lastmodified)
78
80
  # returns Meta object contains last modified time.
79
81
  # === setting and reading other metadata: publisher, language, coverage, date, description, format, relation, rights, source, subject, type (delegated to Metadata)
@@ -116,14 +118,15 @@ module GEPUB
116
118
 
117
119
  # creates new empty Book object.
118
120
  # usually you do not need to specify any arguments.
119
-
120
- def initialize(path='OEBPS/package.opf', attributes = {})
121
+ def initialize(path='OEBPS/package.opf', attributes = {}, &block)
121
122
  if File.extname(path) != '.opf'
122
123
  warn 'GEPUB::Book#new interface changed. You must supply path to package.opf as first argument. If you want to set title, please use GEPUB::Book#title='
123
124
  end
124
125
  @package = Package.new(path, attributes)
125
126
  @toc = []
126
- yield book if block_given?
127
+ if block
128
+ block.arity < 1 ? instance_eval(&block) : block[self]
129
+ end
127
130
  end
128
131
 
129
132
 
@@ -142,15 +145,7 @@ module GEPUB
142
145
  (@optional_files ||= {})[path] = io.read
143
146
  end
144
147
 
145
- # add navigation text (which will appear on navigation document or table of contents) to an item.
146
- # DEPRECATED: please use Item#toc_text or Item#toc_text_with_id, or Builder#heading
147
-
148
- def add_nav(item, text, id = nil)
149
- warn 'add_nav is deprecated: please use Item#toc_text'
150
- @toc.push({ :item => item, :text => text, :id => id})
151
- end
152
-
153
- def set_sigleton_methods_to_item(item)
148
+ def set_singleton_methods_to_item(item)
154
149
  toc = @toc
155
150
  metaclass = (class << item;self;end)
156
151
  metaclass.send(:define_method, :toc_text,
@@ -176,7 +171,7 @@ module GEPUB
176
171
  # the added item will be referenced by the first argument in the EPUB container.
177
172
  def add_item(href, io_or_filename = nil, id = nil, attributes = {})
178
173
  item = @package.add_item(href,nil,id,attributes)
179
- set_sigleton_methods_to_item(item)
174
+ set_singleton_methods_to_item(item)
180
175
  item.add_content io_or_filename unless io_or_filename.nil?
181
176
  item
182
177
  end
@@ -184,7 +179,7 @@ module GEPUB
184
179
  # same as add_item, but the item will be added to spine of the EPUB.
185
180
  def add_ordered_item(href, io_or_filename = nil, id = nil, attributes = {})
186
181
  item = @package.add_ordered_item(href,io_or_filename,id,attributes)
187
- set_sigleton_methods_to_item(item)
182
+ set_singleton_methods_to_item(item)
188
183
  yield item if block_given?
189
184
  item
190
185
  end
@@ -235,7 +230,7 @@ module GEPUB
235
230
  entries.sort_by { |k,v| k }.each {
236
231
  |k,v|
237
232
  epub.put_next_entry(k)
238
- epub << v.force_to_bin
233
+ epub << v.force_encoding('us-ascii')
239
234
  }
240
235
  end
241
236
 
@@ -391,7 +386,7 @@ EOF
391
386
  end
392
387
  def cleanup_for_epub3
393
388
  if version.to_f >=3.0
394
- @package.metadata.set_lastmodified
389
+ @package.metadata.modified_now
395
390
 
396
391
  if @package.manifest.item_list.select {
397
392
  |href, item|
data/lib/gepub/builder.rb CHANGED
@@ -163,15 +163,15 @@ module GEPUB
163
163
  end
164
164
 
165
165
  def file_as(name)
166
- @item.set_file_as(name)
166
+ @item.file_as(name)
167
167
  end
168
168
 
169
169
  def seq(num)
170
- @item.set_display_seq(num)
170
+ @item.display_seq(num)
171
171
  end
172
172
 
173
173
  def group_position(num)
174
- @item.set_group_position(num)
174
+ @item.group_position(num)
175
175
  end
176
176
 
177
177
  def id(val)
@@ -182,7 +182,7 @@ module GEPUB
182
182
  def initialize(attributes = {}, &block)
183
183
  @last_defined_item = nil
184
184
  @book = Book.new
185
- instance_eval &block
185
+ instance_eval(&block)
186
186
  # TODO check @book's consistency
187
187
  true
188
188
  end
@@ -210,7 +210,7 @@ module GEPUB
210
210
 
211
211
  def collection(val, count = 1)
212
212
  @last_defined_item =
213
- MetaItem.new(@book.add_title(val, nil, GEPUB::TITLE_TYPE::COLLECTION).set_group_position(count.to_s))
213
+ MetaItem.new(@book.add_title(val, nil, GEPUB::TITLE_TYPE::COLLECTION).group_position(count.to_s))
214
214
  end
215
215
 
216
216
  def creator(val, role = 'aut')
@@ -245,7 +245,7 @@ module GEPUB
245
245
  end
246
246
 
247
247
  def unique_identifier(val, id = 'BookID', scheme = 'nil')
248
- @last_defined_item = MetaItem.new(@book.set_primary_identifier(val, id, scheme))
248
+ @last_defined_item = MetaItem.new(@book.primary_identifier(val, id, scheme))
249
249
  end
250
250
 
251
251
  def alts(alt_vals = {})
@@ -269,6 +269,11 @@ module GEPUB
269
269
  def ibooks_version(val)
270
270
  @book.ibooks_version=val
271
271
  end
272
+ # specify scroll axis for ibooks
273
+ def ibooks_scroll_axis(val)
274
+ @book.ibooks_scroll_axis = val
275
+ end
276
+
272
277
  # set optional file.
273
278
  # val should be String or Hash.
274
279
  # if val is String, file is read from the File specified by string and stored in EPUB to the path specified by string.
@@ -11,10 +11,10 @@ module GEPUB
11
11
  end
12
12
 
13
13
  def content=(date)
14
- if content.is_a? String
15
- content = Time.parse(content)
14
+ if date.is_a? String
15
+ date = Time.parse(date)
16
16
  end
17
- @content = content
17
+ @content = date
18
18
  end
19
19
 
20
20
  def to_s(locale = nil)
@@ -0,0 +1,11 @@
1
+ module GEPUB
2
+ module DSLUtil
3
+ UNASSIGNED = Object.new
4
+
5
+ private
6
+ def unassigned?(value)
7
+ return value === UNASSIGNED
8
+ end
9
+ end
10
+ end
11
+
data/lib/gepub/item.rb CHANGED
@@ -23,7 +23,7 @@ module GEPUB
23
23
  attributes['properties'] = attributes['properties'].split(' ')
24
24
  end
25
25
  @attributes = {'id' => itemid, 'href' => itemhref, 'media-type' => itemmediatype}.merge(attributes)
26
- @attributes['media-type'] = guess_mediatype if media_type.nil?
26
+ @attributes['media-type'] = GEPUB::Mime.guess_mediatype(itemhref) if media_type.nil?
27
27
  @parent = parent
28
28
  @parent.register_item(self) unless @parent.nil?
29
29
  self
@@ -125,7 +125,7 @@ module GEPUB
125
125
  # generate xml to supplied Nokogiri builder.
126
126
  def to_xml(builder, opf_version = '3.0')
127
127
  attr = @attributes.dup
128
- if opf_version.to_f < 3.0
128
+ if opf_version.to_f < 3.0
129
129
  attr.reject!{ |k,v| k == 'properties' }
130
130
  end
131
131
  if !attr['properties'].nil?
@@ -136,32 +136,5 @@ module GEPUB
136
136
  end
137
137
  builder.item(attr)
138
138
  end
139
-
140
- def guess_mediatype
141
- case File.extname(href)
142
- when /.(html|xhtml)/i
143
- 'application/xhtml+xml'
144
- when /.css/i
145
- 'text/css'
146
- when /.js/i
147
- 'text/javascript'
148
- when /.(jpg|jpeg)/i
149
- 'image/jpeg'
150
- when /.png/i
151
- 'image/png'
152
- when /.gif/i
153
- 'image/gif'
154
- when /.svg/i
155
- 'image/svg+xml'
156
- when /.opf/i
157
- 'application/oebps-package+xml'
158
- when /.ncx/i
159
- 'application/x-dtbncx+xml'
160
- when /.(otf|ttf|ttc)/i
161
- 'application/vnd.ms-opentype'
162
- when /.woff/i
163
- 'application/font-woff'
164
- end
165
- end
166
139
  end
167
- end
140
+ end
data/lib/gepub/meta.rb CHANGED
@@ -4,6 +4,7 @@ require 'nokogiri'
4
4
  module GEPUB
5
5
  # Holds one metadata with refine meta elements.
6
6
  class Meta
7
+ include DSLUtil
7
8
  attr_accessor :content
8
9
  attr_reader :name
9
10
  def initialize(name, content, parent, attributes= {}, refiners = {})
@@ -64,17 +65,30 @@ module GEPUB
64
65
  ['title-type', 'identifier-type', 'display-seq', 'file-as', 'group-position', 'role'].each {
65
66
  |name|
66
67
  methodbase = name.sub('-','_')
67
- define_method(methodbase + '=') { |val| refine(name, val); }
68
- define_method('set_' + methodbase) { |val| refine(name, val); }
69
- define_method(methodbase) { refiner(name) }
68
+ define_method(methodbase + '=') { |val| refine(name, val) }
69
+ define_method('set_' + methodbase) { |val|
70
+ warn "set_#{methodbase} is obsolete. use #{methodbase} instead."
71
+ refine(name, val)
72
+ }
73
+ define_method(methodbase, ->(value = UNASSIGNED) {
74
+ if unassigned?(value)
75
+ refiner(name)
76
+ else
77
+ refine(name,value)
78
+ end
79
+ })
70
80
  }
71
81
 
72
82
  def lang=(lang)
73
83
  @attributes['xml:lang'] = lang
74
84
  end
75
85
 
76
- def lang
77
- @attributes['xml:lang']
86
+ def lang(lang = UNASSIGNED)
87
+ if unassigned?(lang)
88
+ @attributes['xml:lang']
89
+ else
90
+ self.lang=(lang)
91
+ end
78
92
  end
79
93
 
80
94
  # add alternate script refiner.
@@ -17,7 +17,7 @@ module GEPUB
17
17
  nil
18
18
  end
19
19
  end
20
- include XMLUtil
20
+ include XMLUtil, DSLUtil
21
21
  attr_accessor :opf_version
22
22
  # parse metadata element. metadata_xml should be Nokogiri::XML::Node object.
23
23
  def self.parse(metadata_xml, opf_version = '3.0', id_pool = Package::IDPool.new)
@@ -48,6 +48,8 @@ module GEPUB
48
48
  @spread = metanode
49
49
  when 'ibooks:version'
50
50
  @ibooks_version = metanode
51
+ when 'ibooks:scroll-axis'
52
+ @ibooks_scroll_axis = metanode
51
53
  end
52
54
 
53
55
  }
@@ -70,6 +72,7 @@ module GEPUB
70
72
  @orientation = NilContent
71
73
  @spread = NilContent
72
74
  @ibooks_version = NilContent
75
+ @ibooks_scroll_axis = NilContent
73
76
  yield self if block_given?
74
77
  end
75
78
 
@@ -106,7 +109,7 @@ module GEPUB
106
109
  @oldstyle_meta = []
107
110
  end
108
111
 
109
- CONTENT_NODE_LIST = ['identifier','title', 'language', 'contributor', 'creator', 'coverage', 'date','description','format','publisher','relation','rights','source','subject','type'].each {
112
+ CONTENT_NODE_LIST = ['identifier', 'title', 'language', 'contributor', 'creator', 'coverage', 'date','description','format','publisher','relation','rights','source','subject','type'].each {
110
113
  |node|
111
114
  define_method(node + '_list') { @content_nodes[node].dup.sort_as_meta }
112
115
  define_method(node + '_clear') {
@@ -116,9 +119,14 @@ module GEPUB
116
119
  end
117
120
  }
118
121
 
119
- define_method(node) {
120
- get_first_node(node)
121
- }
122
+ define_method(node, ->(content=UNASSIGNED, id=nil) {
123
+ if unassigned?(content)
124
+ get_first_node(node)
125
+ else
126
+ send(node + "_clear")
127
+ add_metadata(node, content, id)
128
+ end
129
+ })
122
130
 
123
131
  define_method('add_' + node) {
124
132
  |content, id|
@@ -127,13 +135,15 @@ module GEPUB
127
135
 
128
136
  define_method('set_' + node) {
129
137
  |content, id|
138
+ warn "obsolete : set_#{node}. use #{node} instead."
130
139
  send(node + "_clear")
131
140
  add_metadata(node, content, id)
132
141
  }
133
142
 
134
143
  define_method(node+'=') {
135
144
  |content|
136
- send('set_' + node, content, nil)
145
+ send(node + "_clear")
146
+ add_metadata(node, content, nil)
137
147
  }
138
148
  }
139
149
 
@@ -148,15 +158,23 @@ module GEPUB
148
158
  end
149
159
  end
150
160
 
151
- def title
152
- if !@content_nodes['title'].nil?
153
- @content_nodes['title'].each do
154
- |titlenode|
155
- return titlenode if titlenode.title_type.to_s == TITLE_TYPE::MAIN
161
+ def title(content=UNASSIGNED, id = nil, title_type = nil)
162
+ if unassigned?(content)
163
+ if !@content_nodes['title'].nil?
164
+ @content_nodes['title'].each do
165
+ |titlenode|
166
+ return titlenode if titlenode.title_type.to_s == TITLE_TYPE::MAIN
167
+ end
156
168
  end
169
+ get_first_node('title')
170
+ else
171
+ title_clear
172
+ meta = add_title(content, id, title_type)
173
+ yield meta if block_given?
174
+ meta
157
175
  end
158
- get_first_node('title')
159
176
  end
177
+
160
178
 
161
179
  def get_first_node(node)
162
180
  if !@content_nodes[node].nil? && @content_nodes[node].size > 0
@@ -198,6 +216,7 @@ module GEPUB
198
216
  end
199
217
 
200
218
  def set_title(content, id = nil, title_type = nil)
219
+ warn "obsolete : set_title. use title instead."
201
220
  title_clear
202
221
  meta = add_title(content, id, title_type)
203
222
  yield meta if block_given?
@@ -222,15 +241,31 @@ module GEPUB
222
241
  meta
223
242
  end
224
243
 
225
- def lastmodified
226
- ret = (@content_nodes['meta'] ||=[]).select {
227
- |meta|
228
- meta['property'] == 'dcterms:modified'
229
- }
230
- ret.size == 0 ? nil : ret[0]
244
+ def lastmodified(date=UNASSIGNED)
245
+ if unassigned?(date)
246
+ ret = (@content_nodes['meta'] ||=[]).select {
247
+ |meta|
248
+ meta['property'] == 'dcterms:modified'
249
+ }
250
+ ret.size == 0 ? nil : ret[0]
251
+ else
252
+ date ||= Time.now
253
+ (@content_nodes['meta'] ||= []).each {
254
+ |meta|
255
+ if (meta['property'] == 'dcterms:modified')
256
+ @content_nodes['meta'].delete meta
257
+ end
258
+ }
259
+ add_metadata('meta', date.utc.strftime('%Y-%m-%dT%H:%M:%SZ'), nil, DateMeta)['property'] = 'dcterms:modified'
260
+ end
231
261
  end
232
-
262
+
263
+ def modified_now
264
+ lastmodified Time.now
265
+ end
266
+
233
267
  def set_lastmodified(date=nil)
268
+ warn "obsolete : set_lastmodified. use lastmodified instead."
234
269
  date ||= Time.now
235
270
  (@content_nodes['meta'] ||= []).each {
236
271
  |meta|
@@ -298,13 +333,25 @@ module GEPUB
298
333
  @ibooks_version = Meta.new('meta', val, self, { 'property' => 'ibooks:version' })
299
334
  (@content_nodes['meta'] ||= []) << @ibooks_version
300
335
  end
336
+
337
+ def ibooks_scroll_axis
338
+ @ibooks_scroll_axis.content || ''
339
+ end
340
+
341
+ def ibooks_scroll_axis=(val)
342
+ if ![:vertical, :horizontal, :default].member? val.to_sym
343
+ raise 'ibooks_scroll_axis should be one of vertical, horizontal or default'
344
+ end
345
+ @ibooks_scroll_axis = Meta.new('meta', val, self, { 'property' => 'ibooks:scroll-axis' })
346
+ (@content_nodes['meta'] ||= []) << @ibooks_scroll_axis
347
+ end
301
348
 
302
349
  def rendition_specified?
303
350
  @layout.content || @orientation.content || @spread.content
304
351
  end
305
352
 
306
353
  def ibooks_vocaburaly_specified?
307
- @ibooks_version.content
354
+ @ibooks_version.content || @ibooks_scroll_axis.content
308
355
  end
309
356
 
310
357
  private
data/lib/gepub/mime.rb ADDED
@@ -0,0 +1,49 @@
1
+ module GEPUB
2
+ #
3
+ # Static Object to hold and operate with OEBPS data MIME types
4
+ #
5
+
6
+ class Mime
7
+
8
+ # compile mime_types regexp
9
+ def self.compile_mime_types
10
+ @@mime_types_compiled = Hash[@@mime_types.map { |expr, mime| [ /\A\.#{expr}\Z/i, mime ] }]
11
+ end
12
+
13
+ # media types by file extension regexp seeds to mime types
14
+ @@mime_types = {
15
+ '(html|xhtml)' => 'application/xhtml+xml',
16
+ 'css' => 'text/css',
17
+ 'js' => 'text/javascript',
18
+ '(jpg|jpeg)' => 'image/jpeg',
19
+ 'png' => 'image/png',
20
+ 'gif' => 'image/gif',
21
+ 'svg' => 'image/svg+xml',
22
+ 'opf' => 'application/oebps-package+xml',
23
+ 'ncx' => 'application/x-dtbncx+xml',
24
+ '(otf|ttf|ttc|eot)' => 'application/vnd.ms-opentype',
25
+ 'woff' => 'application/font-woff',
26
+ 'mp4' => 'video/mp4',
27
+ 'mp3' => 'audio/mpeg'
28
+ }
29
+ compile_mime_types
30
+
31
+ # return mime media types => mime types hash
32
+ def self.mime_types
33
+ @@mime_types
34
+ end
35
+
36
+ # add new mediatype to @@mediatypes
37
+ def self.add_mimetype(mediatypes)
38
+ mediatypes.each { |expr, mime| @@mime_types[expr] ||= mime }
39
+ compile_mime_types
40
+ end
41
+
42
+ #guess mediatype by mime type mask
43
+ def self.guess_mediatype(href)
44
+ ext = File.extname(href)
45
+ @@mime_types_compiled.select { |pattern, mime| ext =~ pattern }.values[0]
46
+ end
47
+
48
+ end
49
+ end