fb2rb 0.1.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +5 -0
- data/CHANGELOG.adoc +23 -0
- data/README.adoc +19 -1
- data/fb2rb.gemspec +3 -3
- data/lib/fb2rb.rb +168 -50
- data/lib/fb2rb/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfb4528624a4eb3be4782bc3a3affe44cee7a9ba88f2123ae83a0a8cd4791455
|
4
|
+
data.tar.gz: 6221bfe28e99a59b82f87c7957213ad24c1befa6f6b2460173aa56da3fd8f400
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b019fe1a3f27dc0d64e909a5f0655ca154e9c3addc6f38f2ea3716dc7eee19798604e54045d2ef94844ed0f495d33fa5ffa8d6db13a3065182dc7aa30fabd5e0
|
7
|
+
data.tar.gz: c7840ad4f5bb5cc4feb2c878f862c993db3fa842eb3be1013e17b6fb14ea7182e3818a487fb260c1c9a7541f90f0b791fad9afc919cc24eacd2b60d1bfc5fea5
|
data/.github/dependabot.yml
CHANGED
data/CHANGELOG.adoc
CHANGED
@@ -7,6 +7,29 @@
|
|
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.4.0 (2020-11-24) - @slonopotamus
|
11
|
+
|
12
|
+
* add `Book::add_stylesheet` method
|
13
|
+
|
14
|
+
== 0.3.0 (2020-07-27) - @slonopotamus
|
15
|
+
|
16
|
+
* Support reading/writing uncompressed FB2. https://github.com/slonopotamus/fb2rb/issues/5[#5]
|
17
|
+
|
18
|
+
== 0.2.1 (2020-07-24) - @slonopotamus
|
19
|
+
|
20
|
+
* Fix field annotation on `FB2rb::TitleInfo::date`
|
21
|
+
|
22
|
+
== 0.2.0 (2020-07-24) - @slonopotamus
|
23
|
+
|
24
|
+
* Add support for reproducible builds
|
25
|
+
* Remove broken `FB2rb::Book.to_ios`.
|
26
|
+
Use `FB2rb::Book.write` instead.
|
27
|
+
|
28
|
+
== 0.1.1 (2020-07-23) - @slonopotamus
|
29
|
+
|
30
|
+
* Annotate field types
|
31
|
+
* Fix serialization of `<publisher>` in `<document-info>`
|
32
|
+
|
10
33
|
== 0.1.0 (2020-07-23) - @slonopotamus
|
11
34
|
|
12
35
|
* Initial release
|
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.
|
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
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
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.
|
26
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
27
|
-
s.add_development_dependency 'rubocop-rspec', '~> 1.
|
25
|
+
s.add_development_dependency 'rspec', '~> 3.10.0'
|
26
|
+
s.add_development_dependency 'rubocop', '~> 0.93.0'
|
27
|
+
s.add_development_dependency 'rubocop-rspec', '~> 1.44.0'
|
28
28
|
end
|
data/lib/fb2rb.rb
CHANGED
@@ -12,10 +12,14 @@ 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
|
+
# @return [Array<FB2rb::Stylesheet>]
|
16
17
|
attr_accessor(:stylesheets)
|
18
|
+
# @return [FB2rb::Description]
|
17
19
|
attr_accessor(:description)
|
20
|
+
# @return [Array<FB2rb::Body>]
|
18
21
|
attr_accessor(:bodies)
|
22
|
+
# @return [Array<FB2fb::Binary>]
|
19
23
|
attr_accessor(:binaries)
|
20
24
|
|
21
25
|
def initialize(description = Description.new, bodies = [], binaries = [], stylesheets = [])
|
@@ -25,38 +29,65 @@ module FB2rb
|
|
25
29
|
@stylesheets = stylesheets
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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?
|
33
39
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
38
45
|
end
|
39
46
|
end
|
40
|
-
end
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
# Reads existing uncompressed FB2 file from an IO object, and creates new Book object.
|
49
|
+
# @return [FB2rb::Book]
|
50
|
+
def read_uncompressed(filename_or_io)
|
51
|
+
xml = read_xml(filename_or_io)
|
52
|
+
fb2_prefix = ns_prefix(FB2rb::FB2_NAMESPACE, xml.namespaces)
|
53
|
+
xlink_prefix = ns_prefix(FB2rb::XLINK_NAMESPACE, xml.namespaces)
|
54
|
+
parse(xml, fb2_prefix, xlink_prefix)
|
55
|
+
end
|
46
56
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
def ns_prefix(namespace, namespaces)
|
58
|
+
prefix = namespaces.key(namespace)
|
59
|
+
prefix.nil? ? nil : prefix.sub(/^xmlns:/, '')
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# @return [FB2rb::Book]
|
65
|
+
def parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/MethodLength
|
66
|
+
Book.new(
|
67
|
+
Description.parse(
|
68
|
+
xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:description"), fb2_prefix, xlink_prefix
|
69
|
+
),
|
70
|
+
xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:body").map do |node|
|
71
|
+
Body.parse(node)
|
72
|
+
end,
|
73
|
+
xml.xpath("#{fb2_prefix}:FictionBook/#{fb2_prefix}:binary").map do |node|
|
74
|
+
Binary.parse(node)
|
75
|
+
end,
|
76
|
+
xml.xpath("/#{fb2_prefix}:FictionBook/#{fb2_prefix}:stylesheet").map do |node|
|
77
|
+
Stylesheet.parse(node)
|
78
|
+
end
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def read_xml(filename_or_io)
|
83
|
+
if filename_or_io.respond_to? :read
|
84
|
+
Nokogiri::XML::Document.parse(filename_or_io)
|
85
|
+
else
|
86
|
+
File.open(filename_or_io, 'rb') do |io|
|
87
|
+
return Nokogiri::XML::Document.parse(io)
|
88
|
+
end
|
58
89
|
end
|
59
|
-
|
90
|
+
end
|
60
91
|
end
|
61
92
|
|
62
93
|
def to_xml(xml) # rubocop:disable Metrics/MethodLength
|
@@ -85,15 +116,18 @@ module FB2rb
|
|
85
116
|
end
|
86
117
|
end
|
87
118
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
119
|
+
def add_stylesheet(content_type, filename_or_io)
|
120
|
+
if filename_or_io.respond_to?(:read)
|
121
|
+
add_stylesheet_io(content_type, filename_or_io)
|
122
|
+
else
|
123
|
+
File.open(filename_or_io, 'r') do |io|
|
124
|
+
add_stylesheet_io(content_type, io)
|
125
|
+
end
|
92
126
|
end
|
93
127
|
end
|
94
128
|
|
95
|
-
# Writes FB2 to file or IO object. If file exists, it will be overwritten.
|
96
|
-
def
|
129
|
+
# Writes compressed FB2 to file or IO object. If file exists, it will be overwritten.
|
130
|
+
def write_compressed(filename_or_io = StringIO.new)
|
97
131
|
if filename_or_io.respond_to?(:write)
|
98
132
|
Zip::OutputStream.write_buffer(filename_or_io) do |zos|
|
99
133
|
write_to_zip(zos)
|
@@ -105,12 +139,34 @@ module FB2rb
|
|
105
139
|
end
|
106
140
|
end
|
107
141
|
|
142
|
+
# Writes FB2 (uncompressed) to file or IO object specified by the argument.
|
143
|
+
def write_uncompressed(filename_or_io = StringIO.new) # rubocop:disable Metrics/MethodLength
|
144
|
+
data = (Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
145
|
+
to_xml(xml)
|
146
|
+
end).to_xml
|
147
|
+
|
148
|
+
if filename_or_io.respond_to?(:write)
|
149
|
+
filename_or_io.write(data)
|
150
|
+
else
|
151
|
+
File.open(filename_or_io, 'wb') do |io|
|
152
|
+
io.write(data)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
filename_or_io
|
156
|
+
end
|
157
|
+
|
108
158
|
private
|
109
159
|
|
110
160
|
def write_to_zip(zos)
|
161
|
+
mod_time = Zip::DOSTime.now
|
162
|
+
unless (tm = description.document_info.date.value).nil?
|
163
|
+
mod_time = Zip::DOSTime.gm(tm.year, tm.month, tm.day)
|
164
|
+
end
|
165
|
+
|
111
166
|
# TODO: entry name
|
112
|
-
|
113
|
-
|
167
|
+
mimetype_entry = Zip::Entry.new(nil, 'book.fb2', nil, nil, nil, nil, nil, nil, mod_time)
|
168
|
+
zos.put_next_entry(mimetype_entry, nil, nil, Zip::Entry::DEFLATED)
|
169
|
+
write_uncompressed(zos)
|
114
170
|
end
|
115
171
|
|
116
172
|
def add_binary_io(name, io, content_type = nil)
|
@@ -120,22 +176,25 @@ module FB2rb
|
|
120
176
|
self
|
121
177
|
end
|
122
178
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
xml = builder.to_xml
|
129
|
-
io.write(xml)
|
179
|
+
def add_stylesheet_io(content_type, io)
|
180
|
+
io.binmode
|
181
|
+
content = io.read
|
182
|
+
@stylesheets << Stylesheet.new(content_type, content)
|
183
|
+
self
|
130
184
|
end
|
131
185
|
end
|
132
186
|
|
133
187
|
# Holds <description> data
|
134
188
|
class Description
|
189
|
+
# @return [FB2rb::TitleInfo]
|
135
190
|
attr_accessor(:title_info)
|
191
|
+
# @return [FB2rb::TitleInfo, nil]
|
136
192
|
attr_accessor(:src_title_info)
|
193
|
+
# @return [FB2rb::DocumentInfo]
|
137
194
|
attr_accessor(:document_info)
|
195
|
+
# @return [FB2rb::PublishInfo, nil]
|
138
196
|
attr_accessor(:publish_info)
|
197
|
+
# @return [Array<FB2rb::CustomInfo>]
|
139
198
|
attr_accessor(:custom_infos)
|
140
199
|
# TODO: <output>
|
141
200
|
|
@@ -151,6 +210,7 @@ module FB2rb
|
|
151
210
|
@custom_infos = custom_infos
|
152
211
|
end
|
153
212
|
|
213
|
+
# @return [FB2rb::Description]
|
154
214
|
def self.parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/MethodLength
|
155
215
|
publish_info_xml = xml.at("./#{fb2_prefix}:publish-info")
|
156
216
|
src_title_info_xml = xml.at("./#{fb2_prefix}:src-title-info")
|
@@ -180,7 +240,9 @@ module FB2rb
|
|
180
240
|
|
181
241
|
# Holds <stylesheet> data
|
182
242
|
class Stylesheet
|
243
|
+
# @return [String]
|
183
244
|
attr_accessor(:type)
|
245
|
+
# @return [String, nil]
|
184
246
|
attr_accessor(:content)
|
185
247
|
|
186
248
|
def initialize(type = '', content = nil)
|
@@ -201,7 +263,9 @@ module FB2rb
|
|
201
263
|
|
202
264
|
# Holds <custom-info> data
|
203
265
|
class CustomInfo
|
266
|
+
# @return [String]
|
204
267
|
attr_accessor(:info_type)
|
268
|
+
# @return [String, nil]
|
205
269
|
attr_accessor(:content)
|
206
270
|
|
207
271
|
def initialize(info_type = '', content = nil)
|
@@ -209,6 +273,7 @@ module FB2rb
|
|
209
273
|
@content = content
|
210
274
|
end
|
211
275
|
|
276
|
+
# @return [FB2rb::CustomInfo]
|
212
277
|
def self.parse(xml)
|
213
278
|
CustomInfo.new(xml['info-type'], xml.text)
|
214
279
|
end
|
@@ -222,11 +287,17 @@ module FB2rb
|
|
222
287
|
|
223
288
|
# Holds <publish-info> data
|
224
289
|
class PublishInfo
|
290
|
+
# @return [String, nil]
|
225
291
|
attr_accessor(:book_name)
|
292
|
+
# @return [String, nil]
|
226
293
|
attr_accessor(:publisher)
|
294
|
+
# @return [String, nil]
|
227
295
|
attr_accessor(:city)
|
296
|
+
# @return [String, nil]
|
228
297
|
attr_accessor(:year)
|
298
|
+
# @return [String, nil]
|
229
299
|
attr_accessor(:isbn)
|
300
|
+
# @return [Array<FB2RB::Sequence>]
|
230
301
|
attr_accessor(:sequences)
|
231
302
|
|
232
303
|
def initialize(book_name = nil, # rubocop:disable Metrics/ParameterLists
|
@@ -243,6 +314,7 @@ module FB2rb
|
|
243
314
|
@sequences = sequences
|
244
315
|
end
|
245
316
|
|
317
|
+
# @return [FB2RB::PublishInfo]
|
246
318
|
def self.parse(xml, fb2_prefix)
|
247
319
|
PublishInfo.new(
|
248
320
|
xml.at("./#{fb2_prefix}:book-name/text()")&.text,
|
@@ -272,14 +344,23 @@ module FB2rb
|
|
272
344
|
|
273
345
|
# Holds <document-info> data
|
274
346
|
class DocumentInfo
|
347
|
+
# @return [Array<FB2rb::Author>]
|
275
348
|
attr_accessor(:authors)
|
349
|
+
# @return [String, nil]
|
276
350
|
attr_accessor(:program_used)
|
351
|
+
# @return [FB2rb::FB2Date]
|
277
352
|
attr_accessor(:date)
|
353
|
+
# @return [Array<String>]
|
278
354
|
attr_accessor(:src_urls)
|
355
|
+
# @return [String, nil]
|
279
356
|
attr_accessor(:src_ocr)
|
357
|
+
# @return [String]
|
280
358
|
attr_accessor(:id)
|
359
|
+
# @return [String]
|
281
360
|
attr_accessor(:version)
|
361
|
+
# @return [String, nil]
|
282
362
|
attr_accessor(:history)
|
363
|
+
# @return [Array<String>]
|
283
364
|
attr_accessor(:publishers)
|
284
365
|
|
285
366
|
def initialize(authors = [], # rubocop:disable Metrics/ParameterLists
|
@@ -302,7 +383,8 @@ module FB2rb
|
|
302
383
|
@publishers = publishers
|
303
384
|
end
|
304
385
|
|
305
|
-
|
386
|
+
# @return [FB2rb::DocumentInfo]
|
387
|
+
def self.parse(xml, fb2_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
306
388
|
date = xml.at("./#{fb2_prefix}:date")
|
307
389
|
DocumentInfo.new(
|
308
390
|
xml.xpath("./#{fb2_prefix}:author").map do |node|
|
@@ -314,11 +396,12 @@ module FB2rb
|
|
314
396
|
xml.at("./#{fb2_prefix}:src-ocr")&.text,
|
315
397
|
xml.at("./#{fb2_prefix}:id").text,
|
316
398
|
xml.at("./#{fb2_prefix}:version")&.text,
|
317
|
-
xml.at("./#{fb2_prefix}:history")&.children&.to_s&.strip
|
399
|
+
xml.at("./#{fb2_prefix}:history")&.children&.to_s&.strip,
|
400
|
+
xml.xpath("./#{fb2_prefix}:publisher").map(&:text)
|
318
401
|
)
|
319
402
|
end
|
320
403
|
|
321
|
-
def to_xml(xml) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
404
|
+
def to_xml(xml) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
322
405
|
xml.send(:'document-info') do
|
323
406
|
@authors.each do |author|
|
324
407
|
author.to_xml(xml, 'author')
|
@@ -336,22 +419,36 @@ module FB2rb
|
|
336
419
|
xml << @history
|
337
420
|
end
|
338
421
|
end
|
422
|
+
@publishers.each do |publisher|
|
423
|
+
xml.publisher(publisher)
|
424
|
+
end
|
339
425
|
end
|
340
426
|
end
|
341
427
|
end
|
342
428
|
|
343
429
|
# Holds <title-info>/<src-title-info> data
|
344
430
|
class TitleInfo
|
431
|
+
# @return [Array<String>]
|
345
432
|
attr_accessor(:genres)
|
433
|
+
# @return [Array<FB2rb::Author>]
|
346
434
|
attr_accessor(:authors)
|
435
|
+
# @return [String]
|
347
436
|
attr_accessor(:book_title)
|
437
|
+
# @return [String, nil]
|
348
438
|
attr_accessor(:annotation)
|
439
|
+
# @return [Array<String>]
|
349
440
|
attr_accessor(:keywords)
|
441
|
+
# @return [FB2rb::Date, nil]
|
350
442
|
attr_accessor(:date)
|
443
|
+
# @return [FB2rb::Coverpage, nil]
|
351
444
|
attr_accessor(:coverpage)
|
445
|
+
# @return [String]
|
352
446
|
attr_accessor(:lang)
|
447
|
+
# @return [String, nil]
|
353
448
|
attr_accessor(:src_lang)
|
449
|
+
# @return [Array<FB2rb::Author>]
|
354
450
|
attr_accessor(:translators)
|
451
|
+
# @return [Array<FB2rb::Sequence>]
|
355
452
|
attr_accessor(:sequences)
|
356
453
|
|
357
454
|
def initialize(genres = [], # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
@@ -378,7 +475,8 @@ module FB2rb
|
|
378
475
|
@sequences = sequences
|
379
476
|
end
|
380
477
|
|
381
|
-
|
478
|
+
# @return [FB2rb::TitleInfo]
|
479
|
+
def self.parse(xml, fb2_prefix, xlink_prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
382
480
|
date = xml.at("./#{fb2_prefix}:date")
|
383
481
|
coverpage = xml.at("./#{fb2_prefix}:coverpage")
|
384
482
|
TitleInfo.new(
|
@@ -402,7 +500,7 @@ module FB2rb
|
|
402
500
|
)
|
403
501
|
end
|
404
502
|
|
405
|
-
def to_xml(xml, tag) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
503
|
+
def to_xml(xml, tag) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
406
504
|
xml.send(tag) do
|
407
505
|
genres.each do |genre|
|
408
506
|
xml.genre(genre)
|
@@ -433,6 +531,7 @@ module FB2rb
|
|
433
531
|
|
434
532
|
# Holds <coverpage> data
|
435
533
|
class Coverpage
|
534
|
+
# @return [Array<String>]
|
436
535
|
attr_accessor(:images)
|
437
536
|
|
438
537
|
def initialize(images = [])
|
@@ -456,7 +555,9 @@ module FB2rb
|
|
456
555
|
|
457
556
|
# Holds <date> data
|
458
557
|
class FB2Date
|
558
|
+
# @return [String]
|
459
559
|
attr_accessor(:display_value)
|
560
|
+
# @return [Date, nil]
|
460
561
|
attr_accessor(:value)
|
461
562
|
|
462
563
|
def initialize(display_value = '', value = nil)
|
@@ -481,7 +582,9 @@ module FB2rb
|
|
481
582
|
|
482
583
|
# Holds <sequence> data
|
483
584
|
class Sequence
|
585
|
+
# @return [String]
|
484
586
|
attr_accessor(:name)
|
587
|
+
# @return [Integer, nil]
|
485
588
|
attr_accessor(:number)
|
486
589
|
|
487
590
|
def initialize(name = '', number = nil)
|
@@ -489,6 +592,7 @@ module FB2rb
|
|
489
592
|
@number = number
|
490
593
|
end
|
491
594
|
|
595
|
+
# @return [FB2rb::Sequence]
|
492
596
|
def self.parse(xml)
|
493
597
|
Sequence.new(xml['name'], xml['number']&.to_i)
|
494
598
|
end
|
@@ -502,12 +606,19 @@ module FB2rb
|
|
502
606
|
|
503
607
|
# Holds <author> data
|
504
608
|
class Author
|
609
|
+
# @return [String, nil]
|
505
610
|
attr_accessor(:first_name)
|
611
|
+
# @return [String, nil]
|
506
612
|
attr_accessor(:middle_name)
|
613
|
+
# @return [String, nil]
|
507
614
|
attr_accessor(:last_name)
|
615
|
+
# @return [String, nil]
|
508
616
|
attr_accessor(:nickname)
|
617
|
+
# @return [Array<String>]
|
509
618
|
attr_accessor(:home_pages)
|
619
|
+
# @return [Array<String>]
|
510
620
|
attr_accessor(:emails)
|
621
|
+
# @return [String, nil]
|
511
622
|
attr_accessor(:id)
|
512
623
|
|
513
624
|
def initialize(first_name = nil, # rubocop:disable Metrics/ParameterLists
|
@@ -526,6 +637,7 @@ module FB2rb
|
|
526
637
|
@id = id
|
527
638
|
end
|
528
639
|
|
640
|
+
# @return [FB2rb::Author]
|
529
641
|
def self.parse(xml, fb2_prefix) # rubocop:disable Metrics/CyclomaticComplexity
|
530
642
|
Author.new(
|
531
643
|
xml.at("./#{fb2_prefix}:first-name/text()")&.text,
|
@@ -538,7 +650,7 @@ module FB2rb
|
|
538
650
|
)
|
539
651
|
end
|
540
652
|
|
541
|
-
def to_xml(xml, tag) # rubocop:disable Metrics/
|
653
|
+
def to_xml(xml, tag) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
542
654
|
xml.send(tag) do
|
543
655
|
xml.send('first-name', @first_name) unless @first_name.nil?
|
544
656
|
xml.send('middle-name', @middle_name) unless @middle_name.nil?
|
@@ -557,7 +669,9 @@ module FB2rb
|
|
557
669
|
|
558
670
|
# Holds <body> data
|
559
671
|
class Body
|
672
|
+
# @return [String, nil]
|
560
673
|
attr_accessor(:name)
|
674
|
+
# @return [String]
|
561
675
|
attr_accessor(:content)
|
562
676
|
|
563
677
|
def initialize(name = nil, content = '')
|
@@ -565,6 +679,7 @@ module FB2rb
|
|
565
679
|
@content = content
|
566
680
|
end
|
567
681
|
|
682
|
+
# @return [FB2rb::Body]
|
568
683
|
def self.parse(xml)
|
569
684
|
Body.new(
|
570
685
|
xml['name'],
|
@@ -584,12 +699,15 @@ module FB2rb
|
|
584
699
|
|
585
700
|
# Holds data of a single binary within FB2 file
|
586
701
|
class Binary
|
702
|
+
# @return [String]
|
587
703
|
attr_accessor(:id)
|
704
|
+
# @return [String]
|
588
705
|
attr_accessor(:content)
|
706
|
+
# @return [String, nil]
|
589
707
|
attr_accessor(:content_type)
|
590
708
|
|
591
|
-
def initialize(
|
592
|
-
@id =
|
709
|
+
def initialize(id, content, content_type = nil)
|
710
|
+
@id = id
|
593
711
|
@content = content
|
594
712
|
@content_type = content_type
|
595
713
|
end
|
data/lib/fb2rb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fb2rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.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-
|
11
|
+
date: 2020-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -58,42 +58,42 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.
|
61
|
+
version: 3.10.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.
|
68
|
+
version: 3.10.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rubocop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.93.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.93.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop-rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.
|
89
|
+
version: 1.44.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.
|
96
|
+
version: 1.44.0
|
97
97
|
description:
|
98
98
|
email:
|
99
99
|
- marat@slonopotamus.org
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
requirements: []
|
142
|
-
rubygems_version: 3.1.
|
142
|
+
rubygems_version: 3.1.4
|
143
143
|
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: Fiction Book 2 parser/generator library
|