asciidoctor-epub3 2.0.1 → 2.1.2.dev
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 +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
|