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.
- checksums.yaml +4 -4
- data/Gemfile +10 -2
- data/LICENSE.txt +1 -1
- data/README.md +4 -3
- data/epuber.gemspec +11 -16
- data/lib/epuber/book/contributor.rb +10 -7
- data/lib/epuber/book/file_request.rb +3 -3
- data/lib/epuber/book/target.rb +30 -33
- data/lib/epuber/book/toc_item.rb +2 -4
- data/lib/epuber/book.rb +21 -21
- data/lib/epuber/checker/bookspec_checker.rb +26 -0
- data/lib/epuber/checker/text_checker.rb +16 -7
- data/lib/epuber/checker.rb +16 -2
- data/lib/epuber/checker_transformer_base.rb +3 -6
- data/lib/epuber/command/build.rb +40 -25
- data/lib/epuber/command/from_file.rb +39 -0
- data/lib/epuber/command/init.rb +34 -32
- data/lib/epuber/command/server.rb +3 -3
- data/lib/epuber/command.rb +18 -20
- data/lib/epuber/compiler/compilation_context.rb +10 -8
- data/lib/epuber/compiler/file_database.rb +2 -4
- data/lib/epuber/compiler/file_finders/abstract.rb +36 -26
- data/lib/epuber/compiler/file_finders/imaginary.rb +40 -35
- data/lib/epuber/compiler/file_resolver.rb +79 -89
- data/lib/epuber/compiler/file_stat.rb +4 -4
- data/lib/epuber/compiler/file_types/abstract_file.rb +4 -7
- data/lib/epuber/compiler/file_types/bade_file.rb +20 -15
- data/lib/epuber/compiler/file_types/coffee_script_file.rb +1 -1
- data/lib/epuber/compiler/file_types/css_file.rb +103 -0
- data/lib/epuber/compiler/file_types/generated_file.rb +1 -1
- data/lib/epuber/compiler/file_types/image_file.rb +4 -2
- data/lib/epuber/compiler/file_types/nav_file.rb +0 -1
- data/lib/epuber/compiler/file_types/opf_file.rb +0 -1
- data/lib/epuber/compiler/file_types/source_file.rb +8 -3
- data/lib/epuber/compiler/file_types/stylus_file.rb +4 -3
- data/lib/epuber/compiler/file_types/xhtml_file.rb +67 -13
- data/lib/epuber/compiler/generator.rb +1 -2
- data/lib/epuber/compiler/meta_inf_generator.rb +1 -1
- data/lib/epuber/compiler/nav_generator.rb +10 -11
- data/lib/epuber/compiler/opf_generator.rb +26 -27
- data/lib/epuber/compiler/problem.rb +12 -21
- data/lib/epuber/compiler/xhtml_processor.rb +63 -32
- data/lib/epuber/compiler.rb +77 -25
- data/lib/epuber/config.rb +16 -10
- data/lib/epuber/dsl/attribute.rb +17 -18
- data/lib/epuber/dsl/attribute_support.rb +7 -7
- data/lib/epuber/dsl/object.rb +19 -17
- data/lib/epuber/dsl/tree_object.rb +2 -3
- data/lib/epuber/epubcheck.rb +15 -0
- data/lib/epuber/from_file/bookspec_generator.rb +371 -0
- data/lib/epuber/from_file/encryption_handler.rb +146 -0
- data/lib/epuber/from_file/from_file_executor.rb +140 -0
- data/lib/epuber/from_file/nav_file.rb +163 -0
- data/lib/epuber/from_file/opf_file.rb +219 -0
- data/lib/epuber/helper.rb +0 -1
- data/lib/epuber/lockfile.rb +7 -9
- data/lib/epuber/plugin.rb +2 -3
- data/lib/epuber/ruby_extensions/match_data.rb +1 -1
- data/lib/epuber/ruby_extensions/thread.rb +1 -0
- data/lib/epuber/server/base.styl +0 -1
- data/lib/epuber/server/basic.styl +1 -30
- data/lib/epuber/server/handlers.rb +1 -1
- data/lib/epuber/server.rb +81 -80
- data/lib/epuber/third_party/bower.rb +5 -5
- data/lib/epuber/transformer/book_transformer.rb +108 -0
- data/lib/epuber/transformer/text_transformer.rb +4 -2
- data/lib/epuber/transformer.rb +4 -2
- data/lib/epuber/user_interface.rb +49 -38
- data/lib/epuber/vendor/hash_binding.rb +9 -2
- data/lib/epuber/vendor/ruby_templater.rb +4 -8
- data/lib/epuber/vendor/version.rb +12 -12
- data/lib/epuber/version.rb +1 -1
- metadata +79 -100
- data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Bold.ttf +0 -0
- data/lib/epuber/server/fonts/AvenirNext/AvenirNext-BoldItalic.ttf +0 -0
- data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Italic.ttf +0 -0
- 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
|
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'
|
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
|
-
|
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
|
153
|
+
return unless listener.nil?
|
156
154
|
|
157
155
|
self.listener = Listen.to(Config.instance.project_path, debug: true) do |modified, added, removed|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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(
|
168
|
-
listener.ignore(
|
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
|
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
|
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
|
220
|
+
# @param [Fixnum] index
|
226
221
|
# @return [Epuber::Book::File, nil]
|
227
222
|
#
|
228
223
|
def spine_file_at(index)
|
229
|
-
|
230
|
-
|
231
|
-
|
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
|
267
|
-
# @param
|
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
|
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
|
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
|
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',
|
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?
|
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
|
318
|
-
# @param
|
319
|
-
# @param
|
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 #{
|
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
|
-
|
347
|
-
|
348
|
-
|
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
|
-
|
352
|
-
|
353
|
-
|
346
|
+
true
|
347
|
+
rescue StandardError => e
|
348
|
+
self.file_resolver = compiler.file_resolver
|
354
349
|
|
355
|
-
|
350
|
+
Epuber::UI.error("Compile error: #{e}", location: e)
|
356
351
|
|
357
|
-
|
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
|
363
|
+
completion&.call(result)
|
370
364
|
end
|
371
365
|
|
372
|
-
|
373
|
-
|
374
|
-
|
366
|
+
return unless completion.nil?
|
367
|
+
|
368
|
+
@compilation_thread.join
|
375
369
|
end
|
376
370
|
|
377
|
-
# @param
|
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
|
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 [
|
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
|
410
|
-
# @param
|
411
|
-
# @param
|
404
|
+
# @param [Array<String>] modified
|
405
|
+
# @param [Array<String>] added
|
406
|
+
# @param [Array<String>] removed
|
412
407
|
#
|
413
|
-
def self.changes_detected(
|
414
|
-
all_changed = (
|
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
|
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
|
-
|
444
|
-
|
445
|
-
|
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
|
-
|
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
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
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:
|
9
|
-
cookies:
|
10
|
-
uri:
|
11
|
-
spin:
|
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
|
-
|
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
|
data/lib/epuber/transformer.rb
CHANGED
@@ -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
|
-
:
|
14
|
-
:
|
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
|