asciidoctor-fb2 0.2.0 → 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: 5b60e7a379175a8473e96c61ed95598104689ac84def256f01ec626d850025af
4
- data.tar.gz: 96c60b98e0245a9aa4d61037d538f31b623dfd53e0c24407428c784a2753f9c9
3
+ metadata.gz: 2fe8aeff6fa259f44c96b2adcc9f2f2074e68b918f1dc4ec0d509691b34b67e4
4
+ data.tar.gz: 6ca94abe536faeeb639bea944ac21a90b6cabe6de42ad733fe7879148665441d
5
5
  SHA512:
6
- metadata.gz: 13bc939cf1450190c85b87e51333c6d58f3e2d3b2181be4c9a5af8705dd645900cd00a1290f74f68adfed42ad1570cfc4c6ed8974940b7317e5c524b96824b74
7
- data.tar.gz: 314760eafb08dfda7c44087dab1d7d6a5309ac45f134612a455b84e894d1b8b328beb06d65be37e7e7a7d20de4bc589841a461c3b50c2e666264c8b8ae505ee6
6
+ metadata.gz: b18f5a752a529d7a13e7beb1cc30c097914d2696a39f1bfdb736a748b16ee2fcf32544a6fa6b5166b8611a524411a812acc4530550e366a19210dab66ac3cdd2
7
+ data.tar.gz: 8d6eee70a2a3bbaa328f8f2d9056cf4a25150b0bb6d398323d6ab509cb8a43489171c564492720b21acfda4b52bb0060867d11ad608a76371ba8cbf3565ced2a
@@ -7,6 +7,34 @@
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-11-25) - @slonopotamus
11
+
12
+ * output MIME type for FB2 embedded binary files. https://github.com/slonopotamus/asciidoctor-fb2/issues/19[#19]
13
+ * handle `+image:file[]+` syntax for `+:front-cover-image:+` document attribute. https://github.com/slonopotamus/asciidoctor-fb2/issues/19[#19]
14
+
15
+ == 0.2.4 (2020-11-24) - @slonopotamus
16
+
17
+ * add support for table captions
18
+ * fix images from subfolders not loaded in Calibre
19
+ * add initial CSS support
20
+
21
+ == 0.2.3 (2020-11-24) - @slonopotamus
22
+
23
+ * add support for literal blocks
24
+ * fix crash for `menu` inline macro without submenu. https://github.com/slonopotamus/asciidoctor-fb2/issues/15[#15]
25
+ * add initial support for sidebar
26
+
27
+ == 0.2.2 (2020-11-24) - @slonopotamus
28
+
29
+ * do not crash on inline line break macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/14[#14]
30
+ * add support for verses
31
+ * add support for quotes
32
+
33
+ == 0.2.1 (2020-11-24) - @slonopotamus
34
+
35
+ * add support for `kbd` inline macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/13[#13]
36
+ * add support for `btn` inline macro
37
+
10
38
  == 0.2.0 (2020-11-23) - @slonopotamus
11
39
 
12
40
  * add support for cover image via `+:front-cover-image:+` attribute. https://github.com/slonopotamus/asciidoctor-fb2/issues/3[#3]
@@ -19,11 +19,12 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ['lib']
20
20
 
21
21
  s.add_runtime_dependency 'asciidoctor', '~> 2.0'
22
- s.add_runtime_dependency 'fb2rb', '~> 0.3.0'
22
+ s.add_runtime_dependency 'fb2rb', '~> 0.4.0'
23
+ s.add_runtime_dependency 'mime-types', '~> 3.0'
23
24
 
24
25
  s.add_development_dependency 'asciidoctor-diagram', '~> 2.0'
25
26
  s.add_development_dependency 'rake', '~> 13.0'
26
27
  s.add_development_dependency 'rspec', '~> 3.10.0'
27
- s.add_development_dependency 'rubocop', '~> 0.93.0'
28
- s.add_development_dependency 'rubocop-rspec', '~> 1.44.0'
28
+ s.add_development_dependency 'rubocop', '~> 1.4.0'
29
+ s.add_development_dependency 'rubocop-rspec', '~> 2.0.0'
29
30
  end
@@ -0,0 +1,3 @@
1
+ body {
2
+ text-align: justify
3
+ }
@@ -3,14 +3,18 @@
3
3
  require 'asciidoctor'
4
4
  require 'asciidoctor/converter'
5
5
  require 'fb2rb'
6
+ require 'mime/types'
6
7
 
7
8
  module Asciidoctor
8
9
  module FB2
10
+ DATA_DIR = File.expand_path(File.join(__dir__, '..', 'data'))
11
+
9
12
  # Converts AsciiDoc documents to FB2 e-book formats
10
13
  class Converter < Asciidoctor::Converter::Base # rubocop:disable Metrics/ClassLength
11
14
  include ::Asciidoctor::Writer
12
15
 
13
16
  CSV_DELIMITER_REGEX = /\s*,\s*/.freeze
17
+ IMAGE_ATTRIBUTE_VALUE_RX = /^image:{1,2}(.*?)\[(.*?)\]$/.freeze
14
18
 
15
19
  register_for 'fb2'
16
20
 
@@ -25,6 +29,8 @@ module Asciidoctor
25
29
  # @param node [Asciidoctor::Document]
26
30
  def convert_document(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
27
31
  @book = FB2rb::Book.new
32
+ @book.add_stylesheet('text/css', File.join(DATA_DIR, 'fb2.css'))
33
+
28
34
  document_info = @book.description.document_info
29
35
  title_info = @book.description.title_info
30
36
 
@@ -58,8 +64,9 @@ module Asciidoctor
58
64
  title_info.date = document_info.date = fb2date
59
65
 
60
66
  unless (cover_image = node.attr('front-cover-image')).nil?
67
+ cover_image = Regexp.last_match(1) if cover_image =~ IMAGE_ATTRIBUTE_VALUE_RX
61
68
  cover_image_path = node.image_uri(cover_image)
62
- register_binary(node, cover_image_path)
69
+ register_binary(node, cover_image_path, 'image')
63
70
  title_info.coverpage = FB2rb::Coverpage.new([%(##{cover_image_path})])
64
71
  end
65
72
 
@@ -119,8 +126,47 @@ module Asciidoctor
119
126
  lines * "\n"
120
127
  end
121
128
 
129
+ # @param node [Asciidoctor::Block]
130
+ def convert_quote(node)
131
+ citetitle = node.attr('citetitle')
132
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<subtitle>#{citetitle}</subtitle>)
133
+
134
+ author = node.attr('attribution')
135
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
136
+
137
+ %(<cite>
138
+ #{citetitle_tag}
139
+ <p>#{node.content}</p>
140
+ #{author_tag}
141
+ </cite>)
142
+ end
143
+
144
+ # @param node [Asciidoctor::Block]
145
+ def convert_verse(node)
146
+ body = node.content&.split("\n\n")&.map do |stanza|
147
+ %(<stanza>\n<v>#{stanza.split("\n") * "</v>\n<v>"}</v>\n</stanza>)
148
+ end&.join("\n")
149
+
150
+ citetitle = node.attr('citetitle')
151
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<title>#{citetitle}</title>)
152
+
153
+ author = node.attr('attribution')
154
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
155
+
156
+ %(<poem>
157
+ #{citetitle_tag}
158
+ #{body}
159
+ #{author_tag}
160
+ </poem>)
161
+ end
162
+
122
163
  # @param node [Asciidoctor::Block]
123
164
  def convert_listing(node)
165
+ convert_literal(node)
166
+ end
167
+
168
+ # @param node [Asciidoctor::Block]
169
+ def convert_literal(node)
124
170
  lines = []
125
171
  node.content.split("\n").each do |line|
126
172
  lines << %(<p><code>#{line}</code></p>)
@@ -152,15 +198,30 @@ module Asciidoctor
152
198
  caret = '&#160;<strong>&#8250;</strong> '
153
199
  menu = node.attr('menu')
154
200
  menuitem = node.attr('menuitem')
155
- submenus = node.attr('submenus').join(%(</b>#{caret}<b>))
201
+ submenus = node.attr('submenus') * %(</b>#{caret}<b>)
156
202
 
157
203
  result = %(<strong>#{menu}</strong>)
158
- result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.empty?
159
- result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.empty?
204
+ result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.nil_or_empty?
205
+ result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.nil_or_empty?
160
206
 
161
207
  result
162
208
  end
163
209
 
210
+ # @param node [Asciidoctor::Inline]
211
+ def convert_inline_break(node)
212
+ node.text
213
+ end
214
+
215
+ # @param node [Asciidoctor::Inline]
216
+ def convert_inline_button(node)
217
+ %([<strong>#{node.text}</strong>])
218
+ end
219
+
220
+ # @param node [Asciidoctor::Inline]
221
+ def convert_inline_kbd(node)
222
+ %(<strong>#{node.attr('keys') * '</strong>+<strong>'}</strong>)
223
+ end
224
+
164
225
  # @param node [Asciidoctor::Inline]
165
226
  def convert_inline_anchor(node) # rubocop:disable Metrics/MethodLength
166
227
  case node.type
@@ -189,13 +250,13 @@ module Asciidoctor
189
250
 
190
251
  # @param node [Asciidoctor::Inline]
191
252
  def convert_inline_image(node)
192
- image_attrs = register_binary(node, node.image_uri(node.target))
253
+ image_attrs = register_binary(node, node.image_uri(node.target), 'image')
193
254
  %(<image #{image_attrs * ' '}/>)
194
255
  end
195
256
 
196
257
  # @param node [Asciidoctor::Block]
197
258
  def convert_image(node)
198
- image_attrs = register_binary(node, node.image_uri(node.attr('target')))
259
+ image_attrs = register_binary(node, node.image_uri(node.attr('target')), 'image')
199
260
  image_attrs << %(title="#{node.captioned_title}") if node.title?
200
261
  image_attrs << %(id="#{node.id}") if node.id
201
262
  %(<p><image #{image_attrs * ' '}/></p>)
@@ -208,9 +269,15 @@ module Asciidoctor
208
269
  doc
209
270
  end
210
271
 
272
+ def determine_mime_type(filename, media_type)
273
+ mime_types = MIME::Types.type_for(filename)
274
+ mime_types.delete_if { |x| x.media_type != media_type }
275
+ mime_types.empty? ? nil : mime_types[0].content_type
276
+ end
277
+
211
278
  # @param node [Asciidoctor::AbstractNode]
212
279
  # @param target [String]
213
- def register_binary(node, target) # rubocop:disable Metrics/MethodLength
280
+ def register_binary(node, target, media_type) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
214
281
  unless Asciidoctor::Helpers.uriish?(target)
215
282
  out_dir = node.attr('outdir', nil, true) || doc_option(node.document, :to_dir)
216
283
  fs_path = File.join(out_dir, target)
@@ -220,7 +287,12 @@ module Asciidoctor
220
287
  end
221
288
 
222
289
  if File.readable?(fs_path)
223
- @book.add_binary(target, fs_path)
290
+ # Calibre fails to load images if they contain path separators
291
+ target.sub!('/', '_')
292
+ target.sub!('\\', '_')
293
+
294
+ mime_type = determine_mime_type(target, media_type)
295
+ @book.add_binary(target, fs_path, mime_type)
224
296
  target = %(##{target})
225
297
  end
226
298
  end
@@ -238,6 +310,13 @@ module Asciidoctor
238
310
  lines * "\n"
239
311
  end
240
312
 
313
+ # @param node [Asciidoctor::Block]
314
+ def convert_sidebar(node)
315
+ title_tag = node.title.nil_or_empty? ? '' : %(<p><strong>#{node.title}</strong></p>)
316
+ %(#{title_tag}
317
+ #{node.content})
318
+ end
319
+
241
320
  # @param node [Asciidoctor::List]
242
321
  def convert_ulist(node)
243
322
  lines = []
@@ -300,7 +379,9 @@ module Asciidoctor
300
379
 
301
380
  # @param node [Asciidoctor::Table]
302
381
  def convert_table(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
303
- lines = ['<table>']
382
+ lines = []
383
+ lines << %(<subtitle>#{node.captioned_title}</subtitle>) if node.title?
384
+ lines << '<table>'
304
385
  node.rows.to_h.each do |tsec, rows| # rubocop:disable Metrics/BlockLength
305
386
  next if rows.empty?
306
387
 
@@ -316,7 +397,7 @@ module Asciidoctor
316
397
  when :literal
317
398
  %(<p><pre>#{cell.text}</pre></p>)
318
399
  else
319
- (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content.join "</p>\n<p>"}</p>)
400
+ (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content * "</p>\n<p>"}</p>)
320
401
  end
321
402
  end
322
403
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module FB2
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-fb2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
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-11-23 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.0
33
+ version: 0.4.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.0
40
+ version: 0.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: mime-types
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: asciidoctor-diagram
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,28 +100,28 @@ dependencies:
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.93.0
103
+ version: 1.4.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 0.93.0
110
+ version: 1.4.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rubocop-rspec
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 1.44.0
117
+ version: 2.0.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 1.44.0
124
+ version: 2.0.0
111
125
  description:
112
126
  email:
113
127
  - marat@slonopotamus.org
@@ -129,6 +143,7 @@ files:
129
143
  - Rakefile
130
144
  - asciidoctor-fb2.gemspec
131
145
  - bin/asciidoctor-fb2
146
+ - data/fb2.css
132
147
  - lib/asciidoctor_fb2.rb
133
148
  - lib/asciidoctor_fb2/version.rb
134
149
  - tasks/bundler.rake