asciidoctor-fb2 0.2.1 → 0.3.1

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: 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: {}