epuber 0.7.4 → 0.8.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 +1 -2
- data/README.md +2 -1
- data/epuber.gemspec +10 -12
- data/lib/epuber/book/contributor.rb +0 -1
- data/lib/epuber/book/file_request.rb +1 -1
- data/lib/epuber/book/target.rb +20 -23
- data/lib/epuber/book/toc_item.rb +2 -4
- data/lib/epuber/book.rb +19 -19
- data/lib/epuber/checker/bookspec_checker.rb +26 -0
- data/lib/epuber/checker/text_checker.rb +2 -1
- data/lib/epuber/checker.rb +16 -2
- data/lib/epuber/checker_transformer_base.rb +2 -5
- data/lib/epuber/command/build.rb +34 -24
- data/lib/epuber/command/init.rb +23 -23
- data/lib/epuber/command/server.rb +2 -2
- data/lib/epuber/command.rb +17 -20
- data/lib/epuber/compiler/compilation_context.rb +10 -8
- data/lib/epuber/compiler/file_database.rb +0 -2
- data/lib/epuber/compiler/file_finders/abstract.rb +33 -23
- data/lib/epuber/compiler/file_finders/imaginary.rb +40 -35
- data/lib/epuber/compiler/file_resolver.rb +77 -88
- data/lib/epuber/compiler/file_stat.rb +4 -4
- data/lib/epuber/compiler/file_types/abstract_file.rb +3 -4
- data/lib/epuber/compiler/file_types/bade_file.rb +12 -7
- data/lib/epuber/compiler/file_types/coffee_script_file.rb +1 -1
- 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/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 +5 -6
- data/lib/epuber/compiler/opf_generator.rb +22 -23
- data/lib/epuber/compiler/problem.rb +12 -21
- data/lib/epuber/compiler/xhtml_processor.rb +61 -31
- data/lib/epuber/compiler.rb +66 -19
- data/lib/epuber/config.rb +13 -7
- data/lib/epuber/dsl/attribute.rb +16 -17
- data/lib/epuber/dsl/attribute_support.rb +3 -3
- data/lib/epuber/dsl/object.rb +17 -15
- data/lib/epuber/dsl/tree_object.rb +2 -3
- data/lib/epuber/epubcheck.rb +15 -0
- data/lib/epuber/helper.rb +0 -1
- data/lib/epuber/lockfile.rb +7 -9
- data/lib/epuber/plugin.rb +1 -2
- 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 +67 -66
- data/lib/epuber/third_party/bower.rb +5 -5
- data/lib/epuber/transformer/text_transformer.rb +4 -2
- data/lib/epuber/transformer.rb +2 -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 +1 -5
- data/lib/epuber/vendor/version.rb +10 -10
- data/lib/epuber/version.rb +1 -1
- metadata +67 -69
- 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/command/init.rb
CHANGED
@@ -50,9 +50,9 @@ module Epuber
|
|
50
50
|
private
|
51
51
|
|
52
52
|
def print_good_bye(book_id)
|
53
|
-
puts
|
54
|
-
Project initialized, please review #{book_id}.bookspec file, remove comments and fill some attributes like book title.
|
55
|
-
|
53
|
+
UI.puts <<~TEXT.ansi.green
|
54
|
+
Project initialized, please review #{book_id}.bookspec file, remove comments and fill some attributes like book title.
|
55
|
+
TEXT
|
56
56
|
end
|
57
57
|
|
58
58
|
# Creates <book-id>.bookspec file from template
|
@@ -76,16 +76,18 @@ END
|
|
76
76
|
# @return [void]
|
77
77
|
#
|
78
78
|
def write_sublime_project(book_id)
|
79
|
-
text =
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
79
|
+
text = <<~JSON
|
80
|
+
{
|
81
|
+
"folders": [
|
82
|
+
{
|
83
|
+
"follow_symlinks": true,
|
84
|
+
"path": ".",
|
85
|
+
"folder_exclude_patterns": [".epuber"],
|
86
|
+
"file_exclude_patterns": ["*.epub"]
|
87
|
+
}
|
88
|
+
]
|
89
|
+
}
|
90
|
+
JSON
|
89
91
|
|
90
92
|
write("#{book_id}.sublime-project", text)
|
91
93
|
end
|
@@ -95,7 +97,7 @@ END
|
|
95
97
|
# @return [void]
|
96
98
|
#
|
97
99
|
def write_gitignore
|
98
|
-
append_new_lines('.gitignore', <<~
|
100
|
+
append_new_lines('.gitignore', <<~TEXT)
|
99
101
|
# This is generated with `epuber init`
|
100
102
|
*.epub
|
101
103
|
*.mobi
|
@@ -104,15 +106,13 @@ END
|
|
104
106
|
.epuber/release_build/
|
105
107
|
.epuber/build_cache/
|
106
108
|
.epuber/metadata/
|
107
|
-
|
108
|
-
)
|
109
|
+
TEXT
|
109
110
|
end
|
110
111
|
|
111
112
|
def write_default_style(book_id)
|
112
|
-
write("styles/#{book_id}.styl", <<~
|
113
|
+
write("styles/#{book_id}.styl", <<~STYLUS)
|
113
114
|
// This is generated with `epuber init` script.
|
114
|
-
|
115
|
-
)
|
115
|
+
STYLUS
|
116
116
|
end
|
117
117
|
|
118
118
|
# @param string [String] text to file
|
@@ -122,7 +122,7 @@ END
|
|
122
122
|
#
|
123
123
|
def write(file_path, string)
|
124
124
|
File.write(file_path, string)
|
125
|
-
puts " #{'create'.ansi.green} #{file_path}"
|
125
|
+
UI.puts " #{'create'.ansi.green} #{file_path}"
|
126
126
|
end
|
127
127
|
|
128
128
|
# @param string [String] text to file
|
@@ -146,7 +146,7 @@ END
|
|
146
146
|
existing_content << "\n"
|
147
147
|
|
148
148
|
File.write(file_path, existing_content)
|
149
|
-
puts " #{'update'.ansi.green} #{file_path}"
|
149
|
+
UI.puts " #{'update'.ansi.green} #{file_path}"
|
150
150
|
end
|
151
151
|
|
152
152
|
# @param [String] dir_path path to dir
|
@@ -155,7 +155,7 @@ END
|
|
155
155
|
#
|
156
156
|
def create_folder(dir_path)
|
157
157
|
FileUtils.mkdir_p(dir_path)
|
158
|
-
puts " #{'create'.ansi.green} #{dir_path}/"
|
158
|
+
UI.puts " #{'create'.ansi.green} #{dir_path}/"
|
159
159
|
end
|
160
160
|
|
161
161
|
# @param text [String]
|
@@ -167,7 +167,7 @@ END
|
|
167
167
|
result = $stdin.gets.chomp
|
168
168
|
|
169
169
|
while result.empty?
|
170
|
-
puts 'Value cannot be empty, please fill it!'.ansi.red
|
170
|
+
UI.puts 'Value cannot be empty, please fill it!'.ansi.red
|
171
171
|
print text
|
172
172
|
result = $stdin.gets.chomp
|
173
173
|
end
|
@@ -13,7 +13,7 @@ module Epuber
|
|
13
13
|
|
14
14
|
def self.options
|
15
15
|
[
|
16
|
-
['--open',
|
16
|
+
['--open', 'Opens the web page in default web browser, working only on OS X'],
|
17
17
|
].concat(super)
|
18
18
|
end
|
19
19
|
|
@@ -51,7 +51,7 @@ module Epuber
|
|
51
51
|
if @open_web_browser
|
52
52
|
system "open #{uri}"
|
53
53
|
else
|
54
|
-
puts 'Web browser can be automatically opened by adding --open flag, see --help'
|
54
|
+
UI.puts 'Web browser can be automatically opened by adding --open flag, see --help'
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/epuber/command.rb
CHANGED
@@ -21,21 +21,18 @@ module Epuber
|
|
21
21
|
self.command = 'epuber'
|
22
22
|
self.version = VERSION
|
23
23
|
self.description = 'Epuber, easy creating and maintaining e-book.'
|
24
|
-
self.plugin_prefixes = plugin_prefixes + %w
|
24
|
+
self.plugin_prefixes = plugin_prefixes + %w[epuber]
|
25
25
|
|
26
26
|
def self.run(argv = [])
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
UI.current_command = nil
|
38
|
-
end
|
27
|
+
UI.current_command = self
|
28
|
+
super
|
29
|
+
UI.current_command = nil
|
30
|
+
rescue Interrupt
|
31
|
+
UI.error('[!] Cancelled')
|
32
|
+
rescue StandardError => e
|
33
|
+
UI.error!(e)
|
34
|
+
|
35
|
+
UI.current_command = nil
|
39
36
|
end
|
40
37
|
|
41
38
|
def validate!
|
@@ -70,18 +67,18 @@ module Epuber
|
|
70
67
|
end
|
71
68
|
|
72
69
|
def write_lockfile
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
return if Epuber::Config.test?
|
71
|
+
|
72
|
+
Epuber::Config.instance.save_lockfile
|
76
73
|
end
|
77
74
|
|
78
75
|
def pre_build_checks
|
79
76
|
Config.instance.warn_for_outdated_versions!
|
80
77
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
return unless !Config.instance.same_version_as_last_run? && File.exist?(Config.instance.working_path)
|
79
|
+
|
80
|
+
UI.warning('Using different version of Epuber or Bade, removing all build caches')
|
81
|
+
Config.instance.remove_build_caches
|
85
82
|
end
|
86
83
|
end
|
87
84
|
end
|
@@ -32,15 +32,13 @@ module Epuber
|
|
32
32
|
#
|
33
33
|
def plugins
|
34
34
|
@plugins ||= @target.plugins.map do |path|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
file_resolver.add_file(file)
|
39
|
-
end
|
40
|
-
plugin
|
41
|
-
rescue LoadError
|
42
|
-
UI.error "Can't find plugin at path #{path}"
|
35
|
+
plugin = Plugin.new(path)
|
36
|
+
plugin.files.each do |file|
|
37
|
+
file_resolver.add_file(file)
|
43
38
|
end
|
39
|
+
plugin
|
40
|
+
rescue LoadError
|
41
|
+
UI.error "Can't find plugin at path #{path}"
|
44
42
|
end.compact
|
45
43
|
end
|
46
44
|
|
@@ -100,6 +98,10 @@ module Epuber
|
|
100
98
|
use_cache
|
101
99
|
end
|
102
100
|
|
101
|
+
def release_build?
|
102
|
+
release_build
|
103
|
+
end
|
104
|
+
|
103
105
|
def initialize(book, target)
|
104
106
|
@book = book
|
105
107
|
@target = target
|
@@ -7,7 +7,6 @@ module Epuber
|
|
7
7
|
require_relative 'file_stat'
|
8
8
|
|
9
9
|
class FileDatabase
|
10
|
-
|
11
10
|
# @return [Hash<String, Epuber::Compiler::FileStat>]
|
12
11
|
#
|
13
12
|
attr_accessor :all_files
|
@@ -130,7 +129,6 @@ module Epuber
|
|
130
129
|
_cleanup_stat_dependency_list(file_paths, next_stat)
|
131
130
|
end
|
132
131
|
end
|
133
|
-
|
134
132
|
end
|
135
133
|
end
|
136
134
|
end
|
@@ -16,6 +16,8 @@ module Epuber
|
|
16
16
|
# @param [String] context_path
|
17
17
|
#
|
18
18
|
def initialize(pattern, context_path)
|
19
|
+
super()
|
20
|
+
|
19
21
|
@pattern = pattern
|
20
22
|
@context_path = context_path
|
21
23
|
end
|
@@ -48,6 +50,8 @@ module Epuber
|
|
48
50
|
# @param [Array<String>] files_paths list of founded files
|
49
51
|
#
|
50
52
|
def initialize(pattern, groups, context_path, files_paths)
|
53
|
+
super()
|
54
|
+
|
51
55
|
@pattern = pattern
|
52
56
|
@groups = Array(groups)
|
53
57
|
@context_path = context_path
|
@@ -61,16 +65,16 @@ module Epuber
|
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
|
-
BINARY_EXTENSIONS = %w
|
65
|
-
STATIC_EXTENSIONS = BINARY_EXTENSIONS + %w
|
68
|
+
BINARY_EXTENSIONS = %w[.png .jpeg .jpg .otf .ttf].freeze
|
69
|
+
STATIC_EXTENSIONS = BINARY_EXTENSIONS + %w[.css .js]
|
66
70
|
|
67
71
|
GROUP_EXTENSIONS = {
|
68
|
-
text:
|
69
|
-
image:
|
70
|
-
font:
|
71
|
-
style:
|
72
|
-
script: %w
|
73
|
-
}
|
72
|
+
text: %w[.xhtml .html .bade],
|
73
|
+
image: %w[.png .jpg .jpeg],
|
74
|
+
font: %w[.otf .ttf],
|
75
|
+
style: %w[.css .styl],
|
76
|
+
script: %w[.js .coffee],
|
77
|
+
}.freeze
|
74
78
|
|
75
79
|
EXTENSIONS_RENAME = {
|
76
80
|
'.styl' => '.css',
|
@@ -78,10 +82,9 @@ module Epuber
|
|
78
82
|
'.bade' => '.xhtml',
|
79
83
|
|
80
84
|
'.coffee' => '.js',
|
81
|
-
}
|
85
|
+
}.freeze
|
82
86
|
|
83
87
|
class Abstract
|
84
|
-
|
85
88
|
# @return [String] path where should look for source files
|
86
89
|
#
|
87
90
|
attr_reader :source_path
|
@@ -99,7 +102,6 @@ module Epuber
|
|
99
102
|
@ignored_patterns = []
|
100
103
|
end
|
101
104
|
|
102
|
-
|
103
105
|
# @param [Array<Symbol> | Symbol] groups
|
104
106
|
#
|
105
107
|
def assert_one_file(files, pattern: nil, groups: nil, context_path: nil)
|
@@ -113,7 +115,8 @@ module Epuber
|
|
113
115
|
# When it founds too many (more than two) it will raise MultipleFilesFoundError
|
114
116
|
#
|
115
117
|
# @param [String] pattern pattern of the desired files
|
116
|
-
# @param [Array<Symbol> | Symbol] groups list of group names, nil or empty array for all groups, for valid
|
118
|
+
# @param [Array<Symbol> | Symbol] groups list of group names, nil or empty array for all groups, for valid
|
119
|
+
# values see GROUP_EXTENSIONS
|
117
120
|
# @param [String] context_path path for root of searching, it is also defines start folder of relative path
|
118
121
|
#
|
119
122
|
# @return [Array<String>] list of founded files
|
@@ -128,7 +131,8 @@ module Epuber
|
|
128
131
|
# #source_path and after that it tries to search recursively from #source_path.
|
129
132
|
#
|
130
133
|
# @param [String] pattern pattern of the desired files
|
131
|
-
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
134
|
+
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
135
|
+
# GROUP_EXTENSIONS
|
132
136
|
# @param [String] context_path path for root of searching, it is also defines start folder of relative path
|
133
137
|
#
|
134
138
|
# @return [Array<String>] list of founded files
|
@@ -141,7 +145,9 @@ module Epuber
|
|
141
145
|
searching_path = ::File.expand_path(context_path, @source_path_abs)
|
142
146
|
|
143
147
|
unless searching_path.start_with?(@source_path_abs)
|
144
|
-
raise
|
148
|
+
raise <<~ERROR
|
149
|
+
You can't search from folder (#{searching_path}) that is not sub folder of the source_path (#{source_path}) expanded to (#{@source_path_abs}).
|
150
|
+
ERROR
|
145
151
|
end
|
146
152
|
|
147
153
|
files = __find_files(pattern, groups, searching_path)
|
@@ -152,7 +158,7 @@ module Epuber
|
|
152
158
|
end
|
153
159
|
|
154
160
|
if files.empty? && search_everywhere && !pattern.start_with?('**')
|
155
|
-
files = __find_files(
|
161
|
+
files = __find_files("**/#{pattern}", groups, @source_path_abs, searching_path || @source_path_abs)
|
156
162
|
end
|
157
163
|
|
158
164
|
files
|
@@ -161,13 +167,14 @@ module Epuber
|
|
161
167
|
# Looks for all files from #source_path recursively
|
162
168
|
#
|
163
169
|
# @param [String] pattern pattern of the desired files
|
164
|
-
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
170
|
+
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
171
|
+
# GROUP_EXTENSIONS
|
165
172
|
# @param [String] context_path path for root of searching, it is also defines start folder of relative path
|
166
173
|
#
|
167
174
|
# @return [Array<String>] list of founded files
|
168
175
|
#
|
169
176
|
def find_all(pattern, groups: nil, context_path: @source_path_abs)
|
170
|
-
__find_files(
|
177
|
+
__find_files("**/#{pattern}", groups, context_path)
|
171
178
|
end
|
172
179
|
|
173
180
|
# @param [Array<String>] paths list of file paths
|
@@ -209,7 +216,8 @@ module Epuber
|
|
209
216
|
# Looks for files at given context path, if there is no file, it will try again with pattern for any extension
|
210
217
|
#
|
211
218
|
# @param [String] pattern pattern of the desired files
|
212
|
-
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
219
|
+
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
220
|
+
# GROUP_EXTENSIONS
|
213
221
|
# @param [String] context_path path for root of searching, it is also defines start folder of relative path
|
214
222
|
# @param [String] orig_context_path original context path, wo it will work nicely with iterative searching
|
215
223
|
#
|
@@ -222,15 +230,17 @@ module Epuber
|
|
222
230
|
files = __core_find_files(pattern, groups, context_path, orig_context_path)
|
223
231
|
|
224
232
|
# try to find files with any extension
|
225
|
-
files = __core_find_files(pattern
|
233
|
+
files = __core_find_files("#{pattern}.*", groups, context_path, orig_context_path) if files.empty?
|
226
234
|
|
227
235
|
files
|
228
236
|
end
|
229
237
|
|
230
|
-
# Core method for finding files, it only search for files, filter by input groups and map the final paths to
|
238
|
+
# Core method for finding files, it only search for files, filter by input groups and map the final paths to
|
239
|
+
# pretty relative paths from context_path
|
231
240
|
#
|
232
241
|
# @param [String] pattern pattern of the desired files
|
233
|
-
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
242
|
+
# @param [Array<Symbol>] groups list of group names, nil or empty array for all groups, for valid values see
|
243
|
+
# GROUP_EXTENSIONS
|
234
244
|
# @param [String] context_path path for root of searching, it is also defines start folder of relative path
|
235
245
|
# @param [String] orig_context_path original context path, wo it will work nicely with iterative searching
|
236
246
|
#
|
@@ -258,11 +268,11 @@ module Epuber
|
|
258
268
|
self.class.relative_paths_from(file_paths, orig_context_path)
|
259
269
|
end
|
260
270
|
|
261
|
-
def __core_find_files_from_pattern(
|
271
|
+
def __core_find_files_from_pattern(_pattern)
|
262
272
|
raise 'Implement this in subclass'
|
263
273
|
end
|
264
274
|
|
265
|
-
def __core_file?(
|
275
|
+
def __core_file?(_path)
|
266
276
|
raise 'Implement this in subclass'
|
267
277
|
end
|
268
278
|
end
|
@@ -11,6 +11,8 @@ module Epuber
|
|
11
11
|
#
|
12
12
|
attr_accessor :entries
|
13
13
|
|
14
|
+
# @return [String]
|
15
|
+
#
|
14
16
|
attr_reader :name
|
15
17
|
|
16
18
|
def initialize(name)
|
@@ -32,8 +34,12 @@ module Epuber
|
|
32
34
|
end
|
33
35
|
|
34
36
|
class FileEntry
|
37
|
+
# @return [String]
|
38
|
+
#
|
35
39
|
attr_reader :name
|
36
40
|
|
41
|
+
# @return [String]
|
42
|
+
#
|
37
43
|
attr_reader :absolute_path
|
38
44
|
|
39
45
|
def initialize(name, absolute_path)
|
@@ -42,7 +48,7 @@ module Epuber
|
|
42
48
|
end
|
43
49
|
|
44
50
|
def ==(other)
|
45
|
-
other.is_a?(FileEntry) ?
|
51
|
+
name == (other.is_a?(FileEntry) ? other.name : other.to_s)
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
@@ -83,14 +89,11 @@ module Epuber
|
|
83
89
|
make_dir_p(path)[file_name] = FileEntry.new(file_name, file_path)
|
84
90
|
end
|
85
91
|
|
86
|
-
|
87
92
|
def __core_find_files_from_pattern(pattern)
|
88
93
|
parts = self.class.path_parts(pattern)
|
89
94
|
found_entries = find_recurser(root, parts).flatten
|
90
95
|
file_entries = found_entries.reject { |entry| entry.is_a?(DirEntry) }
|
91
|
-
file_entries.map
|
92
|
-
item.absolute_path
|
93
|
-
end
|
96
|
+
file_entries.map(&:absolute_path)
|
94
97
|
end
|
95
98
|
|
96
99
|
def __core_file?(path)
|
@@ -104,12 +107,14 @@ module Epuber
|
|
104
107
|
current.is_a?(FileEntry)
|
105
108
|
end
|
106
109
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
110
|
+
class << self
|
111
|
+
def path_parts(path)
|
112
|
+
path.split(File::SEPARATOR).reject(&:empty?)
|
113
|
+
end
|
111
114
|
end
|
112
115
|
|
116
|
+
private
|
117
|
+
|
113
118
|
def find_recurser(dir, parts)
|
114
119
|
return [] unless dir.respond_to? :[]
|
115
120
|
|
@@ -117,25 +122,25 @@ module Epuber
|
|
117
122
|
return [] if pattern.nil?
|
118
123
|
|
119
124
|
matches = case pattern
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
else
|
134
|
-
directories_under(dir)
|
135
|
-
end
|
125
|
+
when '**'
|
126
|
+
case parts
|
127
|
+
when ['*']
|
128
|
+
parts = [] # end recursion
|
129
|
+
directories_under(dir).map do |d|
|
130
|
+
d.entries.select do |f|
|
131
|
+
(f.is_a?(FileEntry) || f.is_a?(DirEntry)) &&
|
132
|
+
f.name.match(/\A(?!\.)/)
|
133
|
+
end
|
134
|
+
end.flatten.uniq
|
135
|
+
when []
|
136
|
+
parts = [] # end recursion
|
137
|
+
dir.entries.values.flatten.uniq
|
136
138
|
else
|
137
|
-
|
138
|
-
|
139
|
+
directories_under(dir)
|
140
|
+
end
|
141
|
+
else
|
142
|
+
regex_body = pattern_to_regex(pattern)
|
143
|
+
dir.entries.select { |k, _v| /\A#{regex_body}\Z/ =~ k }.values
|
139
144
|
end
|
140
145
|
|
141
146
|
if parts.empty? # we're done recursing
|
@@ -156,14 +161,14 @@ module Epuber
|
|
156
161
|
|
157
162
|
def pattern_to_regex(pattern)
|
158
163
|
pattern.gsub('.', '\.')
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
164
|
+
.gsub('?', '.')
|
165
|
+
.gsub('*', '.*')
|
166
|
+
.gsub('(', '\(')
|
167
|
+
.gsub(')', '\)')
|
168
|
+
.gsub(/\{(.*?)\}/) do
|
169
|
+
"(#{Regexp.last_match[1].gsub(',', '|')})"
|
170
|
+
end
|
171
|
+
.gsub(/\A\./, '(?!\.).')
|
167
172
|
end
|
168
173
|
end
|
169
174
|
end
|