asciidoctor-epub3 2.0.1 → 2.1.2.dev
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +12 -0
- data/Gemfile +0 -4
- data/README.adoc +1 -11
- data/asciidoctor-epub3.gemspec +12 -6
- data/data/styles/epub3-css3-only.scss +1 -0
- data/data/styles/epub3.scss +5 -2
- data/lib/asciidoctor-epub3/converter.rb +55 -172
- data/lib/asciidoctor-epub3/version.rb +1 -1
- metadata +17 -13
- data/bin/adb-push-ebook +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c0dd509a02dd2ac44d14dd78593ca9a70430a7ad851d753af2588b12758c436
|
4
|
+
data.tar.gz: f361b23eb0cd3b3ceeefa2884d8fd5a3eb2833ed53d3a5d735b4b328bc836e0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee3d61e1dfbff0cd7930477bfd88ec68c5e15afcc3c854fb003f9e75cd46ced07db5f3cdc97f052446d776782df68e36d7fcbad8f4381e2b5253ed00ae4d3715
|
7
|
+
data.tar.gz: 195f1ac17a1203f131a78ff98bde9fc1f519cf51eaff8fdc6e2af3b4417718378a37a4085481e1353e4cac2547cbbf3186052d24bbb5eabdad1bd6b859a13137
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,18 @@
|
|
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
|
+
== 2.1.1 (2024-05-12) - @slonopotamus
|
9
|
+
|
10
|
+
* fix crash when section title contains inline anchor (#472)
|
11
|
+
* fix crash on an SVG image inside table cell (#470)
|
12
|
+
* lock gepub to 1.0.15 to workaround file descriptor leak (#474)
|
13
|
+
|
14
|
+
== 2.1.0 (2024-02-04) - @slonopotamus
|
15
|
+
|
16
|
+
* drop MOBI support
|
17
|
+
* add support for blocks in callouts (#463)
|
18
|
+
* stop packaging samples into gem (#462)
|
19
|
+
|
8
20
|
== 2.0.1 (2024-01-13) - @slonopotamus
|
9
21
|
|
10
22
|
* restore styling of `<strong>` and `<em>` (#461)
|
data/Gemfile
CHANGED
@@ -9,8 +9,4 @@ group :optional do
|
|
9
9
|
# epubcheck-ruby might be safe to be converted into runtime dependency,
|
10
10
|
# but could have issues when packaged into asciidoctorj-epub3
|
11
11
|
gem 'epubcheck-ruby', '~> 5.1.0.0'
|
12
|
-
|
13
|
-
# Kindlegen is unavailable neither for 64-bit x86 macOS nor for ARM
|
14
|
-
# Also, skip JRuby on Windows for now. See https://github.com/jruby/jruby/issues/7171
|
15
|
-
gem 'kindlegen', '~> 3.1.0' unless RUBY_PLATFORM =~ /darwin/ || (Gem.win_platform? && RUBY_ENGINE == 'jruby')
|
16
12
|
end
|
data/README.adoc
CHANGED
@@ -1,6 +1,5 @@
|
|
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
|
-
v2.0.1, 2024-01-13
|
4
3
|
:project-name: Asciidoctor EPUB3
|
5
4
|
:project-handle: asciidoctor-epub3
|
6
5
|
:uri-project: https://github.com/asciidoctor/{project-handle}
|
@@ -13,7 +12,7 @@ image:https://img.shields.io/badge/zulip-join_chat-brightgreen.svg[project chat,
|
|
13
12
|
image:https://img.shields.io/gem/v/asciidoctor-epub3.svg[Latest Release,link={uri-gem}]
|
14
13
|
image:{uri-project}/workflows/CI/badge.svg?branch=main[GitHub Actions,link={uri-ci}]
|
15
14
|
|
16
|
-
{project-name} is a set of Asciidoctor extensions for converting AsciiDoc documents directly to the EPUB3
|
15
|
+
{project-name} is a set of Asciidoctor extensions for converting AsciiDoc documents directly to the EPUB3 e-book format.
|
17
16
|
|
18
17
|
== Documentation
|
19
18
|
|
@@ -54,15 +53,6 @@ $ asciidoctor-epub3 -D output path/to/book.adoc
|
|
54
53
|
When the script completes, you'll see the file [file]_book.epub_ appear in the [path]_output_ directory.
|
55
54
|
Open that file with an EPUB3 reader to view the result.
|
56
55
|
|
57
|
-
You may also produce KF8/MOBI file by setting `ebook-format` attribute to `kf8`.
|
58
|
-
|
59
|
-
[source,shell script]
|
60
|
-
----
|
61
|
-
$ asciidoctor-epub3 -D output -a ebook-format=kf8 path/to/book.adoc
|
62
|
-
----
|
63
|
-
|
64
|
-
When the script completes, the file [file]_book.mobi_ will appear in [path]_output_ directory.
|
65
|
-
|
66
56
|
== Contributing
|
67
57
|
|
68
58
|
In the spirit of free software, _everyone_ is encouraged to help improve this project.
|
data/asciidoctor-epub3.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'asciidoctor-epub3'
|
8
8
|
s.version = Asciidoctor::Epub3::VERSION
|
9
9
|
|
10
|
-
s.summary = 'Converts AsciiDoc documents to EPUB3
|
10
|
+
s.summary = 'Converts AsciiDoc documents to EPUB3 e-book format'
|
11
11
|
s.description = <<~EOS
|
12
|
-
An extension for Asciidoctor that converts AsciiDoc documents to EPUB3
|
12
|
+
An extension for Asciidoctor that converts AsciiDoc documents to EPUB3 e-book format.
|
13
13
|
EOS
|
14
14
|
|
15
15
|
s.authors = ['Dan Allen', 'Sarah White']
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
Dir['**/*']
|
26
26
|
end
|
27
27
|
s.files = files.grep %r{^(?:(?:data/(?:fonts|images|styles)|lib)/.+|Gemfile|Rakefile|LICENSE|(?:CHANGELOG|NOTICE|README)\.adoc|\.yardopts|#{s.name}\.gemspec)$}
|
28
|
-
s.executables = %w[asciidoctor-epub3
|
28
|
+
s.executables = %w[asciidoctor-epub3]
|
29
29
|
|
30
30
|
s.require_paths = ['lib']
|
31
31
|
|
@@ -33,15 +33,21 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_development_dependency 'asciimath', '~> 2.0'
|
34
34
|
s.add_development_dependency 'coderay', '~> 1.1.0'
|
35
35
|
s.add_development_dependency 'pygments.rb', '~> 2.4.0'
|
36
|
-
s.add_development_dependency 'rake', '~> 13.
|
36
|
+
s.add_development_dependency 'rake', '~> 13.2.0'
|
37
37
|
s.add_development_dependency 'rouge', '~> 3.0'
|
38
|
-
s.add_development_dependency 'rspec', '~> 3.
|
38
|
+
s.add_development_dependency 'rspec', '~> 3.13.0'
|
39
39
|
s.add_development_dependency 'rubocop', '~> 1.50.2'
|
40
40
|
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
41
41
|
s.add_development_dependency 'rubocop-rspec', '~> 2.20.0'
|
42
42
|
|
43
43
|
s.add_runtime_dependency 'asciidoctor', '~> 2.0'
|
44
|
-
|
44
|
+
|
45
|
+
# Temporarily ban gepub 1.0.16
|
46
|
+
# Looks like it stopped properly closing files after writing
|
47
|
+
# See https://github.com/skoji/gepub/pull/140#issuecomment-2106238457
|
48
|
+
s.add_runtime_dependency 'gepub', '>= 1.0.0', '<= 1.0.15'
|
49
|
+
# s.add_runtime_dependency 'gepub', '~> 1.0.0'
|
50
|
+
|
45
51
|
s.add_runtime_dependency 'mime-types', '~> 3.0'
|
46
52
|
|
47
53
|
# TODO: switch to 'sass-embedded' when we drop Ruby 2.5 support
|
@@ -32,6 +32,7 @@ body code, body kbd, body :not(.verse) > pre, :not(.verse) > pre :not(code) {
|
|
32
32
|
font-family: "M+ 1mn", monospace !important;
|
33
33
|
}
|
34
34
|
|
35
|
+
/* TODO: DO we still need this? */
|
35
36
|
@media amzn-kf8 {
|
36
37
|
/* Kindle does its own margin management, so don't use an explicit margin */
|
37
38
|
/*body {
|
data/data/styles/epub3.scss
CHANGED
@@ -841,7 +841,7 @@ div.verse {
|
|
841
841
|
page-break-inside: avoid;
|
842
842
|
}
|
843
843
|
|
844
|
-
/* TODO we may want to reenable hyphens here
|
844
|
+
/* TODO we may want to reenable hyphens here */
|
845
845
|
div.verse > pre {
|
846
846
|
font-family: "M+ 1p", sans-serif;
|
847
847
|
background-color: transparent;
|
@@ -1160,7 +1160,10 @@ nav[hidden~="hidden"] {
|
|
1160
1160
|
}
|
1161
1161
|
|
1162
1162
|
@media amzn-mobi {
|
1163
|
-
/*
|
1163
|
+
/*
|
1164
|
+
NOTE mobi7 doesn't support custom fonts, so revert to generic ones.
|
1165
|
+
See https://github.com/asciidoctor/asciidoctor-epub3/issues/56.
|
1166
|
+
*/
|
1164
1167
|
body p, ul, ol, li, dl, dt, dd, figcaption, caption, footer,
|
1165
1168
|
table.table th, table.table td, div.verse .attribution {
|
1166
1169
|
font-family: serif;
|
@@ -7,8 +7,7 @@ require_relative 'font_icon_map'
|
|
7
7
|
|
8
8
|
module Asciidoctor
|
9
9
|
module Epub3
|
10
|
-
# Public: The main converter for the epub3 backend that handles packaging the
|
11
|
-
# EPUB3 or KF8 publication file.
|
10
|
+
# Public: The main converter for the epub3 backend that handles packaging the EPUB3 publication file.
|
12
11
|
class Converter
|
13
12
|
include ::Asciidoctor::Converter
|
14
13
|
include ::Asciidoctor::Logging
|
@@ -17,15 +16,14 @@ module Asciidoctor
|
|
17
16
|
register_for 'epub3'
|
18
17
|
|
19
18
|
def write(output, target)
|
20
|
-
|
21
|
-
|
22
|
-
logger.debug %(Wrote #{@format.upcase} to #{epub_file})
|
19
|
+
output.generate_epub target
|
20
|
+
logger.debug %(Wrote to #{target})
|
23
21
|
if @extract
|
24
|
-
extract_dir =
|
22
|
+
extract_dir = target.sub EPUB_EXTENSION_RX, ''
|
25
23
|
::FileUtils.remove_dir extract_dir if ::File.directory? extract_dir
|
26
24
|
::Dir.mkdir extract_dir
|
27
25
|
::Dir.chdir extract_dir do
|
28
|
-
::Zip::File.open
|
26
|
+
::Zip::File.open target do |entries|
|
29
27
|
entries.each do |entry|
|
30
28
|
next unless entry.file?
|
31
29
|
|
@@ -36,15 +34,12 @@ module Asciidoctor
|
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
39
|
-
logger.debug %(Extracted
|
37
|
+
logger.debug %(Extracted to #{extract_dir})
|
40
38
|
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
elsif @validate
|
46
|
-
validate_epub epub_file
|
47
|
-
end
|
40
|
+
return unless @validate
|
41
|
+
|
42
|
+
validate_epub target
|
48
43
|
end
|
49
44
|
|
50
45
|
CSV_DELIMITED_RX = /\s*,\s*/.freeze
|
@@ -80,14 +75,10 @@ module Asciidoctor
|
|
80
75
|
TO_HTML_SPECIAL_CHARS_RX = /[#{TO_HTML_SPECIAL_CHARS_MAP.keys.join}]/.freeze
|
81
76
|
|
82
77
|
EPUB_EXTENSION_RX = /\.epub$/i.freeze
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
'none' => '-c0',
|
88
|
-
'standard' => '-c1',
|
89
|
-
'huffdic' => '-c2'
|
90
|
-
}.freeze
|
78
|
+
|
79
|
+
# This is a workaround for https://github.com/asciidoctor/asciidoctor/issues/4380
|
80
|
+
# Currently, there is no access to parent cell from inner document
|
81
|
+
PARENT_CELL_FIELD_NAME = :@epub3_parent_cell
|
91
82
|
|
92
83
|
QUOTE_TAGS = begin
|
93
84
|
tags = {
|
@@ -108,8 +99,13 @@ module Asciidoctor
|
|
108
99
|
|
109
100
|
def initialize(backend, opts = {})
|
110
101
|
super
|
102
|
+
|
103
|
+
@xrefs_seen = Set.new
|
104
|
+
@media_files = {}
|
105
|
+
@footnotes = []
|
106
|
+
|
111
107
|
basebackend 'html'
|
112
|
-
outfilesuffix '.epub'
|
108
|
+
outfilesuffix '.epub'
|
113
109
|
htmlsyntax 'xml'
|
114
110
|
end
|
115
111
|
|
@@ -158,19 +154,13 @@ module Asciidoctor
|
|
158
154
|
end
|
159
155
|
|
160
156
|
def convert_document(node)
|
161
|
-
@format = node.attr('ebook-format').to_sym
|
162
|
-
|
163
157
|
@validate = node.attr? 'ebook-validate'
|
164
158
|
@extract = node.attr? 'ebook-extract'
|
165
159
|
@compress = node.attr 'ebook-compress'
|
166
|
-
@kindlegen_path = node.attr 'ebook-kindlegen-path'
|
167
160
|
@epubcheck_path = node.attr 'ebook-epubcheck-path'
|
168
|
-
@xrefs_seen = ::Set.new
|
169
|
-
@media_files = {}
|
170
|
-
@footnotes = []
|
171
161
|
|
172
162
|
@book = GEPUB::Book.new 'EPUB/package.opf'
|
173
|
-
@book.epub_backward_compat =
|
163
|
+
@book.epub_backward_compat = true
|
174
164
|
@book.language node.attr('lang', 'en'), id: 'pub-language'
|
175
165
|
|
176
166
|
if node.attr? 'uuid'
|
@@ -239,7 +229,7 @@ module Asciidoctor
|
|
239
229
|
landmarks = []
|
240
230
|
|
241
231
|
front_cover = add_cover_page node, 'front-cover'
|
242
|
-
if front_cover.nil? &&
|
232
|
+
if front_cover.nil? && node.doctype == 'book'
|
243
233
|
# TODO(#352): add textual front cover similar to PDF
|
244
234
|
end
|
245
235
|
|
@@ -289,9 +279,9 @@ module Asciidoctor
|
|
289
279
|
}
|
290
280
|
end
|
291
281
|
|
292
|
-
nav_item.add_content
|
282
|
+
nav_item.add_content nav_doc(node, toc_items, landmarks, outlinelevels).to_ios
|
293
283
|
# User is not supposed to see landmarks, so pass empty array here
|
294
|
-
toc_item&.add_content
|
284
|
+
toc_item&.add_content nav_doc(node, toc_items, [], toclevels).to_ios
|
295
285
|
|
296
286
|
# NOTE: gepub doesn't support building a ncx TOC with depth > 1, so do it ourselves
|
297
287
|
toc_ncx = ncx_doc node, toc_items, outlinelevels
|
@@ -406,10 +396,8 @@ module Asciidoctor
|
|
406
396
|
end
|
407
397
|
|
408
398
|
header = if title || subtitle
|
409
|
-
%(<header>
|
410
|
-
<div class="chapter-header">
|
399
|
+
%(<header class="chapter-header">
|
411
400
|
#{byline}<h1 class="chapter-title">#{title}#{subtitle ? %(<small class="subtitle">#{subtitle}</small>) : ''}</h1>
|
412
|
-
</div>
|
413
401
|
</header>)
|
414
402
|
else
|
415
403
|
''
|
@@ -419,7 +407,6 @@ module Asciidoctor
|
|
419
407
|
# in order to avoid style duplication across chapter files
|
420
408
|
linkcss = true
|
421
409
|
|
422
|
-
# NOTE: kindlegen seems to mangle the <header> element, so we wrap its content in a div
|
423
410
|
lines = [%(<?xml version='1.0' encoding='utf-8'?>
|
424
411
|
<!DOCTYPE html>
|
425
412
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:mml="http://www.w3.org/1998/Math/MathML" xml:lang="#{lang = node.document.attr 'lang',
|
@@ -455,9 +442,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
455
442
|
unless (fns = node.document.footnotes - @footnotes).empty?
|
456
443
|
@footnotes += fns
|
457
444
|
|
458
|
-
|
459
|
-
lines << '<footer>
|
460
|
-
<div class="chapter-footer">
|
445
|
+
lines << '<footer class="chapter-footer">
|
461
446
|
<div class="footnotes">'
|
462
447
|
fns.each do |footnote|
|
463
448
|
lines << %(<aside id="note-#{footnote.index}" epub:type="footnote">
|
@@ -465,7 +450,6 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
465
450
|
</aside>)
|
466
451
|
end
|
467
452
|
lines << '</div>
|
468
|
-
</div>
|
469
453
|
</footer>'
|
470
454
|
end
|
471
455
|
|
@@ -479,7 +463,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
479
463
|
lines << '</body>
|
480
464
|
</html>'
|
481
465
|
|
482
|
-
chapter_item.add_content
|
466
|
+
chapter_item.add_content((lines * LF).to_ios)
|
483
467
|
epub_properties = node.attr 'epub-properties'
|
484
468
|
chapter_item.add_property 'svg' if epub_properties&.include? 'svg'
|
485
469
|
|
@@ -816,6 +800,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
816
800
|
else
|
817
801
|
case cell.style
|
818
802
|
when :asciidoc
|
803
|
+
cell.inner_document.instance_variable_set(PARENT_CELL_FIELD_NAME, cell)
|
819
804
|
cell_content = %(<div class="embed">#{cell.content}</div>)
|
820
805
|
when :verse
|
821
806
|
cell_content = %(<div class="verse">#{cell.text}</div>)
|
@@ -856,7 +841,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
856
841
|
<ol>']
|
857
842
|
num = CALLOUT_START_NUM
|
858
843
|
node.items.each_with_index do |item, i|
|
859
|
-
lines << %(<li><i class="conum" data-value="#{i + 1}">#{num}</i> #{item.text}</li>)
|
844
|
+
lines << %(<li><i class="conum" data-value="#{i + 1}">#{num}</i> #{item.text}#{item.content if item.blocks?}</li>)
|
860
845
|
num = num.next
|
861
846
|
end
|
862
847
|
lines << '</ol>
|
@@ -974,7 +959,9 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
974
959
|
lines << %(<h3 class="list-heading">#{node.title}</h3>) if node.title?
|
975
960
|
lines << %(<ol#{ol_class_attr}#{ol_start_attr}#{node.option?('reversed') ? ' reversed="reversed"' : ''}>)
|
976
961
|
node.items.each do |item|
|
977
|
-
|
962
|
+
li_classes = [item.role].compact
|
963
|
+
li_class_attr = li_classes.empty? ? '' : %( class="#{li_classes * ' '}")
|
964
|
+
lines << %(<li#{li_class_attr}>
|
978
965
|
<span class="principal">#{item.text}</span>)
|
979
966
|
if item.blocks?
|
980
967
|
lines << item.content
|
@@ -1001,7 +988,9 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1001
988
|
lines << %(<h3 class="list-heading">#{node.title}</h3>) if node.title?
|
1002
989
|
lines << %(<ul#{ul_class_attr}>)
|
1003
990
|
node.items.each do |item|
|
1004
|
-
|
991
|
+
li_classes = [item.role].compact
|
992
|
+
li_class_attr = li_classes.empty? ? '' : %( class="#{li_classes * ' '}")
|
993
|
+
lines << %(<li#{li_class_attr}>
|
1005
994
|
<span class="principal">#{item.text}</span>)
|
1006
995
|
if item.blocks?
|
1007
996
|
lines << item.content
|
@@ -1172,7 +1161,11 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1172
1161
|
return nil if node.nil?
|
1173
1162
|
return node unless get_chapter_filename(node).nil?
|
1174
1163
|
|
1175
|
-
node = node.
|
1164
|
+
node = if node.instance_variable_defined?(PARENT_CELL_FIELD_NAME)
|
1165
|
+
node.instance_variable_get(PARENT_CELL_FIELD_NAME)
|
1166
|
+
else
|
1167
|
+
node.parent
|
1168
|
+
end
|
1176
1169
|
end
|
1177
1170
|
end
|
1178
1171
|
|
@@ -1386,7 +1379,6 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1386
1379
|
end
|
1387
1380
|
|
1388
1381
|
def add_theme_assets(doc)
|
1389
|
-
format = @format
|
1390
1382
|
workdir = if doc.attr? 'epub3-stylesdir'
|
1391
1383
|
stylesdir = doc.attr 'epub3-stylesdir'
|
1392
1384
|
# FIXME: make this work for Windows paths!!
|
@@ -1404,13 +1396,7 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1404
1396
|
# TODO: improve design/UX of custom theme functionality, including custom fonts
|
1405
1397
|
%w[epub3 epub3-css3-only].each do |f|
|
1406
1398
|
css = load_css_file File.join(workdir, %(#{f}.scss))
|
1407
|
-
|
1408
|
-
# NOTE: add layer of indirection so Kindle Direct Publishing (KDP) doesn't strip font-related CSS rules
|
1409
|
-
@book.add_item %(styles/#{f}.css), content: %(@import url("#{f}-proxied.css");).to_ios
|
1410
|
-
@book.add_item %(styles/#{f}-proxied.css), content: css.to_ios
|
1411
|
-
else
|
1412
|
-
@book.add_item %(styles/#{f}.css), content: css.to_ios
|
1413
|
-
end
|
1399
|
+
@book.add_item %(styles/#{f}.css), content: css.to_ios
|
1414
1400
|
end
|
1415
1401
|
|
1416
1402
|
syntax_hl = doc.syntax_highlighter
|
@@ -1433,15 +1419,12 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1433
1419
|
@book.add_item 'styles/epub3-fonts.css', content: font_css.to_ios
|
1434
1420
|
unless font_files.empty?
|
1435
1421
|
# NOTE: metadata property in oepbs package manifest doesn't work; must use proprietary iBooks file instead
|
1436
|
-
|
1437
|
-
unless format == :kf8
|
1438
|
-
@book.add_optional_file 'META-INF/com.apple.ibooks.display-options.xml', '<?xml version="1.0" encoding="UTF-8"?>
|
1422
|
+
@book.add_optional_file 'META-INF/com.apple.ibooks.display-options.xml', '<?xml version="1.0" encoding="UTF-8"?>
|
1439
1423
|
<display_options>
|
1440
1424
|
<platform name="*">
|
1441
1425
|
<option name="specified-fonts">true</option>
|
1442
1426
|
</platform>
|
1443
1427
|
</display_options>'.to_ios
|
1444
|
-
end
|
1445
1428
|
|
1446
1429
|
font_files.each do |font_file|
|
1447
1430
|
@book.add_item font_file, content: File.join(DATA_DIR, font_file)
|
@@ -1486,8 +1469,6 @@ document.addEventListener('DOMContentLoaded', function(event, reader) {
|
|
1486
1469
|
return nil
|
1487
1470
|
end
|
1488
1471
|
|
1489
|
-
return nil if @format == :kf8
|
1490
|
-
|
1491
1472
|
unless !image_attrs.empty? && (width = image_attrs['width']) && (height = image_attrs['height'])
|
1492
1473
|
width = 1050
|
1493
1474
|
height = 1600
|
@@ -1522,9 +1503,9 @@ body > svg {
|
|
1522
1503
|
width="100%" height="100%" viewBox="0 0 #{width} #{height}" preserveAspectRatio="xMidYMid meet">
|
1523
1504
|
<image width="#{width}" height="#{height}" xlink:href="#{image_href}"/>
|
1524
1505
|
</svg></body>
|
1525
|
-
</html>)
|
1506
|
+
</html>)
|
1526
1507
|
|
1527
|
-
@book.add_ordered_item %(#{name}.xhtml), content: content, id: name
|
1508
|
+
@book.add_ordered_item %(#{name}.xhtml), content: content.to_ios, id: name
|
1528
1509
|
end
|
1529
1510
|
|
1530
1511
|
def get_frontmatter_files(doc, workdir)
|
@@ -1559,7 +1540,7 @@ body > svg {
|
|
1559
1540
|
front_matter_content = ::File.read front_matter
|
1560
1541
|
|
1561
1542
|
front_matter_file = File.basename front_matter, '.html'
|
1562
|
-
item = @book.add_ordered_item "#{front_matter_file}.xhtml", content:
|
1543
|
+
item = @book.add_ordered_item "#{front_matter_file}.xhtml", content: front_matter_content.to_ios
|
1563
1544
|
item.add_property 'svg' if SVG_IMG_SNIFF_RX =~ front_matter_content
|
1564
1545
|
# Store link to first frontmatter page
|
1565
1546
|
result = item if result.nil?
|
@@ -1615,8 +1596,8 @@ body > svg {
|
|
1615
1596
|
</head>
|
1616
1597
|
<body>
|
1617
1598
|
<section class="chapter">
|
1618
|
-
<header>
|
1619
|
-
<
|
1599
|
+
<header class="chapter-header">
|
1600
|
+
<h1 class="chapter-title"><small class="subtitle">#{doc.attr 'toc-title'}</small></h1>
|
1620
1601
|
</header>
|
1621
1602
|
<nav epub:type="toc" id="toc">)]
|
1622
1603
|
lines << (nav_level items, [depth, 0].max)
|
@@ -1738,72 +1719,6 @@ body > svg {
|
|
1738
1719
|
sass_engine.render
|
1739
1720
|
end
|
1740
1721
|
|
1741
|
-
def postprocess_xhtml(content)
|
1742
|
-
return content.to_ios unless @format == :kf8
|
1743
|
-
|
1744
|
-
# TODO: convert regular expressions to constants
|
1745
|
-
content
|
1746
|
-
.gsub(/<img([^>]+) style="width: (\d\d)%;"/, '<img\1 style="width: \2%; height: \2%;"')
|
1747
|
-
.gsub(%r{<script type="text/javascript">.*?</script>\n?}m, '')
|
1748
|
-
.to_ios
|
1749
|
-
end
|
1750
|
-
|
1751
|
-
def build_kindlegen_command
|
1752
|
-
unless @kindlegen_path.nil?
|
1753
|
-
logger.debug %(Using ebook-kindlegen-path attribute: #{@kindlegen_path})
|
1754
|
-
return [@kindlegen_path]
|
1755
|
-
end
|
1756
|
-
|
1757
|
-
unless (result = ENV.fetch('KINDLEGEN', nil)).nil?
|
1758
|
-
logger.debug %(Using KINDLEGEN env variable: #{result})
|
1759
|
-
return [result]
|
1760
|
-
end
|
1761
|
-
|
1762
|
-
begin
|
1763
|
-
require 'kindlegen' unless defined? ::Kindlegen
|
1764
|
-
result = ::Kindlegen.command.to_s
|
1765
|
-
logger.debug %(Using KindleGen from gem: #{result})
|
1766
|
-
[result]
|
1767
|
-
rescue LoadError => e
|
1768
|
-
logger.debug %(#{e}; Using KindleGen from PATH)
|
1769
|
-
[%(kindlegen#{::Gem.win_platform? ? '.exe' : ''})]
|
1770
|
-
end
|
1771
|
-
end
|
1772
|
-
|
1773
|
-
def distill_epub_to_mobi(epub_file, target, compress)
|
1774
|
-
mobi_file = ::File.basename target.sub(EPUB_EXTENSION_RX, '.mobi')
|
1775
|
-
compress_flag = KINDLEGEN_COMPRESSION[if compress
|
1776
|
-
compress.empty? ? '1' : compress.to_s
|
1777
|
-
else
|
1778
|
-
'0'
|
1779
|
-
end]
|
1780
|
-
|
1781
|
-
argv = build_kindlegen_command + ['-dont_append_source', compress_flag, '-o', mobi_file, epub_file].compact
|
1782
|
-
begin
|
1783
|
-
# This duplicates Kindlegen.run, but we want to override executable
|
1784
|
-
out, err, res = Open3.capture3(*argv) do |r|
|
1785
|
-
r.force_encoding 'UTF-8' if ::Gem.win_platform? && r.respond_to?(:force_encoding)
|
1786
|
-
end
|
1787
|
-
rescue Errno::ENOENT => e
|
1788
|
-
raise 'Unable to run KindleGen. Either install the kindlegen gem or place `kindlegen` executable on PATH or set KINDLEGEN environment variable with path to it',
|
1789
|
-
cause: e
|
1790
|
-
end
|
1791
|
-
|
1792
|
-
out.each_line do |line|
|
1793
|
-
log_line line
|
1794
|
-
end
|
1795
|
-
err.each_line do |line|
|
1796
|
-
log_line line
|
1797
|
-
end
|
1798
|
-
|
1799
|
-
output_file = ::File.join ::File.dirname(epub_file), mobi_file
|
1800
|
-
if res.success?
|
1801
|
-
logger.debug %(Wrote MOBI to #{output_file})
|
1802
|
-
else
|
1803
|
-
logger.error %(KindleGen failed to write MOBI to #{output_file})
|
1804
|
-
end
|
1805
|
-
end
|
1806
|
-
|
1807
1722
|
def build_epubcheck_command
|
1808
1723
|
unless @epubcheck_path.nil?
|
1809
1724
|
logger.debug %(Using ebook-epubcheck-path attribute: #{@epubcheck_path})
|
@@ -1875,27 +1790,6 @@ body > svg {
|
|
1875
1790
|
end
|
1876
1791
|
end
|
1877
1792
|
|
1878
|
-
class NumericIdGenerator
|
1879
|
-
def initialize
|
1880
|
-
@counter = 1
|
1881
|
-
end
|
1882
|
-
|
1883
|
-
# @param node [Asciidoctor::AbstractNode]
|
1884
|
-
# @return [void]
|
1885
|
-
def generate_id(node)
|
1886
|
-
if node.chapter? || node.is_a?(Asciidoctor::Document)
|
1887
|
-
node.id = %(_generated_id_#{@counter})
|
1888
|
-
@counter += 1
|
1889
|
-
end
|
1890
|
-
|
1891
|
-
# Recurse
|
1892
|
-
node.blocks.each do |subnode|
|
1893
|
-
# dlist contains array of *arrays* of blocks, so just skip them
|
1894
|
-
generate_id subnode if subnode.is_a?(Asciidoctor::AbstractBlock)
|
1895
|
-
end
|
1896
|
-
end
|
1897
|
-
end
|
1898
|
-
|
1899
1793
|
Extensions.register do
|
1900
1794
|
if (document = @document).backend == 'epub3'
|
1901
1795
|
document.set_attribute 'listing-caption', 'Listing'
|
@@ -1904,33 +1798,22 @@ body > svg {
|
|
1904
1798
|
document.set_attribute 'pygments-style', 'bw' unless document.attr? 'pygments-style'
|
1905
1799
|
document.set_attribute 'rouge-style', 'bw' unless document.attr? 'rouge-style'
|
1906
1800
|
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
when 'mobi'
|
1911
|
-
ebook_format = document.attributes['ebook-format'] = 'kf8'
|
1912
|
-
else
|
1913
|
-
# QUESTION: should we display a warning?
|
1914
|
-
ebook_format = document.attributes['ebook-format'] = 'epub3'
|
1915
|
-
end
|
1916
|
-
document.attributes[%(ebook-format-#{ebook_format})] = ''
|
1801
|
+
# Backward compatibility for documents that were created before we dropped MOBI support
|
1802
|
+
document.set_attribute 'ebook-format', 'epub3'
|
1803
|
+
document.set_attribute 'ebook-format-epub3', ''
|
1917
1804
|
|
1918
1805
|
# Enable generation of section ids because we use them for chapter filenames
|
1919
1806
|
document.set_attribute 'sectids'
|
1920
1807
|
treeprocessor do
|
1921
1808
|
process do |doc|
|
1922
|
-
|
1923
|
-
|
1924
|
-
NumericIdGenerator.new.generate_id doc
|
1925
|
-
else
|
1926
|
-
# :sectids: doesn't generate id for top-level section (why?), do it manually
|
1927
|
-
doc.id = Section.generate_id(doc.first_section&.title || doc.attr('docname') || 'document', doc) if doc.id.nil_or_empty?
|
1809
|
+
# :sectids: doesn't generate id for top-level section (why?), do it manually
|
1810
|
+
doc.id = Section.generate_id(doc.first_section&.title || doc.attr('docname') || 'document', doc) if doc.id.nil_or_empty?
|
1928
1811
|
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
end
|
1812
|
+
if (preamble = doc.blocks[0]) && preamble.context == :preamble && preamble.id.nil_or_empty?
|
1813
|
+
# :sectids: doesn't generate id for preamble (because it is not a section), do it manually
|
1814
|
+
preamble.id = Section.generate_id(preamble.title || 'preamble', doc)
|
1933
1815
|
end
|
1816
|
+
|
1934
1817
|
nil
|
1935
1818
|
end
|
1936
1819
|
end
|
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: 2.
|
4
|
+
version: 2.1.2.dev
|
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: 2024-
|
12
|
+
date: 2024-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor-diagram
|
@@ -73,14 +73,14 @@ dependencies:
|
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 13.
|
76
|
+
version: 13.2.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: 13.
|
83
|
+
version: 13.2.0
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rouge
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,14 +101,14 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 3.
|
104
|
+
version: 3.13.0
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: 3.
|
111
|
+
version: 3.13.0
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: rubocop
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,16 +169,22 @@ dependencies:
|
|
169
169
|
name: gepub
|
170
170
|
requirement: !ruby/object:Gem::Requirement
|
171
171
|
requirements:
|
172
|
-
- - "
|
172
|
+
- - ">="
|
173
173
|
- !ruby/object:Gem::Version
|
174
174
|
version: 1.0.0
|
175
|
+
- - "<="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: 1.0.15
|
175
178
|
type: :runtime
|
176
179
|
prerelease: false
|
177
180
|
version_requirements: !ruby/object:Gem::Requirement
|
178
181
|
requirements:
|
179
|
-
- - "
|
182
|
+
- - ">="
|
180
183
|
- !ruby/object:Gem::Version
|
181
184
|
version: 1.0.0
|
185
|
+
- - "<="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 1.0.15
|
182
188
|
- !ruby/object:Gem::Dependency
|
183
189
|
name: mime-types
|
184
190
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,13 +214,12 @@ dependencies:
|
|
208
214
|
- !ruby/object:Gem::Version
|
209
215
|
version: '0'
|
210
216
|
description: 'An extension for Asciidoctor that converts AsciiDoc documents to EPUB3
|
211
|
-
|
217
|
+
e-book format.
|
212
218
|
|
213
219
|
'
|
214
220
|
email: dan@opendevise.com
|
215
221
|
executables:
|
216
222
|
- asciidoctor-epub3
|
217
|
-
- adb-push-ebook
|
218
223
|
extensions: []
|
219
224
|
extra_rdoc_files: []
|
220
225
|
files:
|
@@ -225,7 +230,6 @@ files:
|
|
225
230
|
- README.adoc
|
226
231
|
- Rakefile
|
227
232
|
- asciidoctor-epub3.gemspec
|
228
|
-
- bin/adb-push-ebook
|
229
233
|
- bin/asciidoctor-epub3
|
230
234
|
- data/fonts/assorted-icons.ttf
|
231
235
|
- data/fonts/awesome/LICENSE.txt
|
@@ -304,8 +308,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
308
|
- !ruby/object:Gem::Version
|
305
309
|
version: '0'
|
306
310
|
requirements: []
|
307
|
-
rubygems_version: 3.5.
|
311
|
+
rubygems_version: 3.5.9
|
308
312
|
signing_key:
|
309
313
|
specification_version: 4
|
310
|
-
summary: Converts AsciiDoc documents to EPUB3
|
314
|
+
summary: Converts AsciiDoc documents to EPUB3 e-book format
|
311
315
|
test_files: []
|
data/bin/adb-push-ebook
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
ADB = ENV['ADB'] || 'adb'
|
5
|
-
TARGETS = {
|
6
|
-
'.epub' => '/sdcard/',
|
7
|
-
'.mobi' => '/sdcard/Android/data/com.amazon.kindle/files/'
|
8
|
-
}.freeze
|
9
|
-
|
10
|
-
unless File.executable? ADB
|
11
|
-
warn %(adb-push-ebook: `adb` not found.\nPlease set the ADB environment variable or add `adb` to your PATH.)
|
12
|
-
exit 1
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'open3'
|
16
|
-
require 'shellwords'
|
17
|
-
|
18
|
-
payload_file = ARGV[0] || '_output/sample-book'
|
19
|
-
|
20
|
-
transfers = if (payload_file_ext = File.extname payload_file).empty?
|
21
|
-
TARGETS.map do |(ext, target_dir)|
|
22
|
-
{
|
23
|
-
src: %(#{payload_file}#{ext}),
|
24
|
-
dest: target_dir
|
25
|
-
}
|
26
|
-
end
|
27
|
-
else
|
28
|
-
[{ src: payload_file, dest: TARGETS[payload_file_ext] }]
|
29
|
-
end
|
30
|
-
|
31
|
-
transfers.each do |transfer|
|
32
|
-
next unless File.file? transfer[:src]
|
33
|
-
|
34
|
-
Open3.popen2e Shellwords.join([ADB, 'push', transfer[:src], transfer[:dest]]) do |_input, output, _wait_thr|
|
35
|
-
output.each { |line| puts line }
|
36
|
-
end
|
37
|
-
end
|