epuber 0.8.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/epuber.gemspec +3 -6
- data/lib/epuber/book/contributor.rb +10 -6
- data/lib/epuber/book/file_request.rb +2 -2
- data/lib/epuber/book/target.rb +10 -10
- data/lib/epuber/book.rb +2 -2
- data/lib/epuber/checker/text_checker.rb +14 -6
- data/lib/epuber/checker_transformer_base.rb +1 -1
- data/lib/epuber/command/build.rb +6 -1
- data/lib/epuber/command/from_file.rb +39 -0
- data/lib/epuber/command/init.rb +11 -9
- data/lib/epuber/command/server.rb +1 -1
- data/lib/epuber/command.rb +1 -0
- data/lib/epuber/compiler/file_database.rb +2 -2
- data/lib/epuber/compiler/file_finders/abstract.rb +3 -3
- data/lib/epuber/compiler/file_resolver.rb +3 -2
- data/lib/epuber/compiler/file_types/abstract_file.rb +1 -3
- data/lib/epuber/compiler/file_types/bade_file.rb +9 -9
- data/lib/epuber/compiler/file_types/css_file.rb +84 -0
- data/lib/epuber/compiler/file_types/source_file.rb +31 -0
- data/lib/epuber/compiler/file_types/stylus_file.rb +4 -3
- data/lib/epuber/compiler/nav_generator.rb +5 -5
- data/lib/epuber/compiler/opf_generator.rb +4 -4
- data/lib/epuber/compiler/xhtml_processor.rb +7 -25
- data/lib/epuber/compiler.rb +12 -7
- data/lib/epuber/config.rb +3 -3
- data/lib/epuber/dsl/attribute.rb +1 -1
- data/lib/epuber/dsl/attribute_support.rb +4 -4
- data/lib/epuber/dsl/object.rb +2 -2
- 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/plugin.rb +1 -1
- data/lib/epuber/server.rb +17 -17
- data/lib/epuber/transformer/book_transformer.rb +108 -0
- data/lib/epuber/transformer.rb +2 -0
- data/lib/epuber/user_interface.rb +2 -2
- data/lib/epuber/vendor/ruby_templater.rb +3 -3
- data/lib/epuber/vendor/version.rb +3 -3
- data/lib/epuber/version.rb +1 -1
- metadata +40 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7acd7fcb74da144389521daa83a8fb681015b82d5cc8a1da35de6058d26fec3
|
4
|
+
data.tar.gz: d61a1ac243fc871f6bf2a114d24936b123ed5a28666057b76fb3fc0da6109265
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85a24b75e370556e3a028e0c118b4f4bc36395c4140472ddfde4be4c46fd95549fecf3d18c28d72bf545b13f9850d82394ea509b8a97d9e3f1078f678d28647e
|
7
|
+
data.tar.gz: 62483b8f634b572336cbede86754baa95d3627ac0c69d4f47e44ca701e57b201b53e0b9568a22fd7d4c3ebee6f345c1b132012be303f0ab73ed4db26d332deb3
|
data/Gemfile
CHANGED
@@ -5,6 +5,15 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in Epuber.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
+
# dev
|
9
|
+
gem 'fakefs', '>= 1.3', '< 3.0' # 2.0.0 is not compatible with Ruby 2.5
|
10
|
+
gem 'rake', '~> 13.0'
|
11
|
+
gem 'rspec', '~> 3.2'
|
12
|
+
gem 'rubocop', '~> 1.14'
|
13
|
+
|
14
|
+
# VSCode plugins
|
15
|
+
gem 'ruby-lsp', require: false
|
16
|
+
|
8
17
|
group :dev, optional: true do
|
9
18
|
gem 'rubocop-rspec', require: false
|
10
19
|
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -104,9 +104,9 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
104
104
|
|
105
105
|
## Contributing
|
106
106
|
|
107
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/epuber-io/epuber. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
107
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/epuber-io/epuber. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct.
|
108
108
|
|
109
109
|
|
110
110
|
## License
|
111
111
|
|
112
|
-
The gem is available as open source under the terms of the [MIT License](
|
112
|
+
The gem is available as open source under the terms of the [MIT License](./LICENSE.txt).
|
data/epuber.gemspec
CHANGED
@@ -11,10 +11,10 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.homepage = Epuber::HOME_URL
|
12
12
|
spec.license = 'MIT'
|
13
13
|
spec.required_ruby_version = '>= 2.5'
|
14
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
14
15
|
|
15
16
|
spec.files = Dir['bin/**/*'] + Dir['lib/**/*'] + %w[epuber.gemspec Gemfile LICENSE.txt README.md]
|
16
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_runtime_dependency 'activesupport', '>= 6.0', '< 8.0'
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency 'mime-types', '~> 3.0'
|
25
25
|
spec.add_runtime_dependency 'nokogiri', '~> 1.8', '>= 1.8.2'
|
26
26
|
spec.add_runtime_dependency 'os', '~> 1.0'
|
27
|
+
spec.add_runtime_dependency 'uuidtools', '~> 2.1'
|
27
28
|
|
28
29
|
spec.add_runtime_dependency 'sinatra', '>= 2.0', '< 4.0'
|
29
30
|
spec.add_runtime_dependency 'sinatra-contrib', '>= 2.0', '< 4.0'
|
@@ -37,10 +38,6 @@ Gem::Specification.new do |spec|
|
|
37
38
|
|
38
39
|
spec.add_runtime_dependency 'bade', '~> 0.3', '>= 0.3.1'
|
39
40
|
spec.add_runtime_dependency 'coffee-script', '~> 2.4'
|
41
|
+
spec.add_runtime_dependency 'css_parser', '>= 0.8', '< 2.0'
|
40
42
|
spec.add_runtime_dependency 'epuber-stylus', '~> 1.1', '>= 1.1.1'
|
41
|
-
|
42
|
-
spec.add_development_dependency 'fakefs', '>= 1.3', '< 3.0' # 2.0.0 is not compatible with Ruby 2.5
|
43
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
44
|
-
spec.add_development_dependency 'rspec', '~> 3.2'
|
45
|
-
spec.add_development_dependency 'rubocop', '~> 1.14'
|
46
43
|
end
|
@@ -31,22 +31,26 @@ module Epuber
|
|
31
31
|
|
32
32
|
# Creates new instance of Contributor dependent on obj content
|
33
33
|
#
|
34
|
-
# @param
|
35
|
-
# @param
|
34
|
+
# @param [Hash<Symbol, String>, Array<Hash<Symbol,String>, String, Array<String>] obj input object
|
35
|
+
# @param [String] role role of contributor
|
36
36
|
#
|
37
37
|
# @return [Contributor]
|
38
38
|
#
|
39
|
-
def self.from_obj(obj, role)
|
39
|
+
def self.from_obj(obj, role = 'aut')
|
40
40
|
if obj.is_a?(String)
|
41
|
-
components = obj.split
|
41
|
+
components = obj.split
|
42
42
|
if components.length >= 2
|
43
43
|
NormalContributor.new(components.first(components.length - 1).join(' '), components.last, role)
|
44
|
+
else
|
45
|
+
Contributor.new(obj, obj, role)
|
44
46
|
end
|
45
47
|
elsif obj.is_a?(Hash)
|
46
48
|
if obj.key?(:first_name)
|
47
|
-
NormalContributor.new(obj[:first_name], obj[:last_name], role)
|
49
|
+
NormalContributor.new(obj[:first_name], obj[:last_name], obj[:role] || role)
|
48
50
|
elsif obj.key?(:file_as)
|
49
|
-
Contributor.new(obj[:pretty_name], obj[:file_as], role)
|
51
|
+
Contributor.new(obj[:pretty_name], obj[:file_as], obj[:role] || role)
|
52
|
+
elsif obj.key?(:name)
|
53
|
+
Contributor.from_obj(obj[:name], obj[:role] || role)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
end
|
@@ -45,10 +45,10 @@ module Epuber
|
|
45
45
|
# @return [Numeric]
|
46
46
|
#
|
47
47
|
def hash
|
48
|
-
@source_pattern
|
48
|
+
[@source_pattern, @group, @only_one].hash
|
49
49
|
end
|
50
50
|
|
51
|
-
# @param
|
51
|
+
# @param [String, self] other
|
52
52
|
#
|
53
53
|
def ==(other)
|
54
54
|
if other.is_a?(String)
|
data/lib/epuber/book/target.rb
CHANGED
@@ -215,8 +215,8 @@ module Epuber
|
|
215
215
|
inherited: false
|
216
216
|
|
217
217
|
|
218
|
-
# @param
|
219
|
-
# @param
|
218
|
+
# @param [String | Epuber::Book::File] file_path
|
219
|
+
# @param [Symbol] group
|
220
220
|
#
|
221
221
|
# @return [Epuber::Book::File] created file
|
222
222
|
#
|
@@ -238,7 +238,7 @@ module Epuber
|
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
241
|
-
# @param
|
241
|
+
# @param [Array<String>] file_paths
|
242
242
|
#
|
243
243
|
# @return [void]
|
244
244
|
#
|
@@ -249,8 +249,8 @@ module Epuber
|
|
249
249
|
end
|
250
250
|
end
|
251
251
|
|
252
|
-
# @param
|
253
|
-
# @param
|
252
|
+
# @param [String] key
|
253
|
+
# @param [String] value
|
254
254
|
#
|
255
255
|
# @return [void]
|
256
256
|
#
|
@@ -262,7 +262,7 @@ module Epuber
|
|
262
262
|
end
|
263
263
|
end
|
264
264
|
|
265
|
-
# @param
|
265
|
+
# @param [Array<String>] file_paths
|
266
266
|
#
|
267
267
|
# @return [void]
|
268
268
|
#
|
@@ -278,7 +278,7 @@ module Epuber
|
|
278
278
|
# Add default styles to default target, default styles will be automatically added to xhtml document
|
279
279
|
#
|
280
280
|
# Only difference with #add_default_style is it adds multiple files with one pattern
|
281
|
-
# @param
|
281
|
+
# @param [Array<String>] file_paths
|
282
282
|
#
|
283
283
|
# @return [void]
|
284
284
|
#
|
@@ -291,7 +291,7 @@ module Epuber
|
|
291
291
|
end
|
292
292
|
end
|
293
293
|
|
294
|
-
# @param
|
294
|
+
# @param [Array<String>] file_paths
|
295
295
|
#
|
296
296
|
# @return [void]
|
297
297
|
#
|
@@ -307,7 +307,7 @@ module Epuber
|
|
307
307
|
# Add default scripts to target, default scripts will be automatically added to xhtml document
|
308
308
|
#
|
309
309
|
# Only difference with #add_default_script is it adds multiple files with one pattern
|
310
|
-
# @param
|
310
|
+
# @param [Array<String>] file_paths
|
311
311
|
#
|
312
312
|
# @return [void]
|
313
313
|
#
|
@@ -330,7 +330,7 @@ module Epuber
|
|
330
330
|
yield(@root_toc, self) if block_given?
|
331
331
|
end
|
332
332
|
|
333
|
-
# @param
|
333
|
+
# @param [String] path use some file/module/package
|
334
334
|
#
|
335
335
|
# @return [nil]
|
336
336
|
#
|
data/lib/epuber/book.rb
CHANGED
@@ -160,7 +160,7 @@ module Epuber
|
|
160
160
|
container: Array,
|
161
161
|
required: true,
|
162
162
|
singularize: true,
|
163
|
-
auto_convert: { [String, Hash] => ->(value) { Contributor.from_obj(value
|
163
|
+
auto_convert: { [String, Hash] => ->(value) { Contributor.from_obj(value) } }
|
164
164
|
|
165
165
|
|
166
166
|
# @return [String] publisher name
|
@@ -294,7 +294,7 @@ module Epuber
|
|
294
294
|
|
295
295
|
# Finds target with name or nil when not found
|
296
296
|
#
|
297
|
-
# @param
|
297
|
+
# @param [Symbol, String, Epuber::Book::Target] target_name
|
298
298
|
#
|
299
299
|
# @return [Epuber::Book::Target, nil]
|
300
300
|
#
|
@@ -10,9 +10,9 @@ module Epuber
|
|
10
10
|
class Checker
|
11
11
|
class TextChecker < Checker
|
12
12
|
class MatchProblem < Compiler::Problem
|
13
|
-
# @param
|
14
|
-
# @param
|
15
|
-
# @param
|
13
|
+
# @param [String] message
|
14
|
+
# @param [String] file_path
|
15
|
+
# @param [MatchData] match
|
16
16
|
#
|
17
17
|
def initialize(match, message, file_path)
|
18
18
|
whole_text = match.pre_match + match.matched_string + match.post_match
|
@@ -36,8 +36,8 @@ module Epuber
|
|
36
36
|
|
37
37
|
|
38
38
|
|
39
|
-
# @param
|
40
|
-
# @param
|
39
|
+
# @param [String] file_path
|
40
|
+
# @param [String] text
|
41
41
|
# @param [CompilationContext] compilation_context
|
42
42
|
#
|
43
43
|
# @return nil
|
@@ -52,7 +52,7 @@ module Epuber
|
|
52
52
|
@file_path = nil
|
53
53
|
end
|
54
54
|
|
55
|
-
# @param
|
55
|
+
# @param [Regexp] regexp
|
56
56
|
# @param [String] message message to display, when the regexp found something
|
57
57
|
#
|
58
58
|
def should_not_contain(regexp, message)
|
@@ -65,6 +65,14 @@ module Epuber
|
|
65
65
|
Config.instance.pretty_path_from_project(file_path))
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
69
|
+
def error(message, location: nil)
|
70
|
+
super(message, location: location || Config.instance.pretty_path_from_project(file_path))
|
71
|
+
end
|
72
|
+
|
73
|
+
def warning(message, location: nil)
|
74
|
+
super(message, location: location || Config.instance.pretty_path_from_project(file_path))
|
75
|
+
end
|
68
76
|
end
|
69
77
|
end
|
70
78
|
end
|
data/lib/epuber/command/build.rb
CHANGED
@@ -26,7 +26,12 @@ module Epuber
|
|
26
26
|
].concat(super)
|
27
27
|
end
|
28
28
|
|
29
|
-
#
|
29
|
+
# To resolve problem with `compile` treating as subcommand
|
30
|
+
def self.subcommands
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [CLAide::ARGV] argv
|
30
35
|
#
|
31
36
|
def initialize(argv)
|
32
37
|
@targets_names = argv.arguments!
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../command'
|
4
|
+
require_relative '../from_file/from_file_executor'
|
5
|
+
|
6
|
+
module Epuber
|
7
|
+
class Command
|
8
|
+
class FromFile < Command
|
9
|
+
self.summary = 'Initialize current folder to use it as Epuber project from existing EPUB file'
|
10
|
+
self.arguments = [
|
11
|
+
CLAide::Argument.new('EPUB_FILE', true),
|
12
|
+
]
|
13
|
+
|
14
|
+
# @param [CLAide::ARGV] argv
|
15
|
+
#
|
16
|
+
def initialize(argv)
|
17
|
+
@filepath = argv.arguments!.first
|
18
|
+
|
19
|
+
super(argv)
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate!
|
23
|
+
super
|
24
|
+
|
25
|
+
help! 'You must specify path to existing EPUB file' if @filepath.nil?
|
26
|
+
help! "File #{@filepath} doesn't exists" unless File.exist?(@filepath)
|
27
|
+
|
28
|
+
existing = Dir.glob('*.bookspec')
|
29
|
+
help! "Can't reinit this folder, #{existing.first} already exists." unless existing.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
super
|
34
|
+
|
35
|
+
FromFileExecutor.new(@filepath).run
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/epuber/command/init.rb
CHANGED
@@ -11,10 +11,10 @@ module Epuber
|
|
11
11
|
class Init < Command
|
12
12
|
self.summary = 'Initialize current folder to use it as Epuber project'
|
13
13
|
self.arguments = [
|
14
|
-
CLAide::Argument.new('PROJECT_NAME', false
|
14
|
+
CLAide::Argument.new('PROJECT_NAME', false),
|
15
15
|
]
|
16
16
|
|
17
|
-
# @param
|
17
|
+
# @param [CLAide::ARGV] argv
|
18
18
|
#
|
19
19
|
def initialize(argv)
|
20
20
|
@book_name = argv.arguments!.first
|
@@ -23,6 +23,8 @@ module Epuber
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def validate!
|
26
|
+
super
|
27
|
+
|
26
28
|
help! 'You must specify identifier-like name of the book as first argument' if @book_name.nil?
|
27
29
|
|
28
30
|
existing = Dir.glob('*.bookspec')
|
@@ -57,7 +59,7 @@ module Epuber
|
|
57
59
|
|
58
60
|
# Creates <book-id>.bookspec file from template
|
59
61
|
#
|
60
|
-
# @param
|
62
|
+
# @param [String] book_id
|
61
63
|
#
|
62
64
|
# @return [void]
|
63
65
|
#
|
@@ -71,7 +73,7 @@ module Epuber
|
|
71
73
|
|
72
74
|
# Creates <book-id>.sublime-project
|
73
75
|
#
|
74
|
-
# @param
|
76
|
+
# @param [String] book_id
|
75
77
|
#
|
76
78
|
# @return [void]
|
77
79
|
#
|
@@ -115,8 +117,8 @@ module Epuber
|
|
115
117
|
STYLUS
|
116
118
|
end
|
117
119
|
|
118
|
-
# @param
|
119
|
-
# @param
|
120
|
+
# @param [String] string text to file
|
121
|
+
# @param [String] file_path path to file
|
120
122
|
#
|
121
123
|
# @return [void]
|
122
124
|
#
|
@@ -125,8 +127,8 @@ module Epuber
|
|
125
127
|
UI.puts " #{'create'.ansi.green} #{file_path}"
|
126
128
|
end
|
127
129
|
|
128
|
-
# @param
|
129
|
-
# @param
|
130
|
+
# @param [String] string text to file
|
131
|
+
# @param [String] file_path path to file
|
130
132
|
#
|
131
133
|
# @return [void]
|
132
134
|
#
|
@@ -158,7 +160,7 @@ module Epuber
|
|
158
160
|
UI.puts " #{'create'.ansi.green} #{dir_path}/"
|
159
161
|
end
|
160
162
|
|
161
|
-
# @param
|
163
|
+
# @param [String] text
|
162
164
|
#
|
163
165
|
# @return [String] returned text without new line
|
164
166
|
#
|
data/lib/epuber/command.rb
CHANGED
@@ -65,7 +65,7 @@ module Epuber
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def update_all_metadata
|
68
|
-
@all_files.
|
68
|
+
@all_files.each_key do |file_path|
|
69
69
|
update_metadata(file_path)
|
70
70
|
end
|
71
71
|
end
|
@@ -98,7 +98,7 @@ module Epuber
|
|
98
98
|
to_remove = @all_files.keys - file_paths
|
99
99
|
to_remove.each { |key| @all_files.delete(key) }
|
100
100
|
|
101
|
-
@all_files.
|
101
|
+
@all_files.each_value do |stat|
|
102
102
|
_cleanup_stat_dependency_list(file_paths, stat)
|
103
103
|
end
|
104
104
|
end
|
@@ -194,7 +194,7 @@ module Epuber
|
|
194
194
|
end.flatten
|
195
195
|
|
196
196
|
paths.select do |file_path|
|
197
|
-
valid_extensions.include?(::File.extname(file_path))
|
197
|
+
valid_extensions.include?(::File.extname(file_path).downcase)
|
198
198
|
end
|
199
199
|
end
|
200
200
|
end
|
@@ -247,8 +247,8 @@ module Epuber
|
|
247
247
|
# @return [Array<String>] list of founded files
|
248
248
|
#
|
249
249
|
def __core_find_files(pattern, groups, context_path, orig_context_path = context_path)
|
250
|
-
context_path =
|
251
|
-
orig_context_path =
|
250
|
+
context_path = File.dirname(context_path) if __core_file?(context_path)
|
251
|
+
orig_context_path = File.dirname(orig_context_path) if __core_file?(orig_context_path)
|
252
252
|
|
253
253
|
full_pattern = File.expand_path(pattern, context_path)
|
254
254
|
file_paths = __core_find_files_from_pattern(full_pattern).map(&:unicode_normalize)
|
@@ -20,7 +20,7 @@ module Epuber
|
|
20
20
|
require_relative 'file_types/container_xml_file'
|
21
21
|
require_relative 'file_types/ibooks_display_options_file'
|
22
22
|
require_relative 'file_types/coffee_script_file'
|
23
|
-
|
23
|
+
require_relative 'file_types/css_file'
|
24
24
|
|
25
25
|
class FileResolver
|
26
26
|
class ResolveError < StandardError; end
|
@@ -247,6 +247,7 @@ module Epuber
|
|
247
247
|
def file_class_for(extname)
|
248
248
|
mapping = {
|
249
249
|
'.styl' => FileTypes::StylusFile,
|
250
|
+
'.css' => FileTypes::CSSFile,
|
250
251
|
|
251
252
|
'.coffee' => FileTypes::CoffeeScriptFile,
|
252
253
|
|
@@ -279,7 +280,7 @@ module Epuber
|
|
279
280
|
|
280
281
|
private
|
281
282
|
|
282
|
-
# @param
|
283
|
+
# @param [Epuber::Compiler::AbstractFile] file
|
283
284
|
#
|
284
285
|
# @return [nil]
|
285
286
|
#
|
@@ -45,15 +45,7 @@ module Epuber
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
if
|
49
|
-
xhtml_content = UI.print_step_processing_time('rendering precompiled Bade') do
|
50
|
-
renderer = Bade::Renderer.from_precompiled(precompiled)
|
51
|
-
.with_locals(variables)
|
52
|
-
renderer.file_path = source_path
|
53
|
-
|
54
|
-
renderer.render(new_line: '', indent: '')
|
55
|
-
end
|
56
|
-
else
|
48
|
+
if precompiled.nil?
|
57
49
|
if compilation_context.incremental_build?
|
58
50
|
UI.print_processing_debug_info('Parsing new version of source file')
|
59
51
|
end
|
@@ -70,6 +62,14 @@ module Epuber
|
|
70
62
|
FileUtils.mkdir_p(File.dirname(precompiled_path))
|
71
63
|
renderer.precompiled.write_yaml_to_file(precompiled_path)
|
72
64
|
|
65
|
+
renderer.render(new_line: '', indent: '')
|
66
|
+
end
|
67
|
+
else
|
68
|
+
xhtml_content = UI.print_step_processing_time('rendering precompiled Bade') do
|
69
|
+
renderer = Bade::Renderer.from_precompiled(precompiled)
|
70
|
+
.with_locals(variables)
|
71
|
+
renderer.file_path = source_path
|
72
|
+
|
73
73
|
renderer.render(new_line: '', indent: '')
|
74
74
|
end
|
75
75
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'css_parser'
|
4
|
+
|
5
|
+
module Epuber
|
6
|
+
class Compiler
|
7
|
+
module FileTypes
|
8
|
+
require_relative 'source_file'
|
9
|
+
|
10
|
+
class CSSFile < SourceFile
|
11
|
+
DECLARATION_TO_FILE_GROUP_MAP = {
|
12
|
+
'background' => :image,
|
13
|
+
'background-image' => :image,
|
14
|
+
'list-style' => :image,
|
15
|
+
'list-style-image' => :image,
|
16
|
+
'content' => :image,
|
17
|
+
'cursor' => :image,
|
18
|
+
'border-image' => :image,
|
19
|
+
'border-image-source' => :image,
|
20
|
+
'mask-image' => :image,
|
21
|
+
'mask-box-image' => :image,
|
22
|
+
'src' => :font,
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
URL_REGEXP = /url\((.+)\)/.freeze
|
26
|
+
|
27
|
+
# @param [Compiler::CompilationContext] compilation_context
|
28
|
+
#
|
29
|
+
def process(compilation_context)
|
30
|
+
return if destination_file_up_to_date?
|
31
|
+
|
32
|
+
write_processed(process_css(File.read(abs_source_path), compilation_context))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Processes CSS file, resolves all linked files and adds them to file resolver
|
36
|
+
#
|
37
|
+
# @param [String] content
|
38
|
+
# @param [Compiler::CompilationContext] compilation_context
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
def process_css(content, compilation_context)
|
43
|
+
parser = UI.print_step_processing_time('css parsing') do
|
44
|
+
parser = CssParser::Parser.new
|
45
|
+
parser.load_string!(content)
|
46
|
+
parser
|
47
|
+
end
|
48
|
+
|
49
|
+
# resolve links to files, add other linked resources and compute correct path
|
50
|
+
UI.print_step_processing_time('resolving url()') do
|
51
|
+
parser.each_rule_set do |rule_set, _media_types|
|
52
|
+
declarations = rule_set.instance_eval { @declarations }
|
53
|
+
declarations.each do |property, decl_value|
|
54
|
+
value = decl_value.to_s
|
55
|
+
next unless value =~ URL_REGEXP
|
56
|
+
|
57
|
+
path = Regexp.last_match(1)
|
58
|
+
if path.start_with?('"') && path.end_with?('"')
|
59
|
+
path = path[1..-2]
|
60
|
+
quote = '"'
|
61
|
+
end
|
62
|
+
if path.start_with?("'") && path.end_with?("'")
|
63
|
+
path = path[1..-2]
|
64
|
+
quote = "'"
|
65
|
+
end
|
66
|
+
|
67
|
+
next if path.start_with?('data:') || path.start_with?('http://') || path.start_with?('https://')
|
68
|
+
|
69
|
+
resource_group = DECLARATION_TO_FILE_GROUP_MAP[property]
|
70
|
+
new_url = SourceFile.resolve_relative_file(destination_path,
|
71
|
+
path,
|
72
|
+
compilation_context.file_resolver,
|
73
|
+
group: resource_group)
|
74
|
+
content = content.gsub(value, "url(#{quote}#{new_url}#{quote})")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
content
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -112,6 +112,37 @@ module Epuber
|
|
112
112
|
MSG
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
def self.resolve_relative_file(destination_path, pattern, file_resolver, group: nil)
|
117
|
+
dirname = File.dirname(destination_path)
|
118
|
+
|
119
|
+
begin
|
120
|
+
new_path = file_resolver.dest_finder.find_file(pattern, groups: group, context_path: dirname)
|
121
|
+
rescue FileFinders::FileNotFoundError, FileFinders::MultipleFilesFoundError
|
122
|
+
begin
|
123
|
+
new_path = XHTMLProcessor.resolved_link_to_file(pattern,
|
124
|
+
group,
|
125
|
+
dirname,
|
126
|
+
file_resolver.source_finder).to_s
|
127
|
+
rescue XHTMLProcessor::UnparseableLinkError,
|
128
|
+
FileFinders::FileNotFoundError,
|
129
|
+
FileFinders::MultipleFilesFoundError => e
|
130
|
+
UI.warning(e.to_s, location: img)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
pkg_abs_path = File.expand_path(new_path, dirname).unicode_normalize
|
135
|
+
pkg_new_path = Pathname.new(pkg_abs_path)
|
136
|
+
.relative_path_from(Pathname.new(file_resolver.source_path))
|
137
|
+
.to_s
|
138
|
+
|
139
|
+
file_class = FileResolver.file_class_for(File.extname(new_path))
|
140
|
+
file = file_class.new(pkg_new_path)
|
141
|
+
file.path_type = :manifest
|
142
|
+
file_resolver.add_file(file)
|
143
|
+
|
144
|
+
FileResolver.renamed_file_with_path(new_path)
|
145
|
+
end
|
115
146
|
end
|
116
147
|
end
|
117
148
|
end
|