fb2rb 0.2.0 → 0.6.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 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