asciidoctor-fb2 0.1.0 → 0.2.4

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: c8d4c3a2aa4774098306334ce565317f632d1a18915560dd25df96ce059fa24d
4
- data.tar.gz: fe4bc5213b9009120a250db9ef89db70c5c312a09f57ee3b74bf11f68a4ed180
3
+ metadata.gz: 10a3aff0401e84e1ad7ef6e5beb2cd823dacb368ccd5171326597eb72fadb355
4
+ data.tar.gz: 0120b9bf29fbde68b6bdea2245bc903a27404da357f419116b07ba41c35e7742
5
5
  SHA512:
6
- metadata.gz: 2d9cc6fa6b74be5c852752a2836d0a1607a0d3baeefbeb4047565e2a2b4b68cc7098250a6ad359c58456d55fbf025bcad4c6e0da5f1ad7eb8ba28fccaceebb92
7
- data.tar.gz: d1ba09be9557da949cccef970a09efdd4a78003b8e3f1d726293da17d69d08435f31f9eeab9e96650cb0c37f962f11d4eea20b05e7f0fb787b2a8b10feac460e
6
+ metadata.gz: 8e1d26f435621c97a0b0a62d2de350ad39fa6d4acac36bf6b5d15d330e881bd7dfd5bcf55cbeea8c4e76ac0cf996583ecf27931012427ee4e34b30f7a8f49d2b
7
+ data.tar.gz: fbd79588f67f4295829c4b0012d5178dd292167c14be8d5294fe9fe514fa20073b2afd2fea6d2db8db99a58964fc59c1e9b7a505ebe7871b153dbb97d4ec10c0
@@ -7,6 +7,37 @@
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.2.4 (2020-11-24) - @slonopotamus
11
+
12
+ * add support for table captions
13
+ * fix images from subfolders not loaded in Calibre
14
+ * add initial CSS support
15
+
16
+ == 0.2.3 (2020-11-24) - @slonopotamus
17
+
18
+ * add support for literal blocks
19
+ * fix crash for `menu` inline macro without submenu. https://github.com/slonopotamus/asciidoctor-fb2/issues/15[#15]
20
+ * add initial support for sidebar
21
+
22
+ == 0.2.2 (2020-11-24) - @slonopotamus
23
+
24
+ * do not crash on inline line break macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/14[#14]
25
+ * add support for verses
26
+ * add support for quotes
27
+
28
+ == 0.2.1 (2020-11-24) - @slonopotamus
29
+
30
+ * add support for `kbd` inline macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/13[#13]
31
+ * add support for `btn` inline macro
32
+
33
+ == 0.2.0 (2020-11-23) - @slonopotamus
34
+
35
+ * add support for cover image via `+:front-cover-image:+` attribute. https://github.com/slonopotamus/asciidoctor-fb2/issues/3[#3]
36
+ * update fb2rb to 0.3.0
37
+ * add support for nested lists. https://github.com/slonopotamus/asciidoctor-fb2/issues/2[#2]
38
+ * output uncompressed book if filename doesn't end with `.zip`
39
+ * add support for `menu` inline macro. https://github.com/slonopotamus/asciidoctor-fb2/issues/12[#12]
40
+
10
41
  == 0.1.0 (2020-07-24) - @slonopotamus
11
42
 
12
- * Initial release
43
+ * initial release
@@ -14,24 +14,39 @@ image:{uri-project}/workflows/CI/badge.svg?branch=master[Build Status,link={uri-
14
14
 
15
15
  == Installation
16
16
 
17
+ {project-name} is published on RubyGems.org.
18
+ You can install the published gem using the following command:
19
+
17
20
  [source,shell script]
18
21
  ----
19
- $ gem install asciidoctor-fb2 --pre
22
+ $ gem install asciidoctor-fb2
20
23
  ----
21
24
 
22
- == Usage
25
+ Assuming all the required gems install properly, verify you can run the `{project-handle}` script:
23
26
 
24
27
  [source,shell script]
25
28
  ----
26
- asciidoctor-fb2 /path/to/book.adoc
29
+ $ asciidoctor-fb2 -v
27
30
  ----
28
31
 
29
- == Development
32
+ If you see the version of {project-name} printed, you're ready to use {project-name}.
30
33
 
31
- After checking out the repo, run `bundle install` to install dependencies.
32
- Then, run `bundle exec rake spec` to run the tests.
34
+ == Usage
35
+
36
+ Converting an AsciiDoc document to FB2 is as simple as passing your document to the `{project-handle}` command.
37
+ This command should be available on your PATH if you installed the `{project-handle}` gem.
38
+ Otherwise, you can find the command in the [path]_bin_ folder of the project.
39
+ We also recommend specifying an output directory using the `-D` option flag.
40
+
41
+ [source,shell script]
42
+ ----
43
+ $ asciidoctor-fb2 -D output path/to/book.adoc
44
+ ----
45
+
46
+ When the script completes, you'll see the file [file]_book.fb2.zip_ appear in the [path]_output_ directory.
47
+ Open that file with an FB2 reader to view the result.
33
48
 
34
- === FB2-related AsciiDoc Attributes
49
+ == FB2-related AsciiDoc Attributes
35
50
 
36
51
  The metadata in the generated FB2 file is populated from attributes in the AsciiDoc document.
37
52
  The names of the attributes and the metadata elements to which they map are documented in this section.
@@ -48,10 +63,18 @@ The names of the attributes and the metadata elements to which they map are docu
48
63
  |Populates the content language in FB2 metadata.
49
64
 
50
65
  |keywords
51
- |Populates keywords list in FB2 metadata
66
+ |Populates keywords list in FB2 metadata.
52
67
  The keywords should be represented as comma-separated values (CSV).
53
68
 
54
69
  |genres
55
- |Populates genres list in FB2 metadata
70
+ |Populates genres list in FB2 metadata.
56
71
  The genres should be represented as comma-separated values (CSV).
72
+
73
+ |front-cover-image
74
+ |Specifies path to front cover image.
57
75
  |===
76
+
77
+ == Development
78
+
79
+ After checking out the repo, run `bundle install` to install dependencies.
80
+ Then, run `bundle exec rake spec` to run the tests.
@@ -19,11 +19,11 @@ 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.2.0'
22
+ s.add_runtime_dependency 'fb2rb', '~> 0.4.0'
23
23
 
24
24
  s.add_development_dependency 'asciidoctor-diagram', '~> 2.0'
25
25
  s.add_development_dependency 'rake', '~> 13.0'
26
- s.add_development_dependency 'rspec', '~> 3.9.0'
27
- s.add_development_dependency 'rubocop', '~> 0.88.0'
28
- s.add_development_dependency 'rubocop-rspec', '~> 1.42.0'
26
+ 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'
29
29
  end
@@ -0,0 +1,3 @@
1
+ body {
2
+ text-align: justify
3
+ }
@@ -6,6 +6,8 @@ require 'fb2rb'
6
6
 
7
7
  module Asciidoctor
8
8
  module FB2
9
+ DATA_DIR = File.expand_path(File.join(__dir__, '..', 'data'))
10
+
9
11
  # Converts AsciiDoc documents to FB2 e-book formats
10
12
  class Converter < Asciidoctor::Converter::Base # rubocop:disable Metrics/ClassLength
11
13
  include ::Asciidoctor::Writer
@@ -23,8 +25,10 @@ module Asciidoctor
23
25
  end
24
26
 
25
27
  # @param node [Asciidoctor::Document]
26
- def convert_document(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
28
+ def convert_document(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
27
29
  @book = FB2rb::Book.new
30
+ @book.add_stylesheet('text/css', File.join(DATA_DIR, 'fb2.css'))
31
+
28
32
  document_info = @book.description.document_info
29
33
  title_info = @book.description.title_info
30
34
 
@@ -57,6 +61,12 @@ module Asciidoctor
57
61
  fb2date = FB2rb::FB2Date.new(date, Date.parse(date))
58
62
  title_info.date = document_info.date = fb2date
59
63
 
64
+ unless (cover_image = node.attr('front-cover-image')).nil?
65
+ cover_image_path = node.image_uri(cover_image)
66
+ register_binary(node, cover_image_path)
67
+ title_info.coverpage = FB2rb::Coverpage.new([%(##{cover_image_path})])
68
+ end
69
+
60
70
  document_info.id = node.attr('uuid', '')
61
71
  document_info.version = node.attr('revnumber')
62
72
  document_info.program_used = %(Asciidoctor FB2 #{VERSION} using Asciidoctor #{node.attr('asciidoctor-version')})
@@ -113,8 +123,47 @@ module Asciidoctor
113
123
  lines * "\n"
114
124
  end
115
125
 
126
+ # @param node [Asciidoctor::Block]
127
+ def convert_quote(node)
128
+ citetitle = node.attr('citetitle')
129
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<subtitle>#{citetitle}</subtitle>)
130
+
131
+ author = node.attr('attribution')
132
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
133
+
134
+ %(<cite>
135
+ #{citetitle_tag}
136
+ <p>#{node.content}</p>
137
+ #{author_tag}
138
+ </cite>)
139
+ end
140
+
141
+ # @param node [Asciidoctor::Block]
142
+ def convert_verse(node)
143
+ body = node.content&.split("\n\n")&.map do |stanza|
144
+ %(<stanza>\n<v>#{stanza.split("\n") * "</v>\n<v>"}</v>\n</stanza>)
145
+ end&.join("\n")
146
+
147
+ citetitle = node.attr('citetitle')
148
+ citetitle_tag = citetitle.nil_or_empty? ? '' : %(<title>#{citetitle}</title>)
149
+
150
+ author = node.attr('attribution')
151
+ author_tag = author.nil_or_empty? ? '' : %(<text-author>#{node.attr('attribution')}</text-author>)
152
+
153
+ %(<poem>
154
+ #{citetitle_tag}
155
+ #{body}
156
+ #{author_tag}
157
+ </poem>)
158
+ end
159
+
116
160
  # @param node [Asciidoctor::Block]
117
161
  def convert_listing(node)
162
+ convert_literal(node)
163
+ end
164
+
165
+ # @param node [Asciidoctor::Block]
166
+ def convert_literal(node)
118
167
  lines = []
119
168
  node.content.split("\n").each do |line|
120
169
  lines << %(<p><code>#{line}</code></p>)
@@ -141,6 +190,35 @@ module Asciidoctor
141
190
  %(#{open}#{node.text}#{close})
142
191
  end
143
192
 
193
+ # @param node [Asciidoctor::Inline]
194
+ def convert_inline_menu(node)
195
+ caret = '&#160;<strong>&#8250;</strong> '
196
+ menu = node.attr('menu')
197
+ menuitem = node.attr('menuitem')
198
+ submenus = node.attr('submenus') * %(</b>#{caret}<b>)
199
+
200
+ result = %(<strong>#{menu}</strong>)
201
+ result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.nil_or_empty?
202
+ result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.nil_or_empty?
203
+
204
+ result
205
+ end
206
+
207
+ # @param node [Asciidoctor::Inline]
208
+ def convert_inline_break(node)
209
+ node.text
210
+ end
211
+
212
+ # @param node [Asciidoctor::Inline]
213
+ def convert_inline_button(node)
214
+ %([<strong>#{node.text}</strong>])
215
+ end
216
+
217
+ # @param node [Asciidoctor::Inline]
218
+ def convert_inline_kbd(node)
219
+ %(<strong>#{node.attr('keys') * '</strong>+<strong>'}</strong>)
220
+ end
221
+
144
222
  # @param node [Asciidoctor::Inline]
145
223
  def convert_inline_anchor(node) # rubocop:disable Metrics/MethodLength
146
224
  case node.type
@@ -169,13 +247,13 @@ module Asciidoctor
169
247
 
170
248
  # @param node [Asciidoctor::Inline]
171
249
  def convert_inline_image(node)
172
- image_attrs = resolve_image_attrs(node, node.target)
250
+ image_attrs = register_binary(node, node.image_uri(node.target))
173
251
  %(<image #{image_attrs * ' '}/>)
174
252
  end
175
253
 
176
254
  # @param node [Asciidoctor::Block]
177
255
  def convert_image(node)
178
- image_attrs = resolve_image_attrs(node, node.attr('target'))
256
+ image_attrs = register_binary(node, node.image_uri(node.attr('target')))
179
257
  image_attrs << %(title="#{node.captioned_title}") if node.title?
180
258
  image_attrs << %(id="#{node.id}") if node.id
181
259
  %(<p><image #{image_attrs * ' '}/></p>)
@@ -190,8 +268,7 @@ module Asciidoctor
190
268
 
191
269
  # @param node [Asciidoctor::AbstractNode]
192
270
  # @param target [String]
193
- def resolve_image_attrs(node, target) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
194
- target = node.image_uri(target)
271
+ def register_binary(node, target) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
195
272
  unless Asciidoctor::Helpers.uriish?(target)
196
273
  out_dir = node.attr('outdir', nil, true) || doc_option(node.document, :to_dir)
197
274
  fs_path = File.join(out_dir, target)
@@ -201,6 +278,10 @@ module Asciidoctor
201
278
  end
202
279
 
203
280
  if File.readable?(fs_path)
281
+ # Calibre fails to load images if they contain path separators
282
+ target.sub!('/', '_')
283
+ target.sub!('\\', '_')
284
+
204
285
  @book.add_binary(target, fs_path)
205
286
  target = %(##{target})
206
287
  end
@@ -212,30 +293,47 @@ module Asciidoctor
212
293
 
213
294
  # @param node [Asciidoctor::Block]
214
295
  def convert_admonition(node)
215
- %(<p><strong>#{node.title || node.caption}:</strong>
296
+ lines = [%(<p><strong>#{node.title || node.caption}:</strong>
216
297
  #{node.content}
217
- </p>)
298
+ </p>)]
299
+ lines << '<empty-line/>' unless node.has_role?('last')
300
+ lines * "\n"
301
+ end
302
+
303
+ # @param node [Asciidoctor::Block]
304
+ def convert_sidebar(node)
305
+ title_tag = node.title.nil_or_empty? ? '' : %(<p><strong>#{node.title}</strong></p>)
306
+ %(#{title_tag}
307
+ #{node.content})
218
308
  end
219
309
 
220
310
  # @param node [Asciidoctor::List]
221
311
  def convert_ulist(node)
222
312
  lines = []
313
+ @stack ||= []
314
+
223
315
  node.items.each do |item|
224
- lines << %(<p>• #{item.text}</p>)
316
+ @stack << '•'
317
+ lines << %(<p>#{@stack * ' '} #{item.text}</p>)
225
318
  lines << %(<p>#{item.content}</p>) if item.blocks?
319
+ @stack.pop
226
320
  end
227
- lines << '<empty-line/>' unless node.has_role?('last')
321
+
322
+ lines << '<empty-line/>' unless node.has_role?('last') || !@stack.empty?
228
323
  lines * "\n"
229
324
  end
230
325
 
231
326
  # @param node [Asciidoctor::List]
232
- def convert_olist(node)
327
+ def convert_olist(node) # rubocop:disable Metrics/AbcSize
233
328
  lines = []
329
+ @stack ||= []
234
330
  node.items.each_with_index do |item, index|
235
- lines << %(<p>#{index + 1}. #{item.text}</p>)
331
+ @stack << %(#{index + 1}.)
332
+ lines << %(<p>#{@stack * ' '} #{item.text}</p>)
236
333
  lines << %(<p>#{item.content}</p>) if item.blocks?
334
+ @stack.pop
237
335
  end
238
- lines << '<empty-line/>' unless node.has_role?('last')
336
+ lines << '<empty-line/>' unless node.has_role?('last') || !@stack.empty?
239
337
  lines * "\n"
240
338
  end
241
339
 
@@ -271,7 +369,9 @@ module Asciidoctor
271
369
 
272
370
  # @param node [Asciidoctor::Table]
273
371
  def convert_table(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
274
- lines = ['<table>']
372
+ lines = []
373
+ lines << %(<subtitle>#{node.captioned_title}</subtitle>) if node.title?
374
+ lines << '<table>'
275
375
  node.rows.to_h.each do |tsec, rows| # rubocop:disable Metrics/BlockLength
276
376
  next if rows.empty?
277
377
 
@@ -287,7 +387,7 @@ module Asciidoctor
287
387
  when :literal
288
388
  %(<p><pre>#{cell.text}</pre></p>)
289
389
  else
290
- (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content.join "</p>\n<p>"}</p>)
390
+ (cell_content = cell.content).empty? ? '' : %(<p>#{cell_content * "</p>\n<p>"}</p>)
291
391
  end
292
392
  end
293
393
 
@@ -319,7 +419,11 @@ module Asciidoctor
319
419
 
320
420
  # @param output [FB2rb::Book]
321
421
  def write(output, target)
322
- output.write(target)
422
+ if target.respond_to?(:end_with?) && target.end_with?('.zip')
423
+ output.write_compressed(target)
424
+ else
425
+ output.write_uncompressed(target)
426
+ end
323
427
  end
324
428
  end
325
429
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module FB2
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.4'
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.1.0
4
+ version: 0.2.4
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-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.2.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.2.0
40
+ version: 0.4.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: asciidoctor-diagram
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,42 +72,42 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 3.9.0
75
+ version: 3.10.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 3.9.0
82
+ version: 3.10.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.88.0
89
+ version: 0.93.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.88.0
96
+ version: 0.93.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.42.0
103
+ version: 1.44.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.42.0
110
+ version: 1.44.0
111
111
  description:
112
112
  email:
113
113
  - marat@slonopotamus.org
@@ -129,6 +129,7 @@ files:
129
129
  - Rakefile
130
130
  - asciidoctor-fb2.gemspec
131
131
  - bin/asciidoctor-fb2
132
+ - data/fb2.css
132
133
  - lib/asciidoctor_fb2.rb
133
134
  - lib/asciidoctor_fb2/version.rb
134
135
  - tasks/bundler.rake
@@ -155,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
156
  - !ruby/object:Gem::Version
156
157
  version: '0'
157
158
  requirements: []
158
- rubygems_version: 3.1.2
159
+ rubygems_version: 3.1.4
159
160
  signing_key:
160
161
  specification_version: 4
161
162
  summary: Converts AsciiDoc documents to FB2 e-book formats