asciidoctor-epub3 1.5.0.alpha.11 → 1.5.0.alpha.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +10 -0
- data/Gemfile +0 -2
- data/README.adoc +23 -5
- data/asciidoctor-epub3.gemspec +6 -5
- data/lib/asciidoctor-epub3/converter.rb +56 -50
- data/lib/asciidoctor-epub3/packager.rb +76 -38
- data/lib/asciidoctor-epub3/version.rb +1 -1
- metadata +41 -9
- data/data/images/default-cover-large.png +0 -0
- data/data/images/default-cover.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 761bc4b79a56daa0101477d7e58da7e5bcfa33f1a23e0f58ded5639ea1f91241
|
4
|
+
data.tar.gz: dc6068f91e7c7284f7e3891ea74d42014255eb7e318911e85be3fbfbbba8fbb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9691e8c859d1a4b8c27f5e1cf2999450ba6dc5dc53b5841084a734196de6ffc6eb6158bec6bd9dda70cfa869837d466e02bd7db9ca524fd27f72b417ad77bc37
|
7
|
+
data.tar.gz: 1d7f3bc67a899f05596ca5be57aedee0e737a0ec2243767faf2ea1f3ad2fcef40b6111d5a6798a9156ca73872df90e3e7338acf5c395d5b0f41d5523cab639e9
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,16 @@
|
|
5
5
|
This document provides a high-level view of the changes to the {project-name} by release.
|
6
6
|
For a detailed view of what has changed, refer to the {uri-repo}/commits/master[commit history] on GitHub.
|
7
7
|
|
8
|
+
== 1.5.0.alpha.12 (2020-02-02) - @slonopotamus
|
9
|
+
|
10
|
+
* make kindlegen a runtime dependency so it installs automatically during `gem install asciidoctor-epub3` (#270)
|
11
|
+
* make `KINDLEGEN` env var work again (#269)
|
12
|
+
* stop adding default front cover image (#180)
|
13
|
+
* enable Pygments on non-Windows JRuby platforms (#264)
|
14
|
+
* provide a human-readable error message when we fail to find KindleGen (#268)
|
15
|
+
* try to use KindleGen/EPUBCheck binary from `$PATH` (#276)
|
16
|
+
* add `ebook-kindlegen-path`/`ebook-epubcheck-path` attributes to override KindleGen/EPUBCheck executable location (#276)
|
17
|
+
|
8
18
|
== 1.5.0.alpha.11 (2020-01-26) - @slonopotamus
|
9
19
|
|
10
20
|
* drop unused dependencies: thread_safe, concurrent-ruby (#234)
|
data/Gemfile
CHANGED
@@ -8,8 +8,6 @@ gemspec
|
|
8
8
|
gem 'asciidoctor', ENV['ASCIIDOCTOR_VERSION'], require: false if ENV.key? 'ASCIIDOCTOR_VERSION'
|
9
9
|
|
10
10
|
group :optional do
|
11
|
-
gem 'epubcheck-ruby', '4.2.2.0'
|
12
|
-
gem 'kindlegen', (Gem::Version.new RUBY_VERSION) < (Gem::Version.new '2.4.0') ? '3.0.3' : '3.0.5'
|
13
11
|
gem 'pygments.rb', '1.2.1'
|
14
12
|
end
|
15
13
|
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= {project-name}: A _native_ EPUB3 converter for AsciiDoc
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
3
|
-
v1.5.0.alpha.
|
3
|
+
v1.5.0.alpha.12, 2020-02-02
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -541,14 +541,22 @@ For more information about this attribute and other related attributes, see {uri
|
|
541
541
|
*-D, --destination-dir* ::
|
542
542
|
Writes files to specified directory (defaults to the current directory)
|
543
543
|
|
544
|
+
*-a ebook-epubcheck-path=<path>*::
|
545
|
+
Specifies path to EPUBCheck executable to use with `-a ebook-validate`.
|
546
|
+
This attribute takes precedence over `EPUBCHECK` environment variable.
|
547
|
+
|
544
548
|
*-a ebook-extract* ::
|
545
549
|
Extracts the EPUB3 to a folder in the destination directory after the file is generated
|
546
550
|
|
547
551
|
*-a ebook-format=<format>* ::
|
548
552
|
Specifies the ebook format to generate (epub3 or kf8, default: epub3)
|
549
553
|
|
554
|
+
*-a ebook-kindlegen-path=<path>*::
|
555
|
+
Specifies path to KindleGen executable to use when producing KF8/Mobi.
|
556
|
+
This attribute takes precedence over `KINDLEGEN` environment variable.
|
557
|
+
|
550
558
|
*-a ebook-validate* ::
|
551
|
-
Runs {uri-epubcheck}[
|
559
|
+
Runs {uri-epubcheck}[EPUBCheck] to validate output file against the EPUB3 specification
|
552
560
|
|
553
561
|
*-a ebook-compress=<0|1|2|none|standard|huffdic>* ::
|
554
562
|
Controls the compression type used by kindlegen (0=none [default if unset], 1=standard [default if empty], 2=huffdic)
|
@@ -556,6 +564,16 @@ For more information about this attribute and other related attributes, see {uri
|
|
556
564
|
*-v, --version* ::
|
557
565
|
Display the program version
|
558
566
|
|
567
|
+
=== Environment variables
|
568
|
+
|
569
|
+
*EPUBCHECK*::
|
570
|
+
Specifies path to EPUBCheck executable to use with `-a ebook-validate`.
|
571
|
+
Effect of this variable can be overriden with `-a ebook-epubcheck-path` attribute.
|
572
|
+
|
573
|
+
*KINDLEGEN*::
|
574
|
+
Specifies path to KindleGen executable to use when producing KF8/Mobi.
|
575
|
+
Effect of this variable can be overriden with `-a ebook-kindlegen-path` attribute.
|
576
|
+
|
559
577
|
=== EPUB3 Archive Structure
|
560
578
|
|
561
579
|
Here's a sample manifest of files found in an EPUB3 document produced by {project-name}.
|
@@ -614,16 +632,16 @@ The sample book contains placeholder images for an author avatar and a book cove
|
|
614
632
|
|
615
633
|
// TODO explain the avatar and book cover images
|
616
634
|
|
617
|
-
===
|
635
|
+
=== Adding the Cover Image
|
618
636
|
|
619
637
|
Ereaders have different image resolution and file size limits regarding a book's cover.
|
620
|
-
Kindle covers tend to be 1050x1600 (16:9 resolution)
|
638
|
+
Kindle covers tend to be 1050x1600 (16:9 resolution).
|
621
639
|
To ensure your cover displays correctly, you'll want to review the documentation or publisher guidelines for the e-reading platform you're targeting.
|
622
640
|
|
623
641
|
WARNING: We've found that if the book cover is more than 1600px on any side, Aldiko will not render it and may even crash.
|
624
642
|
|
625
643
|
Feel free to use the SVG of the sample cover in the [path]_data/images_ folder as a template for creating your own cover.
|
626
|
-
Once your image is ready, you can
|
644
|
+
Once your image is ready, you can set the cover image by defining the `front-cover-image` attribute in the header of the master document.
|
627
645
|
|
628
646
|
[source,asciidoc]
|
629
647
|
----
|
data/asciidoctor-epub3.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'lib/asciidoctor-epub3/version'
|
4
4
|
require 'open3' unless defined? Open3
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
@@ -17,8 +17,7 @@ An extension for Asciidoctor that converts AsciiDoc documents to EPUB3 and KF8/M
|
|
17
17
|
s.homepage = 'https://github.com/asciidoctor/asciidoctor-epub3'
|
18
18
|
s.license = 'MIT'
|
19
19
|
|
20
|
-
|
21
|
-
#s.required_ruby_version = '>= 2.3.0'
|
20
|
+
s.required_ruby_version = '>= 2.3.0'
|
22
21
|
|
23
22
|
files = begin
|
24
23
|
(result = Open3.popen3('git ls-files -z') {|_, out| out.read }.split %(\0)).empty? ? Dir['**/*'] : result
|
@@ -31,11 +30,13 @@ An extension for Asciidoctor that converts AsciiDoc documents to EPUB3 and KF8/M
|
|
31
30
|
|
32
31
|
s.require_paths = ['lib']
|
33
32
|
|
34
|
-
s.add_development_dependency 'rake', '~>
|
33
|
+
s.add_development_dependency 'rake', '~> 13.0.0'
|
35
34
|
s.add_development_dependency 'rspec', '~> 3.9.0'
|
36
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
35
|
+
s.add_development_dependency 'rubocop', '~> 0.79.0'
|
37
36
|
s.add_development_dependency 'rubocop-rspec', '~> 1.37.0'
|
38
37
|
|
39
38
|
s.add_runtime_dependency 'asciidoctor', '>= 1.5.3', '< 3.0.0'
|
39
|
+
s.add_runtime_dependency 'epubcheck-ruby', '~> 4.2.2.0'
|
40
40
|
s.add_runtime_dependency 'gepub', '~> 1.0.0'
|
41
|
+
s.add_runtime_dependency 'kindlegen', '>= 3.0.3', '<= 3.0.5'
|
41
42
|
end
|
@@ -21,6 +21,8 @@ module Asciidoctor
|
|
21
21
|
htmlsyntax 'xml'
|
22
22
|
@validate = false
|
23
23
|
@extract = false
|
24
|
+
@kindlegen_path = nil
|
25
|
+
@epubcheck_path = nil
|
24
26
|
end
|
25
27
|
|
26
28
|
def convert node, name = nil
|
@@ -28,6 +30,8 @@ module Asciidoctor
|
|
28
30
|
@validate = node.attr? 'ebook-validate'
|
29
31
|
@extract = node.attr? 'ebook-extract'
|
30
32
|
@compress = node.attr 'ebook-compress'
|
33
|
+
@kindlegen_path = node.attr 'ebook-kindlegen-path'
|
34
|
+
@epubcheck_path = node.attr 'ebook-epubcheck-path'
|
31
35
|
spine_items = node.references[:spine_items]
|
32
36
|
if spine_items.nil?
|
33
37
|
logger.error %(#{::File.basename node.document.attr('docfile')}: failed to find spine items, produced file will be invalid)
|
@@ -44,7 +48,7 @@ module Asciidoctor
|
|
44
48
|
|
45
49
|
# FIXME: we have to package in write because we don't have access to target before this point
|
46
50
|
def write packager, target
|
47
|
-
packager.package validate: @validate, extract: @extract, compress: @compress, target: target
|
51
|
+
packager.package validate: @validate, extract: @extract, compress: @compress, kindlegen_path: @kindlegen_path, epubcheck_path: @epubcheck_path, target: target
|
48
52
|
nil
|
49
53
|
end
|
50
54
|
end
|
@@ -92,15 +96,16 @@ module Asciidoctor
|
|
92
96
|
@icon_names = []
|
93
97
|
end
|
94
98
|
|
95
|
-
def convert node, name = nil
|
96
|
-
|
97
|
-
|
99
|
+
def convert node, name = nil, _opts = {}
|
100
|
+
method_name = %(convert_#{name ||= node.node_name})
|
101
|
+
if respond_to? method_name
|
102
|
+
send method_name, node
|
98
103
|
else
|
99
|
-
logger.warn %(conversion missing in
|
104
|
+
logger.warn %(conversion missing in backend #{@backend} for #{name})
|
100
105
|
end
|
101
106
|
end
|
102
107
|
|
103
|
-
def
|
108
|
+
def convert_document node
|
104
109
|
docid = node.id
|
105
110
|
pubtype = node.attr 'publication-type', 'book'
|
106
111
|
|
@@ -193,11 +198,11 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
193
198
|
end
|
194
199
|
|
195
200
|
# NOTE embedded is used for AsciiDoc table cell content
|
196
|
-
def
|
201
|
+
def convert_embedded node
|
197
202
|
node.content
|
198
203
|
end
|
199
204
|
|
200
|
-
def
|
205
|
+
def convert_section node
|
201
206
|
hlevel = node.level + 1
|
202
207
|
epub_type_attr = node.special ? %( epub:type="#{node.sectname}") : ''
|
203
208
|
div_classes = [%(sect#{node.level}), node.role].compact
|
@@ -215,36 +220,36 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
215
220
|
end
|
216
221
|
|
217
222
|
# TODO: support use of quote block as abstract
|
218
|
-
def
|
223
|
+
def convert_preamble node
|
219
224
|
if (first_block = node.blocks[0]) && first_block.style == 'abstract'
|
220
|
-
|
225
|
+
convert_abstract first_block
|
221
226
|
# REVIEW: should we treat the preamble as an abstract in general?
|
222
227
|
elsif first_block && node.blocks.size == 1
|
223
|
-
|
228
|
+
convert_abstract first_block
|
224
229
|
else
|
225
230
|
node.content
|
226
231
|
end
|
227
232
|
end
|
228
233
|
|
229
|
-
def
|
234
|
+
def convert_open node
|
230
235
|
id_attr = node.id ? %( id="#{node.id}") : nil
|
231
236
|
class_attr = node.role ? %( class="#{node.role}") : nil
|
232
237
|
if id_attr || class_attr
|
233
238
|
%(<div#{id_attr}#{class_attr}>
|
234
|
-
#{
|
239
|
+
#{output_content node}
|
235
240
|
</div>)
|
236
241
|
else
|
237
|
-
|
242
|
+
output_content node
|
238
243
|
end
|
239
244
|
end
|
240
245
|
|
241
|
-
def
|
246
|
+
def convert_abstract node
|
242
247
|
%(<div class="abstract" epub:type="preamble">
|
243
|
-
#{
|
248
|
+
#{output_content node}
|
244
249
|
</div>)
|
245
250
|
end
|
246
251
|
|
247
|
-
def
|
252
|
+
def convert_paragraph node
|
248
253
|
role = node.role
|
249
254
|
# stack-head is the alternative to the default, inline-head (where inline means "run-in")
|
250
255
|
head_stop = node.attr 'head-stop', (role && (node.has_role? 'stack-head') ? nil : '.')
|
@@ -257,7 +262,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
257
262
|
end
|
258
263
|
end
|
259
264
|
|
260
|
-
def
|
265
|
+
def convert_pass node
|
261
266
|
content = node.content
|
262
267
|
if content == '<?hard-pagebreak?>'
|
263
268
|
'<hr epub:type="pagebreak" class="pagebreak"/>'
|
@@ -266,7 +271,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
266
271
|
end
|
267
272
|
end
|
268
273
|
|
269
|
-
def
|
274
|
+
def convert_admonition node
|
270
275
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
271
276
|
if node.title?
|
272
277
|
title = node.title
|
@@ -290,29 +295,29 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
290
295
|
end
|
291
296
|
%(<aside#{id_attr} class="admonition #{type}"#{title_attr} epub:type="#{epub_type}">
|
292
297
|
#{title_el}<div class="content">
|
293
|
-
#{
|
298
|
+
#{output_content node}
|
294
299
|
</div>
|
295
300
|
</aside>)
|
296
301
|
end
|
297
302
|
|
298
|
-
def
|
303
|
+
def convert_example node
|
299
304
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
300
305
|
title_div = node.title? ? %(<div class="example-title">#{node.title}</div>
|
301
306
|
) : ''
|
302
307
|
%(<div#{id_attr} class="example">
|
303
308
|
#{title_div}<div class="example-content">
|
304
|
-
#{
|
309
|
+
#{output_content node}
|
305
310
|
</div>
|
306
311
|
</div>)
|
307
312
|
end
|
308
313
|
|
309
|
-
def
|
314
|
+
def convert_floating_title node
|
310
315
|
tag_name = %(h#{node.level + 1})
|
311
316
|
id_attribute = node.id ? %( id="#{node.id}") : ''
|
312
317
|
%(<#{tag_name}#{id_attribute} class="#{['discrete', node.role].compact * ' '}">#{node.title}</#{tag_name}>)
|
313
318
|
end
|
314
319
|
|
315
|
-
def
|
320
|
+
def convert_listing node
|
316
321
|
figure_classes = ['listing']
|
317
322
|
figure_classes << 'coalesce' if node.option? 'unbreakable'
|
318
323
|
pre_classes = node.style == 'source' ? ['source', %(language-#{node.attr 'language'})] : ['screen']
|
@@ -326,19 +331,19 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
326
331
|
end
|
327
332
|
|
328
333
|
# QUESTION should we wrap the <pre> in either <div> or <figure>?
|
329
|
-
def
|
334
|
+
def convert_literal node
|
330
335
|
%(<pre class="screen">#{node.content}</pre>)
|
331
336
|
end
|
332
337
|
|
333
|
-
def
|
338
|
+
def convert_page_break _node
|
334
339
|
'<hr epub:type="pagebreak" class="pagebreak"/>'
|
335
340
|
end
|
336
341
|
|
337
|
-
def
|
342
|
+
def convert_thematic_break _node
|
338
343
|
'<hr class="thematicbreak"/>'
|
339
344
|
end
|
340
345
|
|
341
|
-
def
|
346
|
+
def convert_quote node
|
342
347
|
id_attr = %( id="#{node.id}") if node.id
|
343
348
|
class_attr = (role = node.role) ? %( class="blockquote #{role}") : ' class="blockquote"'
|
344
349
|
|
@@ -356,7 +361,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
356
361
|
|
357
362
|
footer_tag = footer_content.empty? ? '' : %(
|
358
363
|
<footer>~ #{footer_content * ' '}</footer>)
|
359
|
-
content = (
|
364
|
+
content = (output_content node).strip
|
360
365
|
%(<div#{id_attr}#{class_attr}>
|
361
366
|
<blockquote>
|
362
367
|
#{content}#{footer_tag}
|
@@ -364,7 +369,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
364
369
|
</div>)
|
365
370
|
end
|
366
371
|
|
367
|
-
def
|
372
|
+
def convert_verse node
|
368
373
|
id_attr = %( id="#{node.id}") if node.id
|
369
374
|
class_attr = (role = node.role) ? %( class="verse #{role}") : ' class="verse"'
|
370
375
|
|
@@ -385,7 +390,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
385
390
|
</div>)
|
386
391
|
end
|
387
392
|
|
388
|
-
def
|
393
|
+
def convert_sidebar node
|
389
394
|
classes = ['sidebar']
|
390
395
|
if node.title?
|
391
396
|
classes << 'titled'
|
@@ -400,12 +405,12 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
400
405
|
|
401
406
|
%(<aside class="#{classes * ' '}"#{title_attr} epub:type="sidebar">
|
402
407
|
#{title_el}<div class="content">
|
403
|
-
#{
|
408
|
+
#{output_content node}
|
404
409
|
</div>
|
405
410
|
</aside>)
|
406
411
|
end
|
407
412
|
|
408
|
-
def
|
413
|
+
def convert_table node
|
409
414
|
lines = [%(<div class="table">)]
|
410
415
|
lines << %(<div class="content">)
|
411
416
|
table_id_attr = node.id ? %( id="#{node.id}") : ''
|
@@ -493,7 +498,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
493
498
|
lines * LF
|
494
499
|
end
|
495
500
|
|
496
|
-
def
|
501
|
+
def convert_colist node
|
497
502
|
lines = ['<div class="callout-list">
|
498
503
|
<ol>']
|
499
504
|
num = CalloutStartNum
|
@@ -506,7 +511,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
506
511
|
end
|
507
512
|
|
508
513
|
# TODO: add complex class if list has nested blocks
|
509
|
-
def
|
514
|
+
def convert_dlist node
|
510
515
|
lines = []
|
511
516
|
case (style = node.style)
|
512
517
|
when 'itemized', 'ordered'
|
@@ -560,7 +565,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
560
565
|
lines * LF
|
561
566
|
end
|
562
567
|
|
563
|
-
def
|
568
|
+
def convert_olist node
|
564
569
|
complex = false
|
565
570
|
div_classes = ['ordered-list', node.style, node.role].compact
|
566
571
|
ol_classes = [node.style, ((node.option? 'brief') ? 'brief' : nil)].compact
|
@@ -588,7 +593,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
588
593
|
lines * LF
|
589
594
|
end
|
590
595
|
|
591
|
-
def
|
596
|
+
def convert_ulist node
|
592
597
|
complex = false
|
593
598
|
div_classes = ['itemized-list', node.style, node.role].compact
|
594
599
|
ul_classes = [node.style, ((node.option? 'brief') ? 'brief' : nil)].compact
|
@@ -615,7 +620,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
615
620
|
lines * LF
|
616
621
|
end
|
617
622
|
|
618
|
-
def
|
623
|
+
def convert_image node
|
619
624
|
target = node.attr 'target'
|
620
625
|
type = (::File.extname target)[1..-1]
|
621
626
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
@@ -654,7 +659,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
654
659
|
</figure>)
|
655
660
|
end
|
656
661
|
|
657
|
-
def
|
662
|
+
def convert_inline_anchor node
|
658
663
|
target = node.target
|
659
664
|
case node.type
|
660
665
|
when :xref # TODO: would be helpful to know what type the target is (e.g., bibref)
|
@@ -722,22 +727,22 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
722
727
|
end
|
723
728
|
end
|
724
729
|
|
725
|
-
def
|
730
|
+
def convert_inline_break node
|
726
731
|
%(#{node.text}<br/>)
|
727
732
|
end
|
728
733
|
|
729
|
-
def
|
734
|
+
def convert_inline_button node
|
730
735
|
%(<b class="button">[<span class="label">#{node.text}</span>]</b>)
|
731
736
|
end
|
732
737
|
|
733
|
-
def
|
738
|
+
def convert_inline_callout node
|
734
739
|
num = CalloutStartNum
|
735
740
|
int_num = node.text.to_i
|
736
741
|
(int_num - 1).times { num = num.next }
|
737
742
|
%(<i class="conum" data-value="#{int_num}">#{num}</i>)
|
738
743
|
end
|
739
744
|
|
740
|
-
def
|
745
|
+
def convert_inline_footnote node
|
741
746
|
if (index = node.attr 'index')
|
742
747
|
%(<sup class="noteref">[<a id="noteref-#{index}" href="#note-#{index}" epub:type="noteref">#{index}</a>]</sup>)
|
743
748
|
elsif node.type == :xref
|
@@ -745,7 +750,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
745
750
|
end
|
746
751
|
end
|
747
752
|
|
748
|
-
def
|
753
|
+
def convert_inline_image node
|
749
754
|
if node.type == 'icon'
|
750
755
|
@icon_names << (icon_name = node.target)
|
751
756
|
i_classes = ['icon', %(i-#{icon_name})]
|
@@ -769,11 +774,11 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
769
774
|
end
|
770
775
|
end
|
771
776
|
|
772
|
-
def
|
777
|
+
def convert_inline_indexterm node
|
773
778
|
node.type == :visible ? node.text : ''
|
774
779
|
end
|
775
780
|
|
776
|
-
def
|
781
|
+
def convert_inline_kbd node
|
777
782
|
if (keys = node.attr 'keys').size == 1
|
778
783
|
%(<kbd>#{keys[0]}</kbd>)
|
779
784
|
else
|
@@ -782,7 +787,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
782
787
|
end
|
783
788
|
end
|
784
789
|
|
785
|
-
def
|
790
|
+
def convert_inline_menu node
|
786
791
|
menu = node.attr 'menu'
|
787
792
|
# NOTE we swap right angle quote with chevron right from FontAwesome using CSS
|
788
793
|
caret = %(#{NoBreakSpace}<span class="caret">#{RightAngleQuote}</span> )
|
@@ -796,7 +801,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
796
801
|
end
|
797
802
|
end
|
798
803
|
|
799
|
-
def
|
804
|
+
def convert_inline_quoted node
|
800
805
|
case node.type
|
801
806
|
when :strong
|
802
807
|
%(<strong>#{node.text}</strong>)
|
@@ -819,7 +824,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
819
824
|
end
|
820
825
|
end
|
821
826
|
|
822
|
-
def
|
827
|
+
def output_content node
|
823
828
|
node.content_model == :simple ? %(<p>#{node.content}</p>) : node.content
|
824
829
|
end
|
825
830
|
|
@@ -915,7 +920,8 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
915
920
|
if (document = @document).backend == 'epub3'
|
916
921
|
document.attributes['spine'] = ''
|
917
922
|
document.set_attribute 'listing-caption', 'Listing'
|
918
|
-
|
923
|
+
# pygments.rb hangs on JRuby for Windows, see https://github.com/asciidoctor/asciidoctor-epub3/issues/253
|
924
|
+
if !(::RUBY_ENGINE == 'jruby' && Gem.win_platform?) && (Gem.try_activate 'pygments.rb')
|
919
925
|
if document.set_attribute 'source-highlighter', 'pygments'
|
920
926
|
document.set_attribute 'pygments-css', 'style'
|
921
927
|
document.set_attribute 'pygments-style', 'bw'
|
@@ -7,7 +7,7 @@ module Asciidoctor
|
|
7
7
|
module Epub3
|
8
8
|
module GepubBuilderMixin
|
9
9
|
include ::Asciidoctor::Logging
|
10
|
-
DATA_DIR = ::File.expand_path ::File.join(
|
10
|
+
DATA_DIR = ::File.expand_path ::File.join(__dir__, '..', '..', 'data')
|
11
11
|
SAMPLES_DIR = ::File.join DATA_DIR, 'samples'
|
12
12
|
LF = ?\n
|
13
13
|
CharEntityRx = ContentConverter::CharEntityRx
|
@@ -15,7 +15,6 @@ module Asciidoctor
|
|
15
15
|
FromHtmlSpecialCharsMap = ContentConverter::FromHtmlSpecialCharsMap
|
16
16
|
FromHtmlSpecialCharsRx = ContentConverter::FromHtmlSpecialCharsRx
|
17
17
|
CsvDelimiterRx = /\s*,\s*/
|
18
|
-
DefaultCoverImage = 'images/default-cover.png'
|
19
18
|
ImageMacroRx = /^image::?(.*?)\[(.*?)\]$/
|
20
19
|
ImgSrcScanRx = /<img src="(.+?)"/
|
21
20
|
SvgImgSniffRx = /<img src=".+?\.svg"/
|
@@ -119,28 +118,27 @@ module Asciidoctor
|
|
119
118
|
end
|
120
119
|
|
121
120
|
def add_cover_image doc
|
121
|
+
return if (image_path = doc.attr 'front-cover-image').nil?
|
122
|
+
|
122
123
|
imagesdir = (doc.attr 'imagesdir', '.').chomp '/'
|
123
124
|
imagesdir = (imagesdir == '.' ? nil : %(#{imagesdir}/))
|
124
125
|
|
125
|
-
|
126
|
-
|
127
|
-
if
|
128
|
-
|
129
|
-
|
130
|
-
(::Asciidoctor::AttributeList.new $2).parse_into image_attrs, %w(alt width height) unless $2.empty?
|
131
|
-
end
|
132
|
-
workdir = (workdir = doc.attr 'docdir').nil_or_empty? ? '.' : workdir
|
133
|
-
if ::File.readable? ::File.join(workdir, image_path)
|
134
|
-
unless !image_attrs.empty? && (width = image_attrs['width']) && (height = image_attrs['height'])
|
135
|
-
width, height = 1050, 1600
|
136
|
-
end
|
137
|
-
else
|
138
|
-
logger.error %(#{::File.basename doc.attr('docfile')}: front cover image not found or readable: #{::File.expand_path image_path, workdir})
|
139
|
-
image_path = nil
|
140
|
-
end
|
126
|
+
image_attrs = {}
|
127
|
+
if (image_path.include? ':') && image_path =~ ImageMacroRx
|
128
|
+
logger.warn %(deprecated block macro syntax detected in front-cover-image attribute) if image_path.start_with? 'image::'
|
129
|
+
image_path = %(#{imagesdir}#{$1})
|
130
|
+
(::Asciidoctor::AttributeList.new $2).parse_into image_attrs, %w(alt width height) unless $2.empty?
|
141
131
|
end
|
142
132
|
|
143
|
-
|
133
|
+
workdir = (workdir = doc.attr 'docdir').nil_or_empty? ? '.' : workdir
|
134
|
+
unless ::File.readable? ::File.join(workdir, image_path)
|
135
|
+
logger.error %(#{::File.basename doc.attr('docfile')}: front cover image not found or readable: #{::File.expand_path image_path, workdir})
|
136
|
+
return
|
137
|
+
end
|
138
|
+
|
139
|
+
unless !image_attrs.empty? && (width = image_attrs['width']) && (height = image_attrs['height'])
|
140
|
+
width, height = 1050, 1600
|
141
|
+
end
|
144
142
|
|
145
143
|
resources do
|
146
144
|
cover_image %(#{imagesdir}jacket/cover#{::File.extname image_path}) => (::File.join workdir, image_path)
|
@@ -154,7 +152,8 @@ module Asciidoctor
|
|
154
152
|
|
155
153
|
# NOTE must be called within the ordered block
|
156
154
|
def add_cover_page doc, spine_builder, manifest
|
157
|
-
cover_item_attrs = manifest.items['item_cover'].instance_variable_get :@attributes
|
155
|
+
return if (cover_item_attrs = manifest.items['item_cover'].instance_variable_get :@attributes).nil?
|
156
|
+
|
158
157
|
href = cover_item_attrs['href']
|
159
158
|
# NOTE we only store width and height temporarily to pass through the values
|
160
159
|
width = cover_item_attrs.delete 'width'
|
@@ -609,26 +608,46 @@ body > svg {
|
|
609
608
|
|
610
609
|
if fmt == :kf8
|
611
610
|
# QUESTION shouldn't we validate this epub file too?
|
612
|
-
distill_epub_to_mobi epub_file, target, options[:compress]
|
611
|
+
distill_epub_to_mobi epub_file, target, options[:compress], options[:kindlegen_path]
|
613
612
|
elsif options[:validate]
|
614
|
-
validate_epub epub_file
|
613
|
+
validate_epub epub_file, options[:epubcheck_path]
|
615
614
|
end
|
616
615
|
end
|
617
616
|
|
618
|
-
def
|
619
|
-
|
620
|
-
|
621
|
-
|
617
|
+
def get_kindlegen_command kindlegen_path
|
618
|
+
unless kindlegen_path.nil?
|
619
|
+
logger.debug %(Using ebook-kindlegen-path attribute: #{kindlegen_path})
|
620
|
+
return [kindlegen_path]
|
621
|
+
end
|
622
|
+
|
623
|
+
unless (result = ENV['KINDLEGEN']).nil?
|
624
|
+
logger.debug %(Using KINDLEGEN env variable: #{result})
|
625
|
+
return [result]
|
626
|
+
end
|
627
|
+
|
628
|
+
begin
|
622
629
|
require 'kindlegen' unless defined? ::Kindlegen
|
623
|
-
|
630
|
+
result = ::Kindlegen.command.to_s
|
631
|
+
logger.debug %(Using KindleGen from gem: #{result})
|
632
|
+
[result]
|
633
|
+
rescue LoadError => e
|
634
|
+
logger.debug %(#{e}; Using KindleGen from PATH)
|
635
|
+
[%(kindlegen#{::Gem.win_platform? ? '.exe' : ''})]
|
624
636
|
end
|
637
|
+
end
|
638
|
+
|
639
|
+
def distill_epub_to_mobi epub_file, target, compress, kindlegen_path
|
625
640
|
mobi_file = ::File.basename target.sub(EpubExtensionRx, '.mobi')
|
626
641
|
compress_flag = KindlegenCompression[compress ? (compress.empty? ? '1' : compress.to_s) : '0']
|
627
|
-
argv += ['-dont_append_source', compress_flag, '-o', mobi_file, epub_file].compact
|
628
642
|
|
629
|
-
|
630
|
-
|
631
|
-
|
643
|
+
argv = get_kindlegen_command(kindlegen_path) + ['-dont_append_source', compress_flag, '-o', mobi_file, epub_file].compact
|
644
|
+
begin
|
645
|
+
# This duplicates Kindlegen.run, but we want to override executable
|
646
|
+
out, err, res = Open3.capture3(*argv) do |r|
|
647
|
+
r.force_encoding 'UTF-8' if ::Gem.win_platform? && r.respond_to?(:force_encoding)
|
648
|
+
end
|
649
|
+
rescue Errno::ENOENT => e
|
650
|
+
raise 'Unable to run KindleGen. Either install the kindlegen gem or set KINDLEGEN environment variable with path to KindleGen executable', cause: e
|
632
651
|
end
|
633
652
|
|
634
653
|
out.each_line do |line|
|
@@ -646,15 +665,34 @@ body > svg {
|
|
646
665
|
end
|
647
666
|
end
|
648
667
|
|
649
|
-
def
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
argv = [::Gem.ruby, ::Gem.bin_path('epubcheck-ruby', 'epubcheck')]
|
668
|
+
def get_epubcheck_command epubcheck_path
|
669
|
+
unless epubcheck_path.nil?
|
670
|
+
logger.debug %(Using ebook-epubcheck-path attribute: #{epubcheck_path})
|
671
|
+
return [epubcheck_path]
|
654
672
|
end
|
655
673
|
|
656
|
-
|
657
|
-
|
674
|
+
unless (result = ENV['EPUBCHECK']).nil?
|
675
|
+
logger.debug %(Using EPUBCHECK env variable: #{result})
|
676
|
+
return [result]
|
677
|
+
end
|
678
|
+
|
679
|
+
begin
|
680
|
+
result = ::Gem.bin_path 'epubcheck-ruby', 'epubcheck'
|
681
|
+
logger.debug %(Using EPUBCheck from gem: #{result})
|
682
|
+
[::Gem.ruby, result]
|
683
|
+
rescue ::Gem::Exception => e
|
684
|
+
logger.debug %(#{e}; Using EPUBCheck from PATH)
|
685
|
+
['epubcheck']
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
def validate_epub epub_file, epubcheck_path
|
690
|
+
argv = get_epubcheck_command(epubcheck_path) + ['-w', epub_file]
|
691
|
+
begin
|
692
|
+
out, err, res = Open3.capture3(*argv)
|
693
|
+
rescue Errno::ENOENT => e
|
694
|
+
raise 'Unable to run EPUBCheck. Either install epubcheck-ruby gem or set EPUBCHECK environment variable with path to EPUBCheck executable', cause: e
|
695
|
+
end
|
658
696
|
|
659
697
|
out.each_line do |line|
|
660
698
|
logger.info line
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-epub3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.0.alpha.
|
4
|
+
version: 1.5.0.alpha.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 13.0.0
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 13.0.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,14 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 0.
|
48
|
+
version: 0.79.0
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0.
|
55
|
+
version: 0.79.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: rubocop-rspec
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,6 +87,20 @@ dependencies:
|
|
87
87
|
- - "<"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 3.0.0
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: epubcheck-ruby
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.2.2.0
|
97
|
+
type: :runtime
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 4.2.2.0
|
90
104
|
- !ruby/object:Gem::Dependency
|
91
105
|
name: gepub
|
92
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,6 +115,26 @@ dependencies:
|
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: 1.0.0
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: kindlegen
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 3.0.3
|
125
|
+
- - "<="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: 3.0.5
|
128
|
+
type: :runtime
|
129
|
+
prerelease: false
|
130
|
+
version_requirements: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 3.0.3
|
135
|
+
- - "<="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 3.0.5
|
104
138
|
description: 'An extension for Asciidoctor that converts AsciiDoc documents to EPUB3
|
105
139
|
and KF8/MOBI (Kindle) e-book archives.
|
106
140
|
|
@@ -159,8 +193,6 @@ files:
|
|
159
193
|
- data/images/default-avatar.jpg
|
160
194
|
- data/images/default-avatar.png
|
161
195
|
- data/images/default-avatar.svg
|
162
|
-
- data/images/default-cover-large.png
|
163
|
-
- data/images/default-cover.png
|
164
196
|
- data/images/default-cover.svg
|
165
197
|
- data/images/default-headshot.jpg
|
166
198
|
- data/images/default-headshot.png
|
@@ -191,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
223
|
requirements:
|
192
224
|
- - ">="
|
193
225
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
226
|
+
version: 2.3.0
|
195
227
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
228
|
requirements:
|
197
229
|
- - ">"
|
Binary file
|
Binary file
|