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
@@ -6,7 +6,6 @@ module Epuber
6
6
  require_relative 'abstract_file'
7
7
 
8
8
  class SourceFile < AbstractFile
9
-
10
9
  # @return [String] relative source path
11
10
  #
12
11
  attr_reader :source_path
@@ -22,6 +21,8 @@ module Epuber
22
21
  # @param [String] source_path relative path from project root to source file
23
22
  #
24
23
  def initialize(source_path)
24
+ super()
25
+
25
26
  @source_path = source_path
26
27
  end
27
28
 
@@ -95,7 +96,9 @@ module Epuber
95
96
  UI.print_processing_debug_info("Writing compiled version to #{pkg_destination_path}")
96
97
  self.class.write_to_file!(content, final_destination_path)
97
98
  else
98
- UI.print_processing_debug_info("Not writing to disk ... compiled version at #{pkg_destination_path} is same")
99
+ UI.print_processing_debug_info(<<~MSG)
100
+ Not writing to disk ... compiled version at #{pkg_destination_path} is same
101
+ MSG
99
102
  end
100
103
  end
101
104
 
@@ -104,7 +107,9 @@ module Epuber
104
107
  UI.print_processing_debug_info("Writing processed version to #{pkg_destination_path}")
105
108
  self.class.write_to_file!(content, final_destination_path)
106
109
  else
107
- UI.print_processing_debug_info("Not writing to disk ... processed version at #{pkg_destination_path} is same")
110
+ UI.print_processing_debug_info(<<~MSG)
111
+ Not writing to disk ... processed version at #{pkg_destination_path} is same
112
+ MSG
108
113
  end
109
114
  end
110
115
  end
@@ -5,9 +5,9 @@ require 'epuber-stylus'
5
5
  module Epuber
6
6
  class Compiler
7
7
  module FileTypes
8
- require_relative 'source_file'
8
+ require_relative 'css_file'
9
9
 
10
- class StylusFile < SourceFile
10
+ class StylusFile < CSSFile
11
11
  # @param [Compiler::CompilationContext] compilation_context
12
12
  #
13
13
  def process(compilation_context)
@@ -19,7 +19,8 @@ module Epuber
19
19
  Stylus.define('__book_title', compilation_context.book.title)
20
20
  Stylus.define('__const', compilation_context.target.constants)
21
21
 
22
- write_compiled(Stylus.compile(File.new(abs_source_path)))
22
+ css = Stylus.compile(File.new(abs_source_path))
23
+ write_compiled(process_css(css, compilation_context))
23
24
 
24
25
  update_metadata!
25
26
  end
@@ -12,6 +12,21 @@ module Epuber
12
12
  #
13
13
  attr_accessor :toc_item
14
14
 
15
+ # @return [Array<String>]
16
+ #
17
+ attr_accessor :global_ids
18
+
19
+ # @return [Array<String>]
20
+ #
21
+ attr_accessor :global_links
22
+
23
+ def initialize(source_path)
24
+ super
25
+
26
+ self.global_ids = []
27
+ self.global_links = []
28
+ end
29
+
15
30
  # @param [Book::Target] target
16
31
  # @param [FileResolver] file_resolver
17
32
  #
@@ -22,8 +37,9 @@ module Epuber
22
37
  Array(file_resolver.file_from_request(default_style_request))
23
38
  end.flatten
24
39
 
40
+ dirname = Pathname.new(File.dirname(final_destination_path))
25
41
  default_styles.map do |style|
26
- Pathname.new(style.final_destination_path).relative_path_from(Pathname.new(File.dirname(final_destination_path))).to_s
42
+ Pathname.new(style.final_destination_path).relative_path_from(dirname).to_s
27
43
  end
28
44
  end
29
45
 
@@ -37,8 +53,9 @@ module Epuber
37
53
  Array(file_resolver.file_from_request(default_style_request))
38
54
  end.flatten
39
55
 
56
+ dirname = Pathname.new(File.dirname(final_destination_path))
40
57
  default_scripts.map do |style|
41
- Pathname.new(style.final_destination_path).relative_path_from(Pathname.new(File.dirname(final_destination_path))).to_s
58
+ Pathname.new(style.final_destination_path).relative_path_from(dirname).to_s
42
59
  end
43
60
  end
44
61
 
@@ -58,10 +75,7 @@ module Epuber
58
75
  end
59
76
  end
60
77
 
61
-
62
- if compilation_context.should_write
63
- self.class.write_to_file(xhtml_content, abs_source_path)
64
- end
78
+ self.class.write_to_file(xhtml_content, abs_source_path) if compilation_context.should_write
65
79
 
66
80
  xhtml_content
67
81
  end
@@ -88,9 +102,7 @@ module Epuber
88
102
  XHTMLProcessor.xml_doc_from_str_with_errors(content, source_path)
89
103
  end
90
104
 
91
- if compilation_context.release_build && xhtml_doc.errors.count > 0
92
- process_nokogiri_errors(errors)
93
- end
105
+ process_nokogiri_errors(errors) if compilation_context.release_build && xhtml_doc.errors.count.positive?
94
106
 
95
107
  UI.print_step_processing_time('adding missing elements') do
96
108
  XHTMLProcessor.add_missing_root_elements(xhtml_doc, book.title, target.epub_version)
@@ -120,13 +132,13 @@ module Epuber
120
132
  XHTMLProcessor.resolve_mathml_namespace(xhtml_doc)
121
133
 
122
134
  UI.print_step_processing_time('investigating properties') do
123
- self.properties << :remote_resources if XHTMLProcessor.using_remote_resources?(xhtml_doc)
124
- self.properties << :scripted if XHTMLProcessor.using_javascript?(xhtml_doc)
125
- self.properties << :mathml if XHTMLProcessor.using_mathml?(xhtml_doc)
135
+ properties << :remote_resources if XHTMLProcessor.using_remote_resources?(xhtml_doc)
136
+ properties << :scripted if XHTMLProcessor.using_javascript?(xhtml_doc)
137
+ properties << :mathml if XHTMLProcessor.using_mathml?(xhtml_doc)
126
138
  end
127
139
 
128
140
  xhtml_string = UI.print_step_processing_time('converting to XHTML') do
129
- xhtml_doc.to_s
141
+ xhtml_doc.to_s
130
142
  end
131
143
 
132
144
  # perform transformations
@@ -145,6 +157,12 @@ module Epuber
145
157
  end
146
158
  end
147
159
 
160
+ if xhtml_string.include?('="$')
161
+ xhtml_doc = XHTMLProcessor.xml_document_from_string(xhtml_string, final_destination_path)
162
+ self.global_ids = XHTMLProcessor.find_global_ids(xhtml_doc)
163
+ self.global_links = XHTMLProcessor.find_global_links(xhtml_doc)
164
+ end
165
+
148
166
  xhtml_string
149
167
  end
150
168
 
@@ -153,6 +171,42 @@ module Epuber
153
171
  def process(compilation_context)
154
172
  write_processed(common_process(load_source(compilation_context), compilation_context))
155
173
  end
174
+
175
+ # @param [Compiler::CompilationContext] compilation_context
176
+ # @param [Hash<String, XHTMLFile>] global_ids
177
+ #
178
+ def process_global_ids(compilation_context, global_ids)
179
+ return if self.global_ids.empty? && global_links.empty?
180
+
181
+ xhtml_doc = XHTMLProcessor.xml_document_from_string(File.read(final_destination_path), final_destination_path)
182
+
183
+ XHTMLProcessor.find_global_ids_nodes(xhtml_doc).each do |node|
184
+ id = node['id']
185
+ node['id'] = id[1..-1]
186
+ end
187
+
188
+ XHTMLProcessor.find_global_links_nodes(xhtml_doc).each do |node|
189
+ href = node['href'][1..-1]
190
+
191
+ dest_file = global_ids[href]
192
+ if dest_file
193
+ rel_path = Pathname(dest_file.final_destination_path.unicode_normalize)
194
+ .relative_path_from(Pathname(File.dirname(final_destination_path.unicode_normalize))).to_s
195
+
196
+ node['href'] = "#{rel_path}##{href}"
197
+ else
198
+ message = "Can't find global id '#{href}' from link in file #{source_path}"
199
+ location = UserInterface::Location.new(path: final_destination_path, lineno: node.line)
200
+ if compilation_context.release_build?
201
+ UI.error!(message, location: location)
202
+ else
203
+ UI.warning(message, location: location)
204
+ end
205
+ end
206
+ end
207
+
208
+ write_processed(xhtml_doc.to_s)
209
+ end
156
210
  end
157
211
  end
158
212
  end
@@ -12,7 +12,6 @@ module Nokogiri
12
12
  end
13
13
  end
14
14
 
15
-
16
15
  module Epuber
17
16
  class Compiler
18
17
  class Generator
@@ -55,7 +54,7 @@ module Epuber
55
54
  builder = Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml|
56
55
  @xml = xml
57
56
 
58
- block.call(xml) unless block.nil?
57
+ block&.call(xml)
59
58
 
60
59
  @xml = nil
61
60
  end
@@ -15,7 +15,7 @@ module Epuber
15
15
  generate_xml do |xml|
16
16
  xml.container(version: 1.0, xmlns: 'urn:oasis:names:tc:opendocument:xmlns:container') do
17
17
  xml.rootfiles do
18
- @file_resolver.package_files.select { |file| file.kind_of?(FileTypes::OPFFile) }.each do |file|
18
+ @file_resolver.package_files.select { |file| file.is_a?(FileTypes::OPFFile) }.each do |file|
19
19
  path = file.pkg_destination_path
20
20
  xml.rootfile('full-path' => path, 'media-type' => MIME::Types.of(path).first.content_type)
21
21
  end
@@ -9,7 +9,6 @@ module Epuber
9
9
  require_relative 'generator'
10
10
 
11
11
  class NavGenerator < Generator
12
-
13
12
  NCX_NAMESPACES = {
14
13
  'xmlns' => 'http://www.daisy.org/z3986/2005/ncx/',
15
14
  }.freeze
@@ -26,10 +25,10 @@ module Epuber
26
25
 
27
26
  # resource page http://www.idpf.org/epub/301/spec/epub-contentdocs.html#sec-xhtml-nav-def-types-landmarks
28
27
  LANDMARKS_MAP = {
29
- landmark_cover: { type: 'cover', text: 'Cover page' },
30
- landmark_start_page: { type: %w(bodymatter ibooks:reader-start-page), text: 'Start Reading' },
31
- landmark_copyright: { type: 'copyright-page', text: 'Copyright page' },
32
- landmark_toc: { type: 'toc', text: 'Table of contents' },
28
+ landmark_cover: { type: 'cover', text: 'Cover page' },
29
+ landmark_start_page: { type: %w[bodymatter ibooks:reader-start-page], text: 'Start Reading' },
30
+ landmark_copyright: { type: 'copyright-page', text: 'Copyright page' },
31
+ landmark_toc: { type: 'toc', text: 'Table of contents' },
33
32
  }.freeze
34
33
 
35
34
  # Generates XML for toc document, the structure differs depend on epub_version
@@ -95,7 +94,7 @@ module Epuber
95
94
  @xml.ncx(nav_namespaces, version: '2005-1') do
96
95
  # head
97
96
  @xml.head do
98
- @xml.meta(name: 'dtb:uid', content: (@target.identifier || "urn:isbn:#{@target.isbn}"))
97
+ @xml.meta(name: 'dtb:uid', content: @target.identifier || "urn:isbn:#{@target.isbn}")
99
98
  end
100
99
 
101
100
  # title
@@ -112,7 +111,7 @@ module Epuber
112
111
  end
113
112
  end
114
113
 
115
- # @param toc_items [Array<Epuber::Book::TocItem>]
114
+ # @param [Array<Epuber::Book::TocItem>] toc_items
116
115
  #
117
116
  def visit_toc_items(toc_items)
118
117
  iterate_lambda = lambda do
@@ -121,7 +120,7 @@ module Epuber
121
120
  end
122
121
  end
123
122
 
124
- if @target.epub_version >= 3 && toc_items.length > 0 && contains_item_with_title(toc_items)
123
+ if @target.epub_version >= 3 && toc_items.length.positive? && contains_item_with_title(toc_items)
125
124
  @xml.ol do
126
125
  iterate_lambda.call
127
126
  end
@@ -134,7 +133,7 @@ module Epuber
134
133
  toc_items.any? { |a| a.title || contains_item_with_title(a.sub_items) }
135
134
  end
136
135
 
137
- # @param toc_item [Epuber::Book::TocItem]
136
+ # @param [Epuber::Book::TocItem] toc_item
138
137
  #
139
138
  def visit_toc_item(toc_item)
140
139
  result_file_path = pretty_path_for_toc_item(toc_item)
@@ -166,7 +165,7 @@ module Epuber
166
165
 
167
166
  # --------------- landmarks -----------------------------
168
167
 
169
- # @param toc_items [Array<Epuber::Book::TocItem>]
168
+ # @param [Array<Epuber::Book::TocItem>] toc_items
170
169
  #
171
170
  def landmarks_visit_toc_items(toc_items)
172
171
  toc_items.each do |child_item|
@@ -174,7 +173,7 @@ module Epuber
174
173
  end
175
174
  end
176
175
 
177
- # @param toc_item [Epuber::Book::TocItem]
176
+ # @param [Epuber::Book::TocItem] toc_item
178
177
  #
179
178
  def landmarks_visit_toc_item(toc_item)
180
179
  landmarks = toc_item.landmarks
@@ -11,20 +11,19 @@ require_relative '../book/toc_item'
11
11
  module Epuber
12
12
  class Compiler
13
13
  class OPFGenerator < Generator
14
-
15
14
  EPUB2_NAMESPACES = {
16
- 'xmlns' => 'http://www.idpf.org/2007/opf',
17
- 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
15
+ 'xmlns' => 'http://www.idpf.org/2007/opf',
16
+ 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
18
17
  'xmlns:opf' => 'http://www.idpf.org/2007/opf',
19
18
  }.freeze
20
19
 
21
20
  EPUB3_NAMESPACES = {
22
- 'prefix' => 'rendition: http://www.idpf.org/vocab/rendition/',
21
+ 'prefix' => 'rendition: http://www.idpf.org/vocab/rendition/',
23
22
  'xmlns:epub' => 'http://www.idpf.org/2007/ops',
24
23
  }.freeze
25
24
 
26
25
  IBOOKS_NAMESPACES = {
27
- 'prefix' => 'rendition: http://www.idpf.org/vocab/rendition/# ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/',
26
+ 'prefix' => 'rendition: http://www.idpf.org/vocab/rendition/# ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/',
28
27
  'xmlns:ibooks' => 'http://apple.com/ibooks/html-extensions',
29
28
  }.freeze
30
29
 
@@ -32,32 +31,32 @@ module Epuber
32
31
  LANDMARKS_MAP = {
33
32
 
34
33
  # my favorite
35
- landmark_cover: 'cover',
34
+ landmark_cover: 'cover',
36
35
  landmark_start_page: 'text',
37
- landmark_copyright: 'copyright-page',
38
- landmark_toc: 'toc',
36
+ landmark_copyright: 'copyright-page',
37
+ landmark_toc: 'toc',
39
38
 
40
39
  # others
41
- landmark_title: 'title-page',
42
- landmark_index: 'index',
43
- landmark_glossary: 'glossary',
44
- landmark_acknowledgements: 'acknowledgements',
45
- landmark_bibliography: 'bibliography',
46
- landmark_colophon: 'colophon',
47
- landmark_dedication: 'dedication',
48
- landmark_epigraph: 'epigraph',
49
- landmark_foreword: 'foreword',
40
+ landmark_title: 'title-page',
41
+ landmark_index: 'index',
42
+ landmark_glossary: 'glossary',
43
+ landmark_acknowledgements: 'acknowledgements',
44
+ landmark_bibliography: 'bibliography',
45
+ landmark_colophon: 'colophon',
46
+ landmark_dedication: 'dedication',
47
+ landmark_epigraph: 'epigraph',
48
+ landmark_foreword: 'foreword',
50
49
  landmark_list_of_illustrations: 'loi',
51
- landmark_list_of_tables: 'lot',
52
- landmark_notes: 'notes',
53
- landmark_preface: 'preface',
50
+ landmark_list_of_tables: 'lot',
51
+ landmark_notes: 'notes',
52
+ landmark_preface: 'preface',
54
53
 
55
54
  }.freeze
56
55
 
57
56
  PROPERTIES_MAP = {
58
57
  cover_image: 'cover-image',
59
- navigation: 'nav',
60
- scripted: 'scripted',
58
+ navigation: 'nav',
59
+ scripted: 'scripted',
61
60
  remote_resources: 'remote-resources',
62
61
  mathml: 'mathml',
63
62
  }.freeze
@@ -164,7 +163,7 @@ module Epuber
164
163
  attrs['media-type'] = mime_type_for(file)
165
164
 
166
165
  properties = file.properties
167
- if properties.length > 0 && @target.epub_version >= 3
166
+ if properties.length.positive? && @target.epub_version >= 3
168
167
  pretty_properties = properties.to_a.map { |property| PROPERTIES_MAP[property] }.join(' ')
169
168
  attrs['properties'] = pretty_properties
170
169
  end
@@ -218,7 +217,7 @@ module Epuber
218
217
  end
219
218
  end
220
219
 
221
- # @param toc_items [Array<Epuber::Book::TocItem>]
220
+ # @param [Array<Epuber::Book::TocItem>] toc_items
222
221
  #
223
222
  # @return nil
224
223
  #
@@ -228,7 +227,7 @@ module Epuber
228
227
  end
229
228
  end
230
229
 
231
- # @param toc_item [Epuber::Book::TocItem]
230
+ # @param [Epuber::Book::TocItem] toc_item
232
231
  #
233
232
  # @return nil
234
233
  #
@@ -252,7 +251,7 @@ module Epuber
252
251
 
253
252
  # Creates id from file path
254
253
  #
255
- # @param path [String]
254
+ # @param [String] path
256
255
  #
257
256
  # @return [String]
258
257
  #
@@ -264,7 +263,7 @@ module Epuber
264
263
 
265
264
  # Creates proper mime-type for file
266
265
  #
267
- # @param file [Epuber::Compiler::FileTypes::AbstractFile | String]
266
+ # @param [Epuber::Compiler::FileTypes::AbstractFile | String] file
268
267
  #
269
268
  # @return [String]
270
269
  #
@@ -4,9 +4,7 @@ module Epuber
4
4
  class Compiler
5
5
  class Problem
6
6
  class Location
7
- attr_reader :line
8
- attr_reader :column
9
- attr_reader :length
7
+ attr_reader :line, :column, :length
10
8
 
11
9
  def initialize(line, column, length = nil)
12
10
  @line = line
@@ -15,20 +13,14 @@ module Epuber
15
13
  end
16
14
  end
17
15
 
18
- attr_reader :level
19
- attr_reader :message
20
- attr_reader :source
21
- attr_reader :location
22
- attr_reader :file_path
16
+ attr_reader :level, :message, :source, :location, :file_path
23
17
 
24
18
  def initialize(level, message, source, location: nil, line: nil, column: nil, length: nil, file_path: nil)
25
19
  @level = level
26
20
  @message = message
27
21
  @source = source
28
22
  @location = location
29
- if @location.nil? && line && column
30
- @location = Location.new(line, column, length)
31
- end
23
+ @location = Location.new(line, column, length) if @location.nil? && line && column
32
24
 
33
25
  @file_path = file_path
34
26
  end
@@ -40,7 +32,7 @@ module Epuber
40
32
  # @return [String]
41
33
  #
42
34
  def self.caret_symbol(indent)
43
- ' ' * indent + '^'
35
+ "#{' ' * indent}^"
44
36
  end
45
37
 
46
38
  # Formats caret symbols for indent and length
@@ -53,7 +45,7 @@ module Epuber
53
45
  def self.caret_symbols(indent, length)
54
46
  start_sign = caret_symbol(indent)
55
47
  end_sign = if length > 1
56
- caret_symbol(length-2)
48
+ caret_symbol(length - 2)
57
49
  else
58
50
  ''
59
51
  end
@@ -74,10 +66,11 @@ module Epuber
74
66
  lines = text.split("\n")
75
67
 
76
68
  line = lines[line_index] || ''
77
- matched_text = line[column_index ... column_index + location.length] || ''
69
+ matched_text = line[column_index...column_index + location.length] || ''
78
70
 
79
- pre = (lines[0 ... line_index] + [line[0 ... column_index]]).join("\n")
80
- post = ([line[column_index + location.length .. line.length]] + (lines[location.line .. lines.count] || [])).join("\n")
71
+ pre = (lines[0...line_index] + [line[0...column_index]]).join("\n")
72
+ post = ([line[column_index + location.length..line.length]] + (lines[location.line..lines.count] || []))
73
+ .join("\n")
81
74
 
82
75
  [pre, matched_text, post]
83
76
  end
@@ -89,9 +82,7 @@ module Epuber
89
82
  post_line = post.split("\n").first || ''
90
83
 
91
84
  pre = match_pre_line = pre_line
92
- if remove_tabs(match_pre_line).length > 100
93
- pre = "#{match_pre_line.first(20)}...#{match_pre_line.last(30)}"
94
- end
85
+ pre = "#{match_pre_line.first(20)}...#{match_pre_line.last(30)}" if remove_tabs(match_pre_line).length > 100
95
86
 
96
87
  pre = remove_tabs(pre)
97
88
 
@@ -114,8 +105,8 @@ module Epuber
114
105
 
115
106
  [
116
107
  "#{@file_path}:#{line} column: #{column} --- #{@message}",
117
- ' ' + pre + colored_match_text + post,
118
- ' ' + pointers,
108
+ " #{pre}#{colored_match_text}#{post}",
109
+ " #{pointers}",
119
110
  ].join("\n")
120
111
  end
121
112
  end