fb2rb 0.2.1 → 0.3.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: 677f97c36f32659a61a02047c4b1a06e6a6bd54ac3b8088b04519268468c5acd
4
- data.tar.gz: e5d0ad29e58cd0a453ae50123d498eee49a02ad92adbccc39b2e914c9851bcab
3
+ metadata.gz: fc31542e10b2b534c4a4ffd960f6155eebee2c06a8fe5d5527739a653a7be68d
4
+ data.tar.gz: 9863b69c7c307de46f4e5c15389c2b9934818c2a0b2bf4f3ee9126e015277b94
5
5
  SHA512:
6
- metadata.gz: 3703897e4512796eeb79533a6103abf3fc2627580845bc145f3f73b6b35d5d5736a769e6f87af53c9881245942077f947c4a8d72fb64d149b3dab38154b9e377
7
- data.tar.gz: fd4b8cdd88fcfb81e2ced29fd06a90878384695040bd3217bb738a078929d6eb1359c968221a273c777827d472c27ee4e3492c6c1471624d825244b06b390462
6
+ metadata.gz: 1366e3268dc0711bc00eeb7936fba94dfd9f6ad29f497eaed56e9ddf4aff188bd5270e1c552ebfe80fefa2053ab5f39f186d1499e19c3b29edfd181ef3f7edba
7
+ data.tar.gz: 7edd5ad64f31355bd5f014855a8e49d2c5264495ef42e144f978ce4e8fc962e7de04b838ead0688a0ef81a64d9b7229f74ade2887b4f758ed78a29ff93b66f01
@@ -7,6 +7,10 @@
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.3.0 (2020-07-27) - @slonopotamus
11
+
12
+ * Support reading/writing uncompressed FB2. https://github.com/slonopotamus/fb2rb/issues/5[#5]
13
+
10
14
  == 0.2.1 (2020-07-24) - @slonopotamus
11
15
 
12
16
  * Fix field annotation on `FB2rb::TitleInfo::date`
@@ -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
@@ -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]
@@ -29,40 +29,65 @@ module FB2rb
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
44
46
  end
45
- end
46
47
 
47
- def self.ns_prefix(namespace, namespaces)
48
- prefix = namespaces.key(namespace)
49
- prefix.nil? ? nil : prefix.sub(/^xmlns:/, '')
50
- end
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
51
56
 
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)
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
64
89
  end
65
- )
90
+ end
66
91
  end
67
92
 
68
93
  def to_xml(xml) # rubocop:disable Metrics/MethodLength
@@ -91,8 +116,8 @@ module FB2rb
91
116
  end
92
117
  end
93
118
 
94
- # Writes FB2 to file or IO object. If file exists, it will be overwritten.
95
- def write(filename_or_io = StringIO.new)
119
+ # Writes compressed FB2 to file or IO object. If file exists, it will be overwritten.
120
+ def write_compressed(filename_or_io = StringIO.new)
96
121
  if filename_or_io.respond_to?(:write)
97
122
  Zip::OutputStream.write_buffer(filename_or_io) do |zos|
98
123
  write_to_zip(zos)
@@ -104,6 +129,22 @@ module FB2rb
104
129
  end
105
130
  end
106
131
 
132
+ # Writes FB2 (uncompressed) to file or IO object specified by the argument.
133
+ def write_uncompressed(filename_or_io = StringIO.new) # rubocop:disable Metrics/MethodLength
134
+ data = (Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
135
+ to_xml(xml)
136
+ end).to_xml
137
+
138
+ if filename_or_io.respond_to?(:write)
139
+ filename_or_io.write(data)
140
+ else
141
+ File.open(filename_or_io, 'wb') do |io|
142
+ io.write(data)
143
+ end
144
+ end
145
+ filename_or_io
146
+ end
147
+
107
148
  private
108
149
 
109
150
  def write_to_zip(zos)
@@ -115,7 +156,7 @@ module FB2rb
115
156
  # TODO: entry name
116
157
  mimetype_entry = Zip::Entry.new(nil, 'book.fb2', nil, nil, nil, nil, nil, nil, mod_time)
117
158
  zos.put_next_entry(mimetype_entry, nil, nil, Zip::Entry::DEFLATED)
118
- write_to_stream(zos)
159
+ write_uncompressed(zos)
119
160
  end
120
161
 
121
162
  def add_binary_io(name, io, content_type = nil)
@@ -124,15 +165,6 @@ module FB2rb
124
165
  @binaries << Binary.new(name, content, content_type)
125
166
  self
126
167
  end
127
-
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)
135
- end
136
168
  end
137
169
 
138
170
  # Holds <description> data
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FB2rb
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
  end
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.2.1
4
+ version: 0.3.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: 2020-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri