fb2rb 0.2.1 → 0.3.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: 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