asciidoctor-fb2 0.2.0 → 0.3.0
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 +4 -4
- data/CHANGELOG.adoc +28 -0
- data/asciidoctor-fb2.gemspec +4 -3
- data/data/fb2.css +3 -0
- data/lib/asciidoctor_fb2.rb +91 -10
- data/lib/asciidoctor_fb2/version.rb +1 -1
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fe8aeff6fa259f44c96b2adcc9f2f2074e68b918f1dc4ec0d509691b34b67e4
|
4
|
+
data.tar.gz: 6ca94abe536faeeb639bea944ac21a90b6cabe6de42ad733fe7879148665441d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b18f5a752a529d7a13e7beb1cc30c097914d2696a39f1bfdb736a748b16ee2fcf32544a6fa6b5166b8611a524411a812acc4530550e366a19210dab66ac3cdd2
|
7
|
+
data.tar.gz: 8d6eee70a2a3bbaa328f8f2d9056cf4a25150b0bb6d398323d6ab509cb8a43489171c564492720b21acfda4b52bb0060867d11ad608a76371ba8cbf3565ced2a
|
data/CHANGELOG.adoc
CHANGED
@@ -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]
|
data/asciidoctor-fb2.gemspec
CHANGED
@@ -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.
|
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', '~>
|
28
|
-
s.add_development_dependency 'rubocop-rspec', '~>
|
28
|
+
s.add_development_dependency 'rubocop', '~> 1.4.0'
|
29
|
+
s.add_development_dependency 'rubocop-rspec', '~> 2.0.0'
|
29
30
|
end
|
data/data/fb2.css
ADDED
data/lib/asciidoctor_fb2.rb
CHANGED
@@ -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 = ' <strong>›</strong> '
|
153
199
|
menu = node.attr('menu')
|
154
200
|
menuitem = node.attr('menuitem')
|
155
|
-
submenus = node.attr('submenus')
|
201
|
+
submenus = node.attr('submenus') * %(</b>#{caret}<b>)
|
156
202
|
|
157
203
|
result = %(<strong>#{menu}</strong>)
|
158
|
-
result += %(#{caret}<strong>#{submenus}</strong>) unless submenus.
|
159
|
-
result += %(#{caret}<strong>#{menuitem}</strong>) unless menuitem.
|
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
|
-
|
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 = [
|
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
|
400
|
+
(cell_content = cell.content).empty? ? '' : %(<p>#{cell_content * "</p>\n<p>"}</p>)
|
320
401
|
end
|
321
402
|
end
|
322
403
|
|
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.
|
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-
|
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.
|
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.
|
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:
|
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:
|
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:
|
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:
|
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
|