epuber 0.7.4 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -2
  3. data/LICENSE.txt +1 -1
  4. data/README.md +4 -3
  5. data/epuber.gemspec +11 -16
  6. data/lib/epuber/book/contributor.rb +10 -7
  7. data/lib/epuber/book/file_request.rb +3 -3
  8. data/lib/epuber/book/target.rb +30 -33
  9. data/lib/epuber/book/toc_item.rb +2 -4
  10. data/lib/epuber/book.rb +21 -21
  11. data/lib/epuber/checker/bookspec_checker.rb +26 -0
  12. data/lib/epuber/checker/text_checker.rb +16 -7
  13. data/lib/epuber/checker.rb +16 -2
  14. data/lib/epuber/checker_transformer_base.rb +3 -6
  15. data/lib/epuber/command/build.rb +40 -25
  16. data/lib/epuber/command/from_file.rb +39 -0
  17. data/lib/epuber/command/init.rb +34 -32
  18. data/lib/epuber/command/server.rb +3 -3
  19. data/lib/epuber/command.rb +18 -20
  20. data/lib/epuber/compiler/compilation_context.rb +10 -8
  21. data/lib/epuber/compiler/file_database.rb +2 -4
  22. data/lib/epuber/compiler/file_finders/abstract.rb +36 -26
  23. data/lib/epuber/compiler/file_finders/imaginary.rb +40 -35
  24. data/lib/epuber/compiler/file_resolver.rb +79 -89
  25. data/lib/epuber/compiler/file_stat.rb +4 -4
  26. data/lib/epuber/compiler/file_types/abstract_file.rb +4 -7
  27. data/lib/epuber/compiler/file_types/bade_file.rb +20 -15
  28. data/lib/epuber/compiler/file_types/coffee_script_file.rb +1 -1
  29. data/lib/epuber/compiler/file_types/css_file.rb +103 -0
  30. data/lib/epuber/compiler/file_types/generated_file.rb +1 -1
  31. data/lib/epuber/compiler/file_types/image_file.rb +4 -2
  32. data/lib/epuber/compiler/file_types/nav_file.rb +0 -1
  33. data/lib/epuber/compiler/file_types/opf_file.rb +0 -1
  34. data/lib/epuber/compiler/file_types/source_file.rb +8 -3
  35. data/lib/epuber/compiler/file_types/stylus_file.rb +4 -3
  36. data/lib/epuber/compiler/file_types/xhtml_file.rb +67 -13
  37. data/lib/epuber/compiler/generator.rb +1 -2
  38. data/lib/epuber/compiler/meta_inf_generator.rb +1 -1
  39. data/lib/epuber/compiler/nav_generator.rb +10 -11
  40. data/lib/epuber/compiler/opf_generator.rb +26 -27
  41. data/lib/epuber/compiler/problem.rb +12 -21
  42. data/lib/epuber/compiler/xhtml_processor.rb +63 -32
  43. data/lib/epuber/compiler.rb +77 -25
  44. data/lib/epuber/config.rb +16 -10
  45. data/lib/epuber/dsl/attribute.rb +17 -18
  46. data/lib/epuber/dsl/attribute_support.rb +7 -7
  47. data/lib/epuber/dsl/object.rb +19 -17
  48. data/lib/epuber/dsl/tree_object.rb +2 -3
  49. data/lib/epuber/epubcheck.rb +15 -0
  50. data/lib/epuber/from_file/bookspec_generator.rb +371 -0
  51. data/lib/epuber/from_file/encryption_handler.rb +146 -0
  52. data/lib/epuber/from_file/from_file_executor.rb +140 -0
  53. data/lib/epuber/from_file/nav_file.rb +163 -0
  54. data/lib/epuber/from_file/opf_file.rb +219 -0
  55. data/lib/epuber/helper.rb +0 -1
  56. data/lib/epuber/lockfile.rb +7 -9
  57. data/lib/epuber/plugin.rb +2 -3
  58. data/lib/epuber/ruby_extensions/match_data.rb +1 -1
  59. data/lib/epuber/ruby_extensions/thread.rb +1 -0
  60. data/lib/epuber/server/base.styl +0 -1
  61. data/lib/epuber/server/basic.styl +1 -30
  62. data/lib/epuber/server/handlers.rb +1 -1
  63. data/lib/epuber/server.rb +81 -80
  64. data/lib/epuber/third_party/bower.rb +5 -5
  65. data/lib/epuber/transformer/book_transformer.rb +108 -0
  66. data/lib/epuber/transformer/text_transformer.rb +4 -2
  67. data/lib/epuber/transformer.rb +4 -2
  68. data/lib/epuber/user_interface.rb +49 -38
  69. data/lib/epuber/vendor/hash_binding.rb +9 -2
  70. data/lib/epuber/vendor/ruby_templater.rb +4 -8
  71. data/lib/epuber/vendor/version.rb +12 -12
  72. data/lib/epuber/version.rb +1 -1
  73. metadata +79 -100
  74. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Bold.ttf +0 -0
  75. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-BoldItalic.ttf +0 -0
  76. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Italic.ttf +0 -0
  77. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Regular.ttf +0 -0
data/lib/epuber/server.rb CHANGED
@@ -23,9 +23,9 @@ require_relative 'third_party/bower'
23
23
 
24
24
 
25
25
  module Epuber
26
-
27
26
  # API:
28
- # [LATER] /file/<path-or-pattern> -- displays pretty file (image, text file) (for example: /file/text/s01.xhtml or /file/text/s01.bade)
27
+ # [LATER] /file/<path-or-pattern> -- displays pretty file (image, text file) (for example: /file/text/s01.xhtml or
28
+ # /file/text/s01.bade)
29
29
  #
30
30
  class Server < Sinatra::Base
31
31
  require_relative 'server/handlers'
@@ -42,11 +42,9 @@ module Epuber
42
42
  body = pretty(env, e)
43
43
  end
44
44
 
45
- unless body.is_a?(Array)
46
- body = [body]
47
- end
45
+ body = [body] unless body.is_a?(Array)
48
46
 
49
- [500, { 'Content-Type' => content_type,
47
+ [500, { 'Content-Type' => content_type,
50
48
  'Content-Length' => Rack::Utils.bytesize(body.join).to_s },
51
49
  body]
52
50
  end
@@ -118,7 +116,7 @@ module Epuber
118
116
 
119
117
  super() do |server|
120
118
  $stderr = old_stderr
121
- puts "Started development server on #{server.host}:#{server.port}"
119
+ UI.puts "Started development server on #{server.host}:#{server.port}"
122
120
 
123
121
  host = if server.host == '0.0.0.0'
124
122
  'localhost'
@@ -134,11 +132,11 @@ module Epuber
134
132
  @verbose = verbose
135
133
  @default_thin_logger ||= Thin::Logging.logger
136
134
 
137
- unless verbose
135
+ if verbose
136
+ Thin::Logging.logger = @default_thin_logger
137
+ else
138
138
  Thin::Logging.logger = Logger.new(nil)
139
139
  Thin::Logging.logger.level = :fatal
140
- else
141
- Thin::Logging.logger = @default_thin_logger
142
140
  end
143
141
 
144
142
  set :logging, verbose
@@ -152,20 +150,18 @@ module Epuber
152
150
  end
153
151
 
154
152
  def self.start_listening_if_needed
155
- return unless self.listener.nil?
153
+ return unless listener.nil?
156
154
 
157
155
  self.listener = Listen.to(Config.instance.project_path, debug: true) do |modified, added, removed|
158
- begin
159
- changes_detected(modified, added, removed)
160
- rescue => e
161
- # print error, do not send error further, listener will die otherwise
162
- $stderr.puts e
163
- $stderr.puts e.backtrace
164
- end
156
+ changes_detected(modified, added, removed)
157
+ rescue StandardError => e
158
+ # print error, do not send error further, listener will die otherwise
159
+ warn e
160
+ warn e.backtrace
165
161
  end
166
162
 
167
- listener.ignore(%r{\.idea})
168
- listener.ignore(%r{#{Config.instance.working_path}})
163
+ listener.ignore(/\.idea/)
164
+ listener.ignore(/#{Config.instance.working_path}/)
169
165
  listener.ignore(%r{#{Config::WORKING_PATH}/})
170
166
 
171
167
  listener.start
@@ -183,22 +179,21 @@ module Epuber
183
179
  self.class.build_path
184
180
  end
185
181
 
186
-
187
- # @param level [Symbol]
188
- # @param message [String]
182
+ # @param [Symbol] level
183
+ # @param [String] message
189
184
  #
190
185
  # @return nil
191
186
  #
192
187
  def self._log(level, message)
193
188
  case level
194
189
  when :ui
195
- puts message
190
+ UI.puts message
196
191
  when :info
197
- puts "INFO: #{message}" if verbose
192
+ UI.puts "INFO: #{message}" if verbose
198
193
  when :get
199
- puts " GET: #{message}" if verbose
194
+ UI.puts " GET: #{message}" if verbose
200
195
  when :ws
201
- puts " WS: #{message}" if verbose
196
+ UI.puts " WS: #{message}" if verbose
202
197
  else
203
198
  raise "Unknown log level #{level}"
204
199
  end
@@ -213,7 +208,7 @@ module Epuber
213
208
 
214
209
  # @!group Helpers
215
210
 
216
- # @param pattern [String]
211
+ # @param [String] pattern
217
212
  #
218
213
  # @return [String] path to file
219
214
  #
@@ -222,13 +217,13 @@ module Epuber
222
217
  finder.find_files(pattern).first
223
218
  end
224
219
 
225
- # @param index [Fixnum]
220
+ # @param [Fixnum] index
226
221
  # @return [Epuber::Book::File, nil]
227
222
  #
228
223
  def spine_file_at(index)
229
- if !file_resolver.nil? && index >= 0 && index < file_resolver.spine_files.count
230
- file_resolver.spine_files[index]
231
- end
224
+ return unless !file_resolver.nil? && index >= 0 && index < file_resolver.spine_files.count
225
+
226
+ file_resolver.spine_files[index]
232
227
  end
233
228
 
234
229
  # @param [String] path
@@ -238,15 +233,14 @@ module Epuber
238
233
  def self.relative_path_to_book_file(path)
239
234
  file = file_resolver.file_with_source_path(path)
240
235
  return if file.nil?
236
+
241
237
  file.pkg_destination_path
242
238
  end
243
239
 
244
240
  def add_script_file_to_head(html_doc, file_name, *args)
245
241
  source = File.read(File.expand_path("server/#{file_name}", File.dirname(__FILE__)))
246
242
 
247
- if File.extname(file_name) == '.coffee'
248
- source = CoffeeScript.compile(source)
249
- end
243
+ source = CoffeeScript.compile(source) if File.extname(file_name) == '.coffee'
250
244
 
251
245
  args.each do |hash|
252
246
  hash.each do |key, value|
@@ -263,8 +257,8 @@ module Epuber
263
257
  add_script_to_head(html_doc, source)
264
258
  end
265
259
 
266
- # @param html_doc [Nokogiri::HTML::Document]
267
- # @param script_text [String]
260
+ # @param [Nokogiri::HTML::Document] html_doc
261
+ # @param [String] script_text
268
262
  #
269
263
  def add_script_to_head(html_doc, script_text)
270
264
  script_node = html_doc.create_element('script', script_text, type: 'text/javascript')
@@ -278,7 +272,7 @@ module Epuber
278
272
  head.add_child(script_node)
279
273
  end
280
274
 
281
- # @param html_doc [Nokogiri::HTML::Document]
275
+ # @param [Nokogiri::HTML::Document] html_doc
282
276
  #
283
277
  def add_auto_refresh_script(html_doc)
284
278
  add_file_to_head(:js, html_doc, 'auto_refresh/reloader.coffee')
@@ -288,7 +282,7 @@ module Epuber
288
282
  add_script_to_head(html_doc, 'var auto_refresh = new AutoRefresh(window, console);')
289
283
  end
290
284
 
291
- # @param html_doc [Nokogiri::HTML::Document]
285
+ # @param [Nokogiri::HTML::Document] html_doc
292
286
  #
293
287
  def add_keyboard_control_script(html_doc, previous_path, next_path)
294
288
  add_script_file_to_head(html_doc, 'keyboard_control.coffee',
@@ -296,27 +290,29 @@ module Epuber
296
290
  '$next_path' => next_path)
297
291
  end
298
292
 
299
- # @param html_doc [Nokogiri::HTML::Document]
293
+ # @param [Nokogiri::HTML::Document] html_doc
300
294
  #
301
295
  def add_file_to_head(type, html_doc, file_path)
302
296
  head = html_doc.at_css('head')
303
297
  node = case type
304
298
  when :style
305
- html_doc.create_element('link', href: "/server/raw/#{file_path}" ,rel: 'stylesheet', type: 'text/css')
299
+ html_doc.create_element('link', href: "/server/raw/#{file_path}", rel: 'stylesheet', type: 'text/css')
306
300
  when :js
307
301
  html_doc.create_element('script', src: "/server/raw/#{file_path}", type: 'text/javascript')
308
302
  else
309
303
  raise "Unknown file type `#{type}`"
310
304
  end
311
305
 
312
- return if head.css('script, link').any? { |n| (!n['href'].nil? && n['href'] == node['href']) || (!n['src'].nil? && n['src'] == node['src']) }
306
+ return if head.css('script, link').any? do |n|
307
+ (!n['href'].nil? && n['href'] == node['href']) || (!n['src'].nil? && n['src'] == node['src'])
308
+ end
313
309
 
314
310
  head.add_child(node)
315
311
  end
316
312
 
317
- # @param html_doc [Nokogiri::HTML::Document]
318
- # @param key [String]
319
- # @param value [String]
313
+ # @param [Nokogiri::HTML::Document] html_doc
314
+ # @param [String] key
315
+ # @param [String] value
320
316
  #
321
317
  def add_meta_to_head(name, content, html_doc, force: false)
322
318
  head = html_doc.at_css('head')
@@ -338,24 +334,22 @@ module Epuber
338
334
  self.target = new_target
339
335
  else
340
336
  self.target = book.targets.first
341
- _log :ui, "[!] Not found previous target after reloading bookspec file, jumping to first #{self.target.name}"
337
+ _log :ui, "[!] Not found previous target after reloading bookspec file, jumping to first #{target.name}"
342
338
  end
343
339
  end
344
340
 
345
341
  def self._compile_book
346
- begin
347
- compiler = Epuber::Compiler.new(book, target)
348
- compiler.compile(build_path)
349
- self.file_resolver = compiler.file_resolver
342
+ compiler = Epuber::Compiler.new(book, target)
343
+ compiler.compile(build_path)
344
+ self.file_resolver = compiler.file_resolver
350
345
 
351
- true
352
- rescue => e
353
- self.file_resolver = compiler.file_resolver
346
+ true
347
+ rescue StandardError => e
348
+ self.file_resolver = compiler.file_resolver
354
349
 
355
- Epuber::UI.error("Compile error: #{e}", location: e)
350
+ Epuber::UI.error("Compile error: #{e}", location: e)
356
351
 
357
- false
358
- end
352
+ false
359
353
  end
360
354
 
361
355
  def self.compile_book(&completion)
@@ -366,15 +360,15 @@ module Epuber
366
360
 
367
361
  @compilation_thread = Thread.new do
368
362
  result = _compile_book
369
- completion.call(result) unless completion.nil?
363
+ completion&.call(result)
370
364
  end
371
365
 
372
- if completion.nil?
373
- @compilation_thread.join
374
- end
366
+ return unless completion.nil?
367
+
368
+ @compilation_thread.join
375
369
  end
376
370
 
377
- # @param message [String]
371
+ # @param [String] message
378
372
  #
379
373
  def self.send_to_clients(message)
380
374
  _log :info, "sending message to clients #{message.inspect}"
@@ -384,10 +378,11 @@ module Epuber
384
378
  end
385
379
  end
386
380
 
387
- # @param type [Symbol]
381
+ # @param [Symbol] type
388
382
  def self.notify_clients(type, data = nil)
389
383
  _log :info, "Notifying clients with type #{type.inspect}"
390
- raise "Not known type `#{type}`" unless [:styles, :reload, :compile_start, :compile_end].include?(type)
384
+ raise "Not known type `#{type}`" unless %i[styles reload compile_start compile_end].include?(type)
385
+
391
386
  message = {
392
387
  name: type,
393
388
  }
@@ -406,17 +401,17 @@ module Epuber
406
401
  files_paths.select { |file| file_resolver.file_with_source_path(file) || book.file_path == file }
407
402
  end
408
403
 
409
- # @param _modified [Array<String>]
410
- # @param _added [Array<String>]
411
- # @param _removed [Array<String>]
404
+ # @param [Array<String>] modified
405
+ # @param [Array<String>] added
406
+ # @param [Array<String>] removed
412
407
  #
413
- def self.changes_detected(_modified, _added, _removed)
414
- all_changed = (_modified + _added + _removed).uniq.map { |path| path.unicode_normalize }
408
+ def self.changes_detected(modified, added, removed)
409
+ all_changed = (modified + added + removed).uniq.map(&:unicode_normalize)
415
410
 
416
411
  reload_bookspec if all_changed.any? { |file| file == book.file_path }
417
412
 
418
413
  changed = filter_not_project_files(all_changed) || []
419
- return if changed.count == 0
414
+ return if changed.count.zero?
420
415
 
421
416
  notify_clients(:compile_start)
422
417
 
@@ -440,11 +435,15 @@ module Epuber
440
435
  # remove nil paths (for example bookspec can't be found so the relative path is nil)
441
436
  changed.compact!
442
437
 
443
- # if changed.size > 0 && changed.all? { |file| file.end_with?(*Epuber::Compiler::FileFinders::GROUP_EXTENSIONS[:style]) }
444
- # notify_clients(:styles, changed)
445
- # else
438
+ changed_only_styles = changed.all? do |file|
439
+ file.end_with?(*Epuber::Compiler::FileFinders::GROUP_EXTENSIONS[:style])
440
+ end
441
+
442
+ if changed.size.positive? && changed_only_styles
443
+ notify_clients(:styles, changed)
444
+ else
446
445
  notify_clients(:reload, changed)
447
- # end
446
+ end
448
447
  end
449
448
  end
450
449
 
@@ -460,12 +459,12 @@ module Epuber
460
459
  ws.onopen do
461
460
  sockets << ws
462
461
 
463
- ws.send({name: :hello}.to_json)
462
+ ws.send({ name: :hello }.to_json)
464
463
 
465
464
  thread = Thread.new do
466
465
  loop do
467
466
  sleep(10)
468
- ws.send({name: :heartbeat}.to_json)
467
+ ws.send({ name: :heartbeat }.to_json)
469
468
  end
470
469
  end
471
470
  end
@@ -490,6 +489,7 @@ module Epuber
490
489
  mtime = File.mtime(file_path)
491
490
  last_modified(mtime)
492
491
  etag(mtime.to_s)
492
+ cache_control :public, :must_revalidate
493
493
 
494
494
  case File.extname(file_path)
495
495
  when '.styl'
@@ -571,11 +571,11 @@ module Epuber
571
571
  full_path = File.expand_path(path, build_path)
572
572
 
573
573
  case File.extname(full_path)
574
- when '.xhtml'
575
- content_type :xhtml
576
- handle_xhtml_file(full_path)
577
- else
578
- handle_file(full_path)
574
+ when '.xhtml'
575
+ content_type :xhtml
576
+ handle_xhtml_file(full_path)
577
+ else
578
+ handle_file(full_path)
579
579
  end
580
580
  end
581
581
  end
@@ -621,6 +621,7 @@ module Epuber
621
621
  get '/raw/*' do
622
622
  path = find_file
623
623
  next not_found if path.nil?
624
+
624
625
  handle_file(File.expand_path(path, build_path))
625
626
  end
626
627
 
@@ -5,12 +5,12 @@ module Epuber
5
5
  class Bower
6
6
  class << self
7
7
  JS_COMPONENTS = {
8
- jquery: 'jquery/dist/',
9
- cookies: 'cookies-js/dist/',
10
- uri: 'uri.js/src/',
11
- spin: 'spin.js/',
8
+ jquery: 'jquery/dist/',
9
+ cookies: 'cookies-js/dist/',
10
+ uri: 'uri.js/src/',
11
+ spin: 'spin.js/',
12
12
  keymaster: 'keymaster/',
13
- }
13
+ }.freeze
14
14
 
15
15
  def path_to_js(component)
16
16
  path = JS_COMPONENTS[component]
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../transformer'
4
+
5
+ module Epuber
6
+ class Transformer
7
+ class BookTransformer < Transformer
8
+ # @return [Book]
9
+ #
10
+ attr_accessor :book
11
+
12
+ # @return [CompilationContext]
13
+ #
14
+ attr_accessor :compilation_context
15
+
16
+ # @param [Epuber::Book] book
17
+ # @param [Epuber::Compiler::CompilationContext] compilation_context
18
+ #
19
+ def call(book, compilation_context)
20
+ @book = book
21
+ @compilation_context = compilation_context
22
+
23
+ @block.call(self, @book, @compilation_context)
24
+
25
+ @book = nil
26
+ @compilation_context = nil
27
+ end
28
+
29
+ # Find file in source or destination paths
30
+ #
31
+ # @param [String] pattern
32
+ # @param [Thread::Backtrace::Location] location
33
+ #
34
+ # @return [Epuber::Compiler::FileTypes::AbstractFile, nil]
35
+ #
36
+ def find_file(pattern, location: caller_locations.first)
37
+ return pattern if pattern.is_a?(Compiler::FileTypes::AbstractFile)
38
+
39
+ UI.error!("Pattern for finding file can't be nil", location: location) if pattern.nil?
40
+
41
+ begin
42
+ path = @compilation_context.file_resolver.source_finder.find_file(pattern)
43
+ @compilation_context.file_resolver.file_with_source_path(path)
44
+ rescue Compiler::FileFinders::FileNotFoundError
45
+ begin
46
+ path = @compilation_context.file_resolver.dest_finder.find_file(pattern)
47
+ @compilation_context.file_resolver.file_with_destination_path(path)
48
+ rescue Compiler::FileFinders::FileNotFoundError
49
+ nil
50
+ end
51
+ end
52
+ end
53
+
54
+ # Find files destination paths
55
+ #
56
+ # @param [String] pattern
57
+ # @param [Thread::Backtrace::Location] location
58
+ #
59
+ # @return [Array<Epuber::Compiler::FileTypes::AbstractFile>]
60
+ #
61
+ def find_destination_files(pattern, location: caller_locations.first)
62
+ UI.error!("Pattern for finding file can't be nil", location: location) if pattern.nil?
63
+
64
+ paths = @compilation_context.file_resolver.dest_finder.find_files(pattern)
65
+ paths.map { |path| @compilation_context.file_resolver.file_with_destination_path(path) }
66
+ end
67
+
68
+ # Find file and raise exception if not found
69
+ #
70
+ # @param [String] pattern
71
+ # @param [Thread::Backtrace::Location] location
72
+ #
73
+ # @return [Epuber::Compiler::FileTypes::AbstractFile]
74
+ #
75
+ def get_file(pattern, location: caller_locations.first)
76
+ file = find_file(pattern, location: location)
77
+ UI.error!("File with pattern #{pattern} not found", location: location) unless file
78
+
79
+ file
80
+ end
81
+
82
+ # Read file from destination path (raises exception if not found)
83
+ #
84
+ # @param [String] pattern
85
+ # @param [Thread::Backtrace::Location] location
86
+ #
87
+ # @return [String]
88
+ #
89
+ def read_destination_file(pattern, location: caller_locations.first)
90
+ file = get_file(pattern, location: location)
91
+ File.read(file.final_destination_path)
92
+ end
93
+
94
+ # Write file to destination path (raises exception if not found)
95
+ #
96
+ # @param [String] pattern
97
+ # @param [String] content
98
+ # @param [Thread::Backtrace::Location] location
99
+ #
100
+ # @return [void]
101
+ #
102
+ def write_destination_file(pattern, content, location: caller_locations.first)
103
+ file = get_file(pattern, location: location)
104
+ Compiler::FileTypes::AbstractFile.write_to_file(content, file.final_destination_path)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -5,7 +5,6 @@ require_relative '../transformer'
5
5
  module Epuber
6
6
  class Transformer
7
7
  class TextTransformer < Transformer
8
-
9
8
  # @return [String]
10
9
  #
11
10
  attr_accessor :text
@@ -51,7 +50,10 @@ module Epuber
51
50
  @text.gsub!(pattern, replacement, &block)
52
51
  end
53
52
 
54
- result = replace_all(pattern, replacement, multiple_times: multiple_times, &block) if multiple_times && !result.nil?
53
+ if multiple_times && !result.nil?
54
+ result = replace_all(pattern, replacement, multiple_times: multiple_times,
55
+ &block)
56
+ end
55
57
  result
56
58
  end
57
59
  end
@@ -5,13 +5,15 @@ require_relative 'checker_transformer_base'
5
5
  module Epuber
6
6
  class Transformer < CheckerTransformerBase
7
7
  require_relative 'transformer/text_transformer'
8
+ require_relative 'transformer/book_transformer'
8
9
 
9
10
  # @return [Hash<Symbol, Class>]
10
11
  #
11
12
  def self.map_source_type__class
12
13
  {
13
- :result_text_xhtml_string => TextTransformer,
14
- :source_text_file => TextTransformer,
14
+ result_text_xhtml_string: TextTransformer,
15
+ source_text_file: TextTransformer,
16
+ after_all_text_files: BookTransformer,
15
17
  }.merge(super)
16
18
  end
17
19
  end