asciidoctor-fb2 0.2.1 → 0.3.1

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: 210abe6551fe7da1d9b89221086ccf555b0415e14ffec68915c859ba3b05bf5a
4
- data.tar.gz: 92d848355114858d43682c963606466c0f5e07bfcbcaf65e1436aa6cb34cecca
3
+ metadata.gz: fefb6e896cf8679642198ac1ffe5222916781f71cbb775130bf32eeb00b375b4
4
+ data.tar.gz: 5100ec044994316213786b065115f6214ca4dd29c4f8655fc3a9ffc42726d258
5
5
  SHA512:
6
- metadata.gz: 4ca271531be2ecfe832f45bfe25ba0ddfb69c938fd19acb4b9edde6f31c4d1f7b6efee4bc87c00429a9cfd8d3841acd1ecfe78c39fdea3cf5d2a14490a3b3306
7
- data.tar.gz: 68d20bc6f6fae5ba45c036fff85377294801c37bbf0abbc0c47fbf965aee74cfe8517e67c324ace6a96d26e801b1626564043ee6ef8d87d61d11f7742df6f5f1
6
+ metadata.gz: '099b2149b1dacc1a1239725ce386afdc48ff7429a6aa7e0108af80db0c84630c176ec6adf96090f671c7a51bd1140590d920133ba4de76788e239fe490951317'
7
+ data.tar.gz: 7418059f5dd43b7f77087acac3af70764e80af4dc676be995c9d421edd01dd89008b11926c36151b6832b1c137684236cad3b00a12b6798a5747d23690089c7c
@@ -17,8 +17,7 @@ jobs:
17
17
  test:
18
18
  strategy:
19
19
  matrix:
20
- # ruby: [jruby, 2.4, 2.5, 2.6, 2.7]
21
- ruby: [2.4, 2.5, 2.6, 2.7]
20
+ ruby: [jruby, 2.4, 2.5, 2.6, 2.7]
22
21
  platform: [ubuntu-latest, macos-latest, windows-latest]
23
22
  runs-on: ${{ matrix.platform }}
24
23
  steps:
@@ -1,12 +1,41 @@
1
1
  = {project-name} Changelog
2
2
  :project-name: Asciidoctor FB2
3
3
  :project-handle: asciidoctor-fb2
4
- :slug: slonopotamus/{project-handle}
4
+ :slug: asciidoctor/{project-handle}
5
5
  :uri-project: https://github.com/{slug}
6
6
 
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.1 (2020-11-29) - @slonopotamus
11
+
12
+ * fix crash on `+toc::[]+` macro
13
+ * avoid adding `notes` body to FB2 if document doesn't have any footnotes
14
+ * fix invalid XML syntax for table cells
15
+
16
+ == 0.3.0 (2020-11-25) - @slonopotamus
17
+
18
+ * output MIME type for FB2 embedded binary files. https://github.com/slonopotamus/asciidoctor-fb2/issues/19[#19]
19
+ * handle `+image:file[]+` syntax for `+:front-cover-image:+` document attribute. https://github.com/slonopotamus/asciidoctor-fb2/issues/19[#19]
20
+
21
+ == 0.2.4 (2020-11-24) - @slonopotamus
22
+
23
+ * add support for table captions
24
+ * fix images from subfolders not loaded in Calibre
25
+ * add initial CSS support
26
+
27
+ == 0.2.3 (2020-11-24) - @slonopotamus
28
+
29
+ * add support for literal blocks
30
+ * fix crash for `menu` inline macro without submenu. https://github.com/slonopotamus/asciidoctor-fb2/issues/15[#15]
31
+ * add initial support for sidebar
32
+
33
+ == 0.2.2 (2020-11-24) - @slonopotamus
34
+
35
+ * do not crash on inline line break macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/14[#14]
36
+ * add support for verses
37
+ * add support for quotes
38
+
10
39
  == 0.2.1 (2020-11-24) - @slonopotamus
11
40
 
12
41
  * add support for `kbd` inline macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/13[#13]
@@ -2,7 +2,7 @@
2
2
  Marat Radchenko <marat@slonopotamus.org>
3
3
  :project-name: Asciidoctor FB2
4
4
  :project-handle: asciidoctor-fb2
5
- :slug: slonopotamus/{project-handle}
5
+ :slug: asciidoctor/{project-handle}
6
6
  :uri-project: https://github.com/{slug}
7
7
  :uri-ci: {uri-project}/actions?query=branch%3Amaster
8
8
  :uri-gem: https://rubygems.org/gems/{project-handle}
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.authors = ['Marat Radchenko']
9
9
  s.email = ['marat@slonopotamus.org']
10
10
  s.summary = 'Converts AsciiDoc documents to FB2 e-book formats'
11
- s.homepage = 'https://github.com/slonopotamus/asciidoctor-fb2'
11
+ s.homepage = 'https://github.com/asciidoctor/asciidoctor-fb2'
12
12
  s.license = 'MIT'
13
13
  s.required_ruby_version = '>= 2.4.0'
14
14
 
@@ -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
 
@@ -75,7 +82,7 @@ module Asciidoctor
75
82
  #{node.content}
76
83
  </section>)
77
84
  @book.bodies << FB2rb::Body.new(nil, body)
78
- if node.document.footnotes
85
+ unless node.document.footnotes.empty?
79
86
  notes = []
80
87
  node.document.footnotes.each do |footnote|
81
88
  notes << %(<section id="note-#{footnote.index}">
@@ -108,6 +115,11 @@ module Asciidoctor
108
115
  end
109
116
  end
110
117
 
118
+ # @param _node [Asciidoctor::Block]
119
+ def convert_toc(_node)
120
+ ''
121
+ end
122
+
111
123
  # @param node [Asciidoctor::Block]
112
124
  def convert_paragraph(node)
113
125
  lines = [
@@ -119,8 +131,47 @@ module Asciidoctor
119
131
  lines * "\n"
120
132
  end
121
133
 
134
+ # @param node [Asciidoctor::Block]
135
+ def convert_quote(node)
136
+ citetitle = node.attr('citetitle')
137
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<subtitle>#{citetitle}</subtitle>)
138
+
139
+ author = node.attr('attribution')
140
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
141
+
142
+ %(<cite>
143
+ #{citetitle_tag}
144
+ <p>#{node.content}</p>
145
+ #{author_tag}
146
+ </cite>)
147
+ end
148
+
149
+ # @param node [Asciidoctor::Block]
150
+ def convert_verse(node)
151
+ body = node.content&.split("\n\n")&.map do |stanza|
152
+ %(<stanza>\n<v>#{stanza.split("\n") * "</v>\n<v>"}</v>\n</stanza>)
153
+ end&.join("\n")
154
+
155
+ citetitle = node.attr('citetitle')
156
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<title>#{citetitle}</title>)
157
+
158
+ author = node.attr('attribution')
159
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
160
+
161
+ %(<poem>
162
+ #{citetitle_tag}
163
+ #{body}
164
+ #{author_tag}
165
+ </poem>)
166
+ end
167
+
122
168
  # @param node [Asciidoctor::Block]
123
169
  def convert_listing(node)
170
+ convert_literal(node)
171
+ end
172
+
173
+ # @param node [Asciidoctor::Block]
174
+ def convert_literal(node)
124
175
  lines = []
125
176
  node.content.split("\n").each do |line|
126
177
  lines << %(<p><code>#{line}</code></p>)
@@ -152,15 +203,20 @@ module Asciidoctor
152
203
  caret = '&#160;<strong>&#8250;</strong> '
153
204
  menu = node.attr('menu')
154
205
  menuitem = node.attr('menuitem')
155
- submenus = node.attr('submenus').join(%(</b>#{caret}<b>))
206
+ submenus = node.attr('submenus') * %(</b>#{caret}<b>)
156
207
 
157
208
  result = %(<strong>#{menu}</strong>)
158
- result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.empty?
159
- result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.empty?
209
+ result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.nil_or_empty?
210
+ result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.nil_or_empty?
160
211
 
161
212
  result
162
213
  end
163
214
 
215
+ # @param node [Asciidoctor::Inline]
216
+ def convert_inline_break(node)
217
+ node.text
218
+ end
219
+
164
220
  # @param node [Asciidoctor::Inline]
165
221
  def convert_inline_button(node)
166
222
  %([<strong>#{node.text}</strong>])
@@ -168,7 +224,7 @@ module Asciidoctor
168
224
 
169
225
  # @param node [Asciidoctor::Inline]
170
226
  def convert_inline_kbd(node)
171
- %(<strong>#{node.attr('keys').join('</strong>+<strong>')}</strong>)
227
+ %(<strong>#{node.attr('keys') * '</strong>+<strong>'}</strong>)
172
228
  end
173
229
 
174
230
  # @param node [Asciidoctor::Inline]
@@ -199,13 +255,13 @@ module Asciidoctor
199
255
 
200
256
  # @param node [Asciidoctor::Inline]
201
257
  def convert_inline_image(node)
202
- image_attrs = register_binary(node, node.image_uri(node.target))
258
+ image_attrs = register_binary(node, node.image_uri(node.target), 'image')
203
259
  %(<image #{image_attrs * ' '}/>)
204
260
  end
205
261
 
206
262
  # @param node [Asciidoctor::Block]
207
263
  def convert_image(node)
208
- image_attrs = register_binary(node, node.image_uri(node.attr('target')))
264
+ image_attrs = register_binary(node, node.image_uri(node.attr('target')), 'image')
209
265
  image_attrs << %(title="#{node.captioned_title}") if node.title?
210
266
  image_attrs << %(id="#{node.id}") if node.id
211
267
  %(<p><image #{image_attrs * ' '}/></p>)
@@ -218,9 +274,15 @@ module Asciidoctor
218
274
  doc
219
275
  end
220
276
 
277
+ def determine_mime_type(filename, media_type)
278
+ mime_types = MIME::Types.type_for(filename)
279
+ mime_types.delete_if { |x| x.media_type != media_type }
280
+ mime_types.empty? ? nil : mime_types[0].content_type
281
+ end
282
+
221
283
  # @param node [Asciidoctor::AbstractNode]
222
284
  # @param target [String]
223
- def register_binary(node, target) # rubocop:disable Metrics/MethodLength
285
+ def register_binary(node, target, media_type) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
224
286
  unless Asciidoctor::Helpers.uriish?(target)
225
287
  out_dir = node.attr('outdir', nil, true) || doc_option(node.document, :to_dir)
226
288
  fs_path = File.join(out_dir, target)
@@ -230,7 +292,12 @@ module Asciidoctor
230
292
  end
231
293
 
232
294
  if File.readable?(fs_path)
233
- @book.add_binary(target, fs_path)
295
+ # Calibre fails to load images if they contain path separators
296
+ target.sub!('/', '_')
297
+ target.sub!('\\', '_')
298
+
299
+ mime_type = determine_mime_type(target, media_type)
300
+ @book.add_binary(target, fs_path, mime_type)
234
301
  target = %(##{target})
235
302
  end
236
303
  end
@@ -248,6 +315,13 @@ module Asciidoctor
248
315
  lines * "\n"
249
316
  end
250
317
 
318
+ # @param node [Asciidoctor::Block]
319
+ def convert_sidebar(node)
320
+ title_tag = node.title.nil_or_empty? ? '' : %(<p><strong>#{node.title}</strong></p>)
321
+ %(#{title_tag}
322
+ #{node.content})
323
+ end
324
+
251
325
  # @param node [Asciidoctor::List]
252
326
  def convert_ulist(node)
253
327
  lines = []
@@ -310,7 +384,9 @@ module Asciidoctor
310
384
 
311
385
  # @param node [Asciidoctor::Table]
312
386
  def convert_table(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
313
- lines = ['<table>']
387
+ lines = []
388
+ lines << %(<subtitle>#{node.captioned_title}</subtitle>) if node.title?
389
+ lines << '<table>'
314
390
  node.rows.to_h.each do |tsec, rows| # rubocop:disable Metrics/BlockLength
315
391
  next if rows.empty?
316
392
 
@@ -326,7 +402,7 @@ module Asciidoctor
326
402
  when :literal
327
403
  %(<p><pre>#{cell.text}</pre></p>)
328
404
  else
329
- (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content.join "</p>\n<p>"}</p>)
405
+ (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content * "</p>\n<p>"}</p>)
330
406
  end
331
407
  end
332
408
 
@@ -337,7 +413,7 @@ module Asciidoctor
337
413
  ]
338
414
  cell_attrs << %(colspan="#{cell.colspan}") if cell.colspan
339
415
  cell_attrs << %(rowspan="#{cell.rowspan}") if cell.rowspan
340
- lines << %(<#{cell_tag_name} #{cell_attrs * ' '}">#{cell_content}</#{cell_tag_name}>)
416
+ lines << %(<#{cell_tag_name} #{cell_attrs * ' '}>#{cell_content}</#{cell_tag_name}>)
341
417
  end
342
418
  lines << '</tr>'
343
419
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module FB2
5
- VERSION = '0.2.1'
5
+ VERSION = '0.3.1'
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.1
4
+ version: 0.3.1
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-24 00:00:00.000000000 Z
11
+ date: 2020-11-29 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
@@ -136,7 +151,7 @@ files:
136
151
  - tasks/console.rake
137
152
  - tasks/rspec.rake
138
153
  - tasks/rubocop.rake
139
- homepage: https://github.com/slonopotamus/asciidoctor-fb2
154
+ homepage: https://github.com/asciidoctor/asciidoctor-fb2
140
155
  licenses:
141
156
  - MIT
142
157
  metadata: {}