fb2rb 0.2.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5f6fdeb1a2fe779953477c9eca2e0213dc057d2b4efc3728256085874a1f129
4
- data.tar.gz: c298f3cbdb346f83519741dde2f6ac1b572d21cc5593a4a3a670279a79b2dbe1
3
+ metadata.gz: 49116036688f7932770da3cfd236c4d9d94ec45a2027983b2681d164c7ceea46
4
+ data.tar.gz: de234462849464702062f4da8c8a60b0b42fbc32e699de33ad392f594ddb3e9c
5
5
  SHA512:
6
- metadata.gz: b82bc9063e645d85b79bb123ab59e8f5639873ce6ac3edc65330c353a5ef076c25270584539da096c85043d77e1b0690cb774e700b2d91ab699fff3612cdad69
7
- data.tar.gz: ed5787ea4d920ab9520b21a868d282e8dcbbde2ff9e35747d62a93521135d51f4169f2859977184899f689db65a2a06b00190f445b668ecf5739289f88b401b2
6
+ metadata.gz: 28a6f93d832c5d1f9927757a1efe21aeba51a68a4551bd79ceb15c99fb87254d32cef69436ff14b0296883c6c5bce882d89d34fc7087685bbb9003b439bedf61
7
+ data.tar.gz: dcad03884beee280cf6b4f64c8911bb70ef42fedb0b501d0a65676f8907c1edfeedd2673b827323464e06af929aba63b077e75608a984506bbbcb3deb529ecb3
@@ -6,3 +6,8 @@ updates:
6
6
  directory: "/"
7
7
  schedule:
8
8
  interval: "daily"
9
+
10
+ - package-ecosystem: "github-actions"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "daily"
@@ -9,17 +9,16 @@ jobs:
9
9
  - name: Set up Ruby
10
10
  uses: ruby/setup-ruby@v1
11
11
  with:
12
- ruby-version: 2.7
13
- - name: Build
14
- run: bundle install --jobs 4 --retry 3
12
+ ruby-version: '3.0'
13
+ bundler-cache: true
15
14
  - name: Lint
16
15
  run: bundle exec rake lint
17
16
  test:
18
17
  strategy:
19
18
  matrix:
20
- ruby: [jruby, 2.4, 2.5, 2.6, 2.7]
21
- platform: [ubuntu-latest, macos-latest, windows-latest]
22
- runs-on: ${{ matrix.platform }}
19
+ ruby: ['jruby', '2.4', '2.5', '2.6', '2.7', '3.0']
20
+ os: [ubuntu-latest, macos-latest, windows-latest]
21
+ runs-on: ${{ matrix.os }}
23
22
  steps:
24
23
  - name: Checkout
25
24
  uses: actions/checkout@v2
@@ -27,7 +26,6 @@ jobs:
27
26
  uses: ruby/setup-ruby@v1
28
27
  with:
29
28
  ruby-version: ${{ matrix.ruby }}
30
- - name: Build
31
- run: bundle install --jobs 4 --retry 3
29
+ bundler-cache: true
32
30
  - name: Test
33
31
  run: bundle exec rake spec
@@ -11,14 +11,8 @@ jobs:
11
11
  - name: Set up Ruby
12
12
  uses: ruby/setup-ruby@v1
13
13
  with:
14
- ruby-version: 2.7
14
+ ruby-version: '3.0'
15
15
  - name: Publish to RubyGems.org
16
- run: |
17
- mkdir -p $HOME/.gem
18
- touch $HOME/.gem/credentials
19
- chmod 0600 $HOME/.gem/credentials
20
- printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > $HOME/.gem/credentials
21
- gem build *.gemspec
22
- gem push *.gem
23
- env:
24
- RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
16
+ uses: dawidd6/action-publish-gem@v1
17
+ with:
18
+ api_key: ${{ secrets.RUBYGEMS_API_KEY }}
data/CHANGELOG.adoc CHANGED
@@ -7,6 +7,27 @@
7
7
  This document provides a high-level view of the changes to the {project-name} by release.
8
8
  For a detailed view of what has changed, refer to the {uri-project}/commits/master[commit history] on GitHub.
9
9
 
10
+ == 0.6.0 (2021-02-14) @slonopotamus
11
+
12
+ * Allow Nokogiri 1.11
13
+
14
+ == 0.5.0 (2020-12-07) - @slonopotamus
15
+
16
+ * return `nil` from `FB2rb::Book.read_compressed` for empty ZIP files
17
+ * **breaking change**: switch to named parameters instead of optional
18
+
19
+ == 0.4.0 (2020-11-24) - @slonopotamus
20
+
21
+ * add `Book::add_stylesheet` method
22
+
23
+ == 0.3.0 (2020-07-27) - @slonopotamus
24
+
25
+ * Support reading/writing uncompressed FB2. https://github.com/slonopotamus/fb2rb/issues/5[#5]
26
+
27
+ == 0.2.1 (2020-07-24) - @slonopotamus
28
+
29
+ * Fix field annotation on `FB2rb::TitleInfo::date`
30
+
10
31
  == 0.2.0 (2020-07-24) - @slonopotamus
11
32
 
12
33
  * Add support for reproducible builds
data/README.adoc CHANGED
@@ -37,6 +37,8 @@ $ gem install fb2rb
37
37
 
38
38
  == Usage
39
39
 
40
+ You can create FB2 book in memory and write it to file:
41
+
40
42
  [source,ruby]
41
43
  ----
42
44
  require 'fb2rb'
@@ -47,7 +49,23 @@ book.description.title_info.book_title = 'Book title'
47
49
  body = FB2rb::Body.new(nil, '<p>Book text</p>')
48
50
  book.bodies << body
49
51
 
50
- book.write('/path/to/book.fb2.zip')
52
+ book.write_compressed('/path/to/book.fb2.zip')
53
+ # or
54
+ book.write_uncompressed('/path/to/book.fb2')
55
+ ----
56
+
57
+ Also, you can read existing FB2 file:
58
+
59
+ [source,ruby]
60
+ ----
61
+ require 'fb2rb'
62
+
63
+ book = FB2rb::Book.read_compressed('/path/to/book.fb2.zip')
64
+ # or
65
+ book = FB2rb::Book.read_uncompressed('/path/to/book.fb2')
66
+
67
+ puts book.description.title_info.book_title
68
+ puts book.bodies[0].content
51
69
  ----
52
70
 
53
71
  == Development
data/fb2rb.gemspec CHANGED
@@ -18,11 +18,12 @@ Gem::Specification.new do |s|
18
18
  end
19
19
  s.require_paths = ['lib']
20
20
 
21
- s.add_runtime_dependency 'nokogiri', '~> 1.10.0'
21
+ s.add_runtime_dependency 'nokogiri', '>= 1.10', '< 1.12'
22
22
  s.add_runtime_dependency 'rubyzip', '~> 2.3.0'
23
23
 
24
24
  s.add_development_dependency 'rake', '~> 13.0.0'
25
- s.add_development_dependency 'rspec', '~> 3.9.0'
26
- s.add_development_dependency 'rubocop', '~> 0.88.0'
27
- s.add_development_dependency 'rubocop-rspec', '~> 1.42.0'
25
+ s.add_development_dependency 'rspec', '~> 3.10.0'
26
+ s.add_development_dependency 'rubocop', '~> 1.9.0'
27
+ s.add_development_dependency 'rubocop-rake', '~> 0.5.0'
28
+ s.add_development_dependency 'rubocop-rspec', '~> 2.2.0'
28
29
  end
data/lib/fb2rb.rb CHANGED
@@ -12,7 +12,7 @@ module FB2rb
12
12
  XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'
13
13
 
14
14
  # Holds data of a single FB2 file
15
- class Book
15
+ class Book # rubocop:disable Metrics/ClassLength
16
16
  # @return [Array<FB2rb::Stylesheet>]
17
17
  attr_accessor(:stylesheets)
18
18
  # @return [FB2rb::Description]
@@ -22,47 +22,73 @@ module FB2rb
22
22
  # @return [Array<FB2fb::Binary>]
23
23
  attr_accessor(:binaries)
24
24
 
25
- def initialize(description = Description.new, bodies = [], binaries = [], stylesheets = [])
25
+ def initialize(description: Description.new, bodies: [], binaries: [], stylesheets: [])
26
26
  @binaries = binaries
27
27
  @bodies = bodies
28
28
  @description = description
29
29
  @stylesheets = stylesheets
30
30
  end
31
31
 
32
- # Reads existing FB2 file from an IO object, and creates new Book object.
33
- # @return [FB2rb::Book]
34
- def self.read(filename_or_io)
35
- Zip::InputStream.open(filename_or_io) do |zis|
36
- while (entry = zis.get_next_entry)
37
- next if entry.directory?
32
+ class << self
33
+ # Reads existing compressed FB2 file from an IO object, and creates new Book object.
34
+ # @return [FB2rb::Book, nil]
35
+ def read_compressed(filename_or_io)
36
+ Zip::InputStream.open(filename_or_io) do |zis|
37
+ while (entry = zis.get_next_entry)
38
+ next if entry.directory?
38
39
 
39
- xml = Nokogiri::XML::Document.parse(zis)
40
- fb2_prefix = ns_prefix(FB2rb::FB2_NAMESPACE, xml.namespaces)
41
- xlink_prefix = ns_prefix(FB2rb::XLINK_NAMESPACE, xml.namespaces)
42
- return parse(xml, fb2_prefix, xlink_prefix)
40
+ xml = Nokogiri::XML::Document.parse(zis)
41
+ fb2_prefix = ns_prefix(FB2rb::FB2_NAMESPACE, xml.namespaces)
42
+ xlink_prefix = ns_prefix(FB2rb::XLINK_NAMESPACE, xml.namespaces)
43
+ return parse(xml, fb2_prefix, xlink_prefix)
44
+ end
43
45
  end
46
+ nil
44
47
  end
45
- end
46
48
 
47
- def self.ns_prefix(namespace, namespaces)
48
- prefix = namespaces.key(namespace)
49
- prefix.nil? ? nil : prefix.sub(/^xmlns:/, '')
50
- end
49
+ # Reads existing uncompressed FB2 file from an IO object, and creates new Book object.
50
+ # @return [FB2rb::Book]
51
+ def read_uncompressed(filename_or_io)
52
+ xml = read_xml(filename_or_io)
53
+ fb2_prefix = ns_prefix(FB2rb::FB2_NAMESPACE, xml.namespaces)
54
+ xlink_prefix = ns_prefix(FB2rb::XLINK_NAMESPACE, xml.namespaces)
55
+ parse(xml, fb2_prefix, xlink_prefix)
56
+ end
51
57
 
52
- # @return [FB2rb::Book]
53
- def self.parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/MethodLength
54
- Book.new(
55
- Description.parse(xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:description"), fb2_prefix, xlink_prefix),
56
- xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:body").map do |node|
57
- Body.parse(node)
58
- end,
59
- xml.xpath("#{fb2_prefix}:FictionBook/#{fb2_prefix}:binary").map do |node|
60
- Binary.parse(node)
61
- end,
62
- xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:stylesheet").map do |node|
63
- Stylesheet.parse(node)
58
+ def ns_prefix(namespace, namespaces)
59
+ prefix = namespaces.key(namespace)
60
+ prefix.nil? ? nil : prefix.sub(/^xmlns:/, '')
61
+ end
62
+
63
+ private
64
+
65
+ # @return [FB2rb::Book]
66
+ def parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/MethodLength
67
+ Book.new(
68
+ description: Description.parse(
69
+ xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:description"), fb2_prefix, xlink_prefix
70
+ ),
71
+ bodies: xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:body").map do |node|
72
+ Body.parse(node)
73
+ end,
74
+ binaries: xml.xpath("#{fb2_prefix}:FictionBook/#{fb2_prefix}:binary").map do |node|
75
+ Binary.parse(node)
76
+ end,
77
+ stylesheets: xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:stylesheet").map do |node|
78
+ Stylesheet.parse(node)
79
+ end
80
+ )
81
+ end
82
+
83
+ def read_xml(filename_or_io)
84
+ if filename_or_io.respond_to? :read
85
+ Nokogiri::XML::Document.parse(filename_or_io)
86
+ else
87
+ File.open(filename_or_io, 'rb') do |io|
88
+ return Nokogiri::XML::Document.parse(io)
89
+ end
64
90
  end
65
- )
91
+ end
66
92
  end
67
93
 
68
94
  def to_xml(xml) # rubocop:disable Metrics/MethodLength
@@ -81,18 +107,28 @@ module FB2rb
81
107
  end
82
108
  end
83
109
 
84
- def add_binary(name, filename_or_io, content_type = nil)
110
+ def add_binary(id, filename_or_io, content_type = nil)
111
+ if filename_or_io.respond_to?(:read)
112
+ add_binary_io id, filename_or_io, content_type
113
+ else
114
+ File.open(filename_or_io, 'r') do |io|
115
+ add_binary_io id, io, content_type
116
+ end
117
+ end
118
+ end
119
+
120
+ def add_stylesheet(content_type, filename_or_io)
85
121
  if filename_or_io.respond_to?(:read)
86
- add_binary_io name, filename_or_io, content_type
122
+ add_stylesheet_io(content_type, filename_or_io)
87
123
  else
88
124
  File.open(filename_or_io, 'r') do |io|
89
- add_binary_io name, io, content_type
125
+ add_stylesheet_io(content_type, io)
90
126
  end
91
127
  end
92
128
  end
93
129
 
94
- # Writes FB2 to file or IO object. If file exists, it will be overwritten.
95
- def write(filename_or_io = StringIO.new)
130
+ # Writes compressed FB2 to file or IO object. If file exists, it will be overwritten.
131
+ def write_compressed(filename_or_io = StringIO.new)
96
132
  if filename_or_io.respond_to?(:write)
97
133
  Zip::OutputStream.write_buffer(filename_or_io) do |zos|
98
134
  write_to_zip(zos)
@@ -104,6 +140,22 @@ module FB2rb
104
140
  end
105
141
  end
106
142
 
143
+ # Writes FB2 (uncompressed) to file or IO object specified by the argument.
144
+ def write_uncompressed(filename_or_io = StringIO.new) # rubocop:disable Metrics/MethodLength
145
+ data = (Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
146
+ to_xml(xml)
147
+ end).to_xml
148
+
149
+ if filename_or_io.respond_to?(:write)
150
+ filename_or_io.write(data)
151
+ else
152
+ File.open(filename_or_io, 'wb') do |io|
153
+ io.write(data)
154
+ end
155
+ end
156
+ filename_or_io
157
+ end
158
+
107
159
  private
108
160
 
109
161
  def write_to_zip(zos)
@@ -115,23 +167,21 @@ module FB2rb
115
167
  # TODO: entry name
116
168
  mimetype_entry = Zip::Entry.new(nil, 'book.fb2', nil, nil, nil, nil, nil, nil, mod_time)
117
169
  zos.put_next_entry(mimetype_entry, nil, nil, Zip::Entry::DEFLATED)
118
- write_to_stream(zos)
170
+ write_uncompressed(zos)
119
171
  end
120
172
 
121
- def add_binary_io(name, io, content_type = nil)
173
+ def add_binary_io(id, io, content_type = nil)
122
174
  io.binmode
123
175
  content = io.read
124
- @binaries << Binary.new(name, content, content_type)
176
+ @binaries << Binary.new(id: id, content: content, content_type: content_type)
125
177
  self
126
178
  end
127
179
 
128
- # Writes FB2 (uncompressed) to stream specified by the argument.
129
- def write_to_stream(io)
130
- builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
131
- to_xml(xml)
132
- end
133
- xml = builder.to_xml
134
- io.write(xml)
180
+ def add_stylesheet_io(content_type, io)
181
+ io.binmode
182
+ content = io.read
183
+ @stylesheets << Stylesheet.new(content_type: content_type, content: content)
184
+ self
135
185
  end
136
186
  end
137
187
 
@@ -147,13 +197,14 @@ module FB2rb
147
197
  attr_accessor(:publish_info)
148
198
  # @return [Array<FB2rb::CustomInfo>]
149
199
  attr_accessor(:custom_infos)
200
+
150
201
  # TODO: <output>
151
202
 
152
- def initialize(title_info = TitleInfo.new,
153
- document_info = DocumentInfo.new,
154
- publish_info = nil,
155
- src_title_info = nil,
156
- custom_infos = [])
203
+ def initialize(title_info: TitleInfo.new,
204
+ document_info: DocumentInfo.new,
205
+ publish_info: nil,
206
+ src_title_info: nil,
207
+ custom_infos: [])
157
208
  @title_info = title_info
158
209
  @document_info = document_info
159
210
  @publish_info = publish_info
@@ -166,11 +217,11 @@ module FB2rb
166
217
  publish_info_xml = xml.at("./#{fb2_prefix}:publish-info")
167
218
  src_title_info_xml = xml.at("./#{fb2_prefix}:src-title-info")
168
219
  Description.new(
169
- TitleInfo.parse(xml.at("./#{fb2_prefix}:title-info"), fb2_prefix, xlink_prefix),
170
- DocumentInfo.parse(xml.at("./#{fb2_prefix}:document-info"), fb2_prefix),
171
- publish_info_xml.nil? ? nil : PublishInfo.parse(publish_info_xml, fb2_prefix),
172
- src_title_info_xml.nil? ? nil : TitleInfo.parse(src_title_info_xml, fb2_prefix, xlink_prefix),
173
- xml.xpath("./#{fb2_prefix}:custom-info").map do |node|
220
+ title_info: TitleInfo.parse(xml.at("./#{fb2_prefix}:title-info"), fb2_prefix, xlink_prefix),
221
+ document_info: DocumentInfo.parse(xml.at("./#{fb2_prefix}:document-info"), fb2_prefix),
222
+ publish_info: publish_info_xml.nil? ? nil : PublishInfo.parse(publish_info_xml, fb2_prefix),
223
+ src_title_info: src_title_info_xml.nil? ? nil : TitleInfo.parse(src_title_info_xml, fb2_prefix, xlink_prefix),
224
+ custom_infos: xml.xpath("./#{fb2_prefix}:custom-info").map do |node|
174
225
  CustomInfo.parse(node)
175
226
  end
176
227
  )
@@ -192,47 +243,47 @@ module FB2rb
192
243
  # Holds <stylesheet> data
193
244
  class Stylesheet
194
245
  # @return [String]
195
- attr_accessor(:type)
246
+ attr_accessor(:content_type)
196
247
  # @return [String, nil]
197
248
  attr_accessor(:content)
198
249
 
199
- def initialize(type = '', content = nil)
200
- @type = type
250
+ def initialize(content_type: '', content: nil)
251
+ @content_type = content_type
201
252
  @content = content
202
253
  end
203
254
 
204
255
  def self.parse(xml)
205
- Stylesheet.new(xml['type'], xml.text)
256
+ Stylesheet.new(content_type: xml['type'], content: xml.text)
206
257
  end
207
258
 
208
259
  def to_xml(xml)
209
260
  return if @content.nil?
210
261
 
211
- xml.send('stylesheet', @content, 'type' => @type)
262
+ xml.send('stylesheet', @content, 'type' => @content_type)
212
263
  end
213
264
  end
214
265
 
215
266
  # Holds <custom-info> data
216
267
  class CustomInfo
217
268
  # @return [String]
218
- attr_accessor(:info_type)
269
+ attr_accessor(:type)
219
270
  # @return [String, nil]
220
271
  attr_accessor(:content)
221
272
 
222
- def initialize(info_type = '', content = nil)
223
- @info_type = info_type
273
+ def initialize(type: '', content: nil)
274
+ @type = type
224
275
  @content = content
225
276
  end
226
277
 
227
278
  # @return [FB2rb::CustomInfo]
228
279
  def self.parse(xml)
229
- CustomInfo.new(xml['info-type'], xml.text)
280
+ CustomInfo.new(type: xml['info-type'], content: xml.text)
230
281
  end
231
282
 
232
283
  def to_xml(xml)
233
284
  return if @content.nil?
234
285
 
235
- xml.send('custom-info', @content, 'info-type' => @info_type)
286
+ xml.send('custom-info', @content, 'info-type' => @type)
236
287
  end
237
288
  end
238
289
 
@@ -251,12 +302,12 @@ module FB2rb
251
302
  # @return [Array<FB2RB::Sequence>]
252
303
  attr_accessor(:sequences)
253
304
 
254
- def initialize(book_name = nil, # rubocop:disable Metrics/ParameterLists
255
- publisher = nil,
256
- city = nil,
257
- year = nil,
258
- isbn = nil,
259
- sequences = [])
305
+ def initialize(book_name: nil, # rubocop:disable Metrics/ParameterLists
306
+ publisher: nil,
307
+ city: nil,
308
+ year: nil,
309
+ isbn: nil,
310
+ sequences: [])
260
311
  @book_name = book_name
261
312
  @publisher = publisher
262
313
  @city = city
@@ -268,12 +319,12 @@ module FB2rb
268
319
  # @return [FB2RB::PublishInfo]
269
320
  def self.parse(xml, fb2_prefix)
270
321
  PublishInfo.new(
271
- xml.at("./#{fb2_prefix}:book-name/text()")&.text,
272
- xml.at("./#{fb2_prefix}:publisher/text()")&.text,
273
- xml.at("./#{fb2_prefix}:city/text()")&.text,
274
- xml.at("./#{fb2_prefix}:year/text()")&.text,
275
- xml.at("./#{fb2_prefix}:isbn/text()")&.text,
276
- xml.xpath("./#{fb2_prefix}:sequence").map do |node|
322
+ book_name: xml.at("./#{fb2_prefix}:book-name/text()")&.text,
323
+ publisher: xml.at("./#{fb2_prefix}:publisher/text()")&.text,
324
+ city: xml.at("./#{fb2_prefix}:city/text()")&.text,
325
+ year: xml.at("./#{fb2_prefix}:year/text()")&.text,
326
+ isbn: xml.at("./#{fb2_prefix}:isbn/text()")&.text,
327
+ sequences: xml.xpath("./#{fb2_prefix}:sequence").map do |node|
277
328
  Sequence.parse(node)
278
329
  end
279
330
  )
@@ -314,15 +365,15 @@ module FB2rb
314
365
  # @return [Array<String>]
315
366
  attr_accessor(:publishers)
316
367
 
317
- def initialize(authors = [], # rubocop:disable Metrics/ParameterLists
318
- program_used = nil,
319
- date = FB2Date.new,
320
- src_urls = [],
321
- src_ocr = nil,
322
- id = '',
323
- version = '',
324
- history = nil,
325
- publishers = [])
368
+ def initialize(authors: [], # rubocop:disable Metrics/ParameterLists
369
+ program_used: nil,
370
+ date: FB2Date.new,
371
+ src_urls: [],
372
+ src_ocr: nil,
373
+ id: '',
374
+ version: '',
375
+ history: nil,
376
+ publishers: [])
326
377
  @authors = authors
327
378
  @program_used = program_used
328
379
  @date = date
@@ -335,20 +386,20 @@ module FB2rb
335
386
  end
336
387
 
337
388
  # @return [FB2rb::DocumentInfo]
338
- def self.parse(xml, fb2_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
389
+ def self.parse(xml, fb2_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
339
390
  date = xml.at("./#{fb2_prefix}:date")
340
391
  DocumentInfo.new(
341
- xml.xpath("./#{fb2_prefix}:author").map do |node|
392
+ authors: xml.xpath("./#{fb2_prefix}:author").map do |node|
342
393
  Author.parse(node, fb2_prefix)
343
394
  end,
344
- xml.at("./#{fb2_prefix}:program-used")&.text,
345
- date.nil? ? FB2Date.new : FB2Date.parse(date),
346
- xml.xpath("./#{fb2_prefix}:src-url").map(&:text),
347
- xml.at("./#{fb2_prefix}:src-ocr")&.text,
348
- xml.at("./#{fb2_prefix}:id").text,
349
- xml.at("./#{fb2_prefix}:version")&.text,
350
- xml.at("./#{fb2_prefix}:history")&.children&.to_s&.strip,
351
- xml.xpath("./#{fb2_prefix}:publisher").map(&:text)
395
+ program_used: xml.at("./#{fb2_prefix}:program-used")&.text,
396
+ date: date.nil? ? FB2Date.new : FB2Date.parse(date),
397
+ src_urls: xml.xpath("./#{fb2_prefix}:src-url").map(&:text),
398
+ src_ocr: xml.at("./#{fb2_prefix}:src-ocr")&.text,
399
+ id: xml.at("./#{fb2_prefix}:id").text,
400
+ version: xml.at("./#{fb2_prefix}:version")&.text,
401
+ history: xml.at("./#{fb2_prefix}:history")&.children&.to_s&.strip,
402
+ publishers: xml.xpath("./#{fb2_prefix}:publisher").map(&:text)
352
403
  )
353
404
  end
354
405
 
@@ -389,7 +440,7 @@ module FB2rb
389
440
  attr_accessor(:annotation)
390
441
  # @return [Array<String>]
391
442
  attr_accessor(:keywords)
392
- # @return [String, nil]
443
+ # @return [FB2rb::Date, nil]
393
444
  attr_accessor(:date)
394
445
  # @return [FB2rb::Coverpage, nil]
395
446
  attr_accessor(:coverpage)
@@ -402,17 +453,17 @@ module FB2rb
402
453
  # @return [Array<FB2rb::Sequence>]
403
454
  attr_accessor(:sequences)
404
455
 
405
- def initialize(genres = [], # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
406
- authors = [],
407
- book_title = '',
408
- annotation = nil,
409
- keywords = [],
410
- date = nil,
411
- coverpage = nil,
412
- lang = 'en',
413
- src_lang = nil,
414
- translators = [],
415
- sequences = [])
456
+ def initialize(genres: [], # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
457
+ authors: [],
458
+ book_title: '',
459
+ annotation: nil,
460
+ keywords: [],
461
+ date: nil,
462
+ coverpage: nil,
463
+ lang: 'en',
464
+ src_lang: nil,
465
+ translators: [],
466
+ sequences: [])
416
467
  @genres = genres
417
468
  @authors = authors
418
469
  @book_title = book_title
@@ -427,31 +478,31 @@ module FB2rb
427
478
  end
428
479
 
429
480
  # @return [FB2rb::TitleInfo]
430
- def self.parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
481
+ def self.parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
431
482
  date = xml.at("./#{fb2_prefix}:date")
432
483
  coverpage = xml.at("./#{fb2_prefix}:coverpage")
433
484
  TitleInfo.new(
434
- xml.xpath("./#{fb2_prefix}:genre/text()").map(&:text),
435
- xml.xpath("./#{fb2_prefix}:author").map do |node|
485
+ genres: xml.xpath("./#{fb2_prefix}:genre/text()").map(&:text),
486
+ authors: xml.xpath("./#{fb2_prefix}:author").map do |node|
436
487
  Author.parse(node, fb2_prefix)
437
488
  end,
438
- xml.at("./#{fb2_prefix}:book-title/text()")&.text,
439
- xml.at("./#{fb2_prefix}:annotation")&.children.to_s.strip,
440
- xml.at("./#{fb2_prefix}:keywords/text()")&.text&.split(', ') || [],
441
- date.nil? ? nil : FB2Date.parse(date),
442
- coverpage.nil? ? nil : Coverpage.parse(coverpage, fb2_prefix, xlink_prefix),
443
- xml.at("./#{fb2_prefix}:lang/text()").text,
444
- xml.at("./#{fb2_prefix}:src-lang/text()")&.text,
445
- xml.xpath("./#{fb2_prefix}:translator").map do |node|
489
+ book_title: xml.at("./#{fb2_prefix}:book-title/text()")&.text,
490
+ annotation: xml.at("./#{fb2_prefix}:annotation")&.children.to_s.strip,
491
+ keywords: xml.at("./#{fb2_prefix}:keywords/text()")&.text&.split(', ') || [],
492
+ date: date.nil? ? nil : FB2Date.parse(date),
493
+ coverpage: coverpage.nil? ? nil : Coverpage.parse(coverpage, fb2_prefix, xlink_prefix),
494
+ lang: xml.at("./#{fb2_prefix}:lang/text()").text,
495
+ src_lang: xml.at("./#{fb2_prefix}:src-lang/text()")&.text,
496
+ translators: xml.xpath("./#{fb2_prefix}:translator").map do |node|
446
497
  Author.parse(node, fb2_prefix)
447
498
  end,
448
- xml.xpath("./#{fb2_prefix}:sequence").map do |node|
499
+ sequences: xml.xpath("./#{fb2_prefix}:sequence").map do |node|
449
500
  Sequence.parse(node)
450
501
  end
451
502
  )
452
503
  end
453
504
 
454
- def to_xml(xml, tag) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
505
+ def to_xml(xml, tag) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
455
506
  xml.send(tag) do
456
507
  genres.each do |genre|
457
508
  xml.genre(genre)
@@ -485,13 +536,13 @@ module FB2rb
485
536
  # @return [Array<String>]
486
537
  attr_accessor(:images)
487
538
 
488
- def initialize(images = [])
539
+ def initialize(images: [])
489
540
  @images = images
490
541
  end
491
542
 
492
543
  def self.parse(xml, fb2_prefix, xlink_prefix)
493
544
  Coverpage.new(
494
- xml.xpath("./#{fb2_prefix}:image/@#{xlink_prefix}:href").map(&:to_s)
545
+ images: xml.xpath("./#{fb2_prefix}:image/@#{xlink_prefix}:href").map(&:to_s)
495
546
  )
496
547
  end
497
548
 
@@ -511,7 +562,7 @@ module FB2rb
511
562
  # @return [Date, nil]
512
563
  attr_accessor(:value)
513
564
 
514
- def initialize(display_value = '', value = nil)
565
+ def initialize(display_value: '', value: nil)
515
566
  @display_value = display_value
516
567
  @value = value
517
568
  end
@@ -519,8 +570,8 @@ module FB2rb
519
570
  def self.parse(xml)
520
571
  value = xml['value']
521
572
  FB2Date.new(
522
- xml.at('./text()')&.text || '',
523
- value.nil? ? nil : Date.parse(value)
573
+ display_value: xml.at('./text()')&.text || '',
574
+ value: value.nil? ? nil : Date.parse(value)
524
575
  )
525
576
  end
526
577
 
@@ -538,14 +589,14 @@ module FB2rb
538
589
  # @return [Integer, nil]
539
590
  attr_accessor(:number)
540
591
 
541
- def initialize(name = '', number = nil)
592
+ def initialize(name: '', number: nil)
542
593
  @name = name
543
594
  @number = number
544
595
  end
545
596
 
546
597
  # @return [FB2rb::Sequence]
547
598
  def self.parse(xml)
548
- Sequence.new(xml['name'], xml['number']&.to_i)
599
+ Sequence.new(name: xml['name'], number: xml['number']&.to_i)
549
600
  end
550
601
 
551
602
  def to_xml(xml)
@@ -572,13 +623,13 @@ module FB2rb
572
623
  # @return [String, nil]
573
624
  attr_accessor(:id)
574
625
 
575
- def initialize(first_name = nil, # rubocop:disable Metrics/ParameterLists
576
- middle_name = nil,
577
- last_name = nil,
578
- nickname = nil,
579
- home_pages = [],
580
- emails = [],
581
- id = nil)
626
+ def initialize(first_name: nil, # rubocop:disable Metrics/ParameterLists
627
+ middle_name: nil,
628
+ last_name: nil,
629
+ nickname: nil,
630
+ home_pages: [],
631
+ emails: [],
632
+ id: nil)
582
633
  @first_name = first_name
583
634
  @middle_name = middle_name
584
635
  @last_name = last_name
@@ -591,17 +642,17 @@ module FB2rb
591
642
  # @return [FB2rb::Author]
592
643
  def self.parse(xml, fb2_prefix) # rubocop:disable Metrics/CyclomaticComplexity
593
644
  Author.new(
594
- xml.at("./#{fb2_prefix}:first-name/text()")&.text,
595
- xml.at("./#{fb2_prefix}:middle-name/text()")&.text,
596
- xml.at("./#{fb2_prefix}:last-name/text()")&.text,
597
- xml.at("./#{fb2_prefix}:nickname/text()")&.text,
598
- xml.xpath("./#{fb2_prefix}:home-page/text()").map(&:text),
599
- xml.xpath("./#{fb2_prefix}:email/text()").map(&:text),
600
- xml.at("./#{fb2_prefix}:id/text()")&.text
645
+ first_name: xml.at("./#{fb2_prefix}:first-name/text()")&.text,
646
+ middle_name: xml.at("./#{fb2_prefix}:middle-name/text()")&.text,
647
+ last_name: xml.at("./#{fb2_prefix}:last-name/text()")&.text,
648
+ nickname: xml.at("./#{fb2_prefix}:nickname/text()")&.text,
649
+ home_pages: xml.xpath("./#{fb2_prefix}:home-page/text()").map(&:text),
650
+ emails: xml.xpath("./#{fb2_prefix}:email/text()").map(&:text),
651
+ id: xml.at("./#{fb2_prefix}:id/text()")&.text
601
652
  )
602
653
  end
603
654
 
604
- def to_xml(xml, tag) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
655
+ def to_xml(xml, tag) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
605
656
  xml.send(tag) do
606
657
  xml.send('first-name', @first_name) unless @first_name.nil?
607
658
  xml.send('middle-name', @middle_name) unless @middle_name.nil?
@@ -625,7 +676,7 @@ module FB2rb
625
676
  # @return [String]
626
677
  attr_accessor(:content)
627
678
 
628
- def initialize(name = nil, content = '')
679
+ def initialize(name: nil, content: '')
629
680
  @name = name
630
681
  @content = content
631
682
  end
@@ -633,8 +684,8 @@ module FB2rb
633
684
  # @return [FB2rb::Body]
634
685
  def self.parse(xml)
635
686
  Body.new(
636
- xml['name'],
637
- xml.children.to_s.strip
687
+ name: xml['name'],
688
+ content: xml.children.to_s.strip
638
689
  )
639
690
  end
640
691
 
@@ -657,7 +708,7 @@ module FB2rb
657
708
  # @return [String, nil]
658
709
  attr_accessor(:content_type)
659
710
 
660
- def initialize(id, content, content_type = nil)
711
+ def initialize(id: nil, content: ''.b, content_type: nil)
661
712
  @id = id
662
713
  @content = content
663
714
  @content_type = content_type
@@ -665,7 +716,7 @@ module FB2rb
665
716
 
666
717
  def self.parse(xml)
667
718
  decoded = Base64.decode64(xml.text)
668
- Binary.new(xml['id'], decoded, xml['content-type'])
719
+ Binary.new(id: xml['id'], content: decoded, content_type: xml['content-type'])
669
720
  end
670
721
 
671
722
  def to_xml(xml)
data/lib/fb2rb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FB2rb
4
- VERSION = '0.2.0'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fb2rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marat Radchenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-24 00:00:00.000000000 Z
11
+ date: 2021-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: 1.10.0
22
+ version: '1.12'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.10'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: 1.10.0
32
+ version: '1.12'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rubyzip
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -58,42 +64,56 @@ dependencies:
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: 3.9.0
67
+ version: 3.10.0
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: 3.9.0
74
+ version: 3.10.0
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rubocop
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
79
  - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: 0.88.0
81
+ version: 1.9.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 1.9.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop-rake
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.5.0
76
96
  type: :development
77
97
  prerelease: false
78
98
  version_requirements: !ruby/object:Gem::Requirement
79
99
  requirements:
80
100
  - - "~>"
81
101
  - !ruby/object:Gem::Version
82
- version: 0.88.0
102
+ version: 0.5.0
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: rubocop-rspec
85
105
  requirement: !ruby/object:Gem::Requirement
86
106
  requirements:
87
107
  - - "~>"
88
108
  - !ruby/object:Gem::Version
89
- version: 1.42.0
109
+ version: 2.2.0
90
110
  type: :development
91
111
  prerelease: false
92
112
  version_requirements: !ruby/object:Gem::Requirement
93
113
  requirements:
94
114
  - - "~>"
95
115
  - !ruby/object:Gem::Version
96
- version: 1.42.0
116
+ version: 2.2.0
97
117
  description:
98
118
  email:
99
119
  - marat@slonopotamus.org
@@ -139,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
159
  - !ruby/object:Gem::Version
140
160
  version: '0'
141
161
  requirements: []
142
- rubygems_version: 3.1.2
162
+ rubygems_version: 3.2.3
143
163
  signing_key:
144
164
  specification_version: 4
145
165
  summary: Fiction Book 2 parser/generator library