asciidoctor 2.0.20 → 2.0.22
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 +46 -1
- data/README-de.adoc +2 -2
- data/README-fr.adoc +2 -2
- data/README-jp.adoc +2 -2
- data/README-zh_CN.adoc +2 -2
- data/README.adoc +2 -2
- data/asciidoctor.gemspec +1 -1
- data/data/reference/syntax.adoc +1 -1
- data/data/stylesheets/asciidoctor-default.css +3 -2
- data/lib/asciidoctor/abstract_node.rb +6 -6
- data/lib/asciidoctor/converter/docbook5.rb +74 -42
- data/lib/asciidoctor/converter/html5.rb +1 -1
- data/lib/asciidoctor/converter/manpage.rb +41 -50
- data/lib/asciidoctor/logging.rb +2 -0
- data/lib/asciidoctor/parser.rb +27 -13
- data/lib/asciidoctor/reader.rb +5 -1
- data/lib/asciidoctor/rx.rb +3 -2
- data/lib/asciidoctor/substitutors.rb +87 -76
- data/lib/asciidoctor/version.rb +1 -1
- data/lib/asciidoctor.rb +2 -3
- data/man/asciidoctor.1 +3 -3
- data/man/asciidoctor.adoc +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c8bf90148c22e9396333d1062352368ea297bd1a63d03c0166e0dde81677989
|
|
4
|
+
data.tar.gz: a9c48ed8d9827acb0b9919b1f6909c1752cd62115b3e6e7e9b552d8a6d7930c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 84f45230cbd9b25b810ef9a369b2c2e769833517fda4197f55f52129b86c6c30b9c4f06d20df20e6abd552a3b12679c123641de35c8d29e6dd3d0d3b511b8185
|
|
7
|
+
data.tar.gz: 0cf0028a60356d0966ff1637e130b285b73d769f7bcf426a31397f9eab8bbe91118d78fa27c303684f0e624dd062980ec5602c931e65272382d079b086ea076f
|
data/CHANGELOG.adoc
CHANGED
|
@@ -16,6 +16,52 @@ For an even more detailed look at what has changed, refer to the {url-repo}/comm
|
|
|
16
16
|
This project utilizes semantic versioning.
|
|
17
17
|
|
|
18
18
|
// tag::compact[]
|
|
19
|
+
== 2.0.22 (2024-03-08) - @mojavelinux
|
|
20
|
+
|
|
21
|
+
Improvements::
|
|
22
|
+
|
|
23
|
+
* Set `cloaked-context` attribute on source block when context is not `:listing` (#4556)
|
|
24
|
+
|
|
25
|
+
Compliance::
|
|
26
|
+
|
|
27
|
+
* Remove use of base64 library to prevent warning in Ruby >= 3.3 (#4561)
|
|
28
|
+
|
|
29
|
+
=== Details
|
|
30
|
+
|
|
31
|
+
{url-repo}/releases/tag/v2.0.22[git tag] | {url-repo}/compare/v2.0.21\...v2.0.22[full diff]
|
|
32
|
+
// end::compact[]
|
|
33
|
+
|
|
34
|
+
== 2.0.21 (2024-02-20) - @mojavelinux
|
|
35
|
+
|
|
36
|
+
Compliance::
|
|
37
|
+
|
|
38
|
+
* Turn off system-dependent newline conversion when writing files; don't convert line feeds to system-dependent newline (#4550)
|
|
39
|
+
* Support logger in Ruby 3.3 by instantiating super class (#4493) (*@mtasaka*)
|
|
40
|
+
* Add support for `scaledwidth` and `scale` attributes on inline image macro in DocBook output (#4552)
|
|
41
|
+
* Update latest Ruby to 3.3 in CI workflows
|
|
42
|
+
|
|
43
|
+
Improvements::
|
|
44
|
+
|
|
45
|
+
* Change title to doctitle in warning message about use of abstract to make subject more clear
|
|
46
|
+
* Modify default stylesheet to add text decoration to active footnote number link in footnotes list (#4530) (@Larhzu)
|
|
47
|
+
|
|
48
|
+
Bug Fixes::
|
|
49
|
+
|
|
50
|
+
* Nested dlist attached using list continuation should not consume detached paragraph (#3535)
|
|
51
|
+
* Don't break nested dlist with attached block if offset from parent list by empty line (#3693)
|
|
52
|
+
* Preserve paragraph breaks in normal table cell in manpage output (#4481)
|
|
53
|
+
* Style cells in head row as bold in manpage output (#4490)
|
|
54
|
+
* Escape spaces in include target (using inline passthrough) when generating link from include directive (#4461)
|
|
55
|
+
* Move abstract inside info tag in DocBook output (#3602)
|
|
56
|
+
* Honor secondary and tertiary terms on `indexterm` macro when primary term is quoted and contains an equals sign (#3652)
|
|
57
|
+
* Remove extra border below doctitle when sidebar toc is collapsed into main content area (#4523)
|
|
58
|
+
* Treat bare URL enclosed in angle brackets as unconstrained syntax; only match until closing angled bracket (#4468)
|
|
59
|
+
* Allow URL enclosed in angled brackets syntax to be escaped using backslash (#4468)
|
|
60
|
+
|
|
61
|
+
=== Details
|
|
62
|
+
|
|
63
|
+
{url-repo}/releases/tag/v2.0.21[git tag] | {url-repo}/compare/v2.0.20\...v2.0.21[full diff]
|
|
64
|
+
|
|
19
65
|
== 2.0.20 (2023-05-18) - @mojavelinux
|
|
20
66
|
|
|
21
67
|
Bug Fixes::
|
|
@@ -26,7 +72,6 @@ Bug Fixes::
|
|
|
26
72
|
=== Details
|
|
27
73
|
|
|
28
74
|
{url-repo}/releases/tag/v2.0.20[git tag] | {url-repo}/compare/v2.0.19\...v2.0.20[full diff]
|
|
29
|
-
// end::compact[]
|
|
30
75
|
|
|
31
76
|
== 2.0.19 (2023-05-17) - @mojavelinux
|
|
32
77
|
|
data/README-de.adoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Asciidoctor
|
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
|
3
|
-
v2.0.
|
|
3
|
+
v2.0.22, 2024-03-08
|
|
4
4
|
// settings:
|
|
5
5
|
:idprefix:
|
|
6
6
|
:idseparator: -
|
|
@@ -16,7 +16,7 @@ ifdef::env-github[]
|
|
|
16
16
|
:warning-caption: :warning:
|
|
17
17
|
endif::[]
|
|
18
18
|
// Variables:
|
|
19
|
-
:release-version: 2.0.
|
|
19
|
+
:release-version: 2.0.22
|
|
20
20
|
// URIs:
|
|
21
21
|
:uri-org: https://github.com/asciidoctor
|
|
22
22
|
:uri-repo: {uri-org}/asciidoctor
|
data/README-fr.adoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Asciidoctor
|
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
|
3
|
-
v2.0.
|
|
3
|
+
v2.0.22, 2024-03-08
|
|
4
4
|
// settings:
|
|
5
5
|
:idprefix:
|
|
6
6
|
:idseparator: -
|
|
@@ -16,7 +16,7 @@ ifdef::env-github[]
|
|
|
16
16
|
:warning-caption: :warning:
|
|
17
17
|
endif::[]
|
|
18
18
|
// Variables:
|
|
19
|
-
:release-version: 2.0.
|
|
19
|
+
:release-version: 2.0.22
|
|
20
20
|
// URIs:
|
|
21
21
|
:uri-org: https://github.com/asciidoctor
|
|
22
22
|
:uri-repo: {uri-org}/asciidoctor
|
data/README-jp.adoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Asciidoctor
|
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
|
3
|
-
v2.0.
|
|
3
|
+
v2.0.22, 2024-03-08
|
|
4
4
|
// settings:
|
|
5
5
|
:idprefix:
|
|
6
6
|
:idseparator: -
|
|
@@ -16,7 +16,7 @@ ifdef::env-github[]
|
|
|
16
16
|
:warning-caption: :warning:
|
|
17
17
|
endif::[]
|
|
18
18
|
// Variables:
|
|
19
|
-
:release-version: 2.0.
|
|
19
|
+
:release-version: 2.0.22
|
|
20
20
|
// URIs:
|
|
21
21
|
:uri-org: https://github.com/asciidoctor
|
|
22
22
|
:uri-repo: {uri-org}/asciidoctor
|
data/README-zh_CN.adoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Asciidoctor
|
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
|
3
|
-
v2.0.
|
|
3
|
+
v2.0.22, 2024-03-08
|
|
4
4
|
// settings:
|
|
5
5
|
:page-layout: base
|
|
6
6
|
:idprefix:
|
|
@@ -17,7 +17,7 @@ ifdef::env-github[]
|
|
|
17
17
|
:warning-caption: :warning:
|
|
18
18
|
endif::[]
|
|
19
19
|
// Variables:
|
|
20
|
-
:release-version: 2.0.
|
|
20
|
+
:release-version: 2.0.22
|
|
21
21
|
// URIs:
|
|
22
22
|
:uri-org: https://github.com/asciidoctor
|
|
23
23
|
:uri-repo: {uri-org}/asciidoctor
|
data/README.adoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Asciidoctor
|
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
|
3
|
-
v2.0.
|
|
3
|
+
v2.0.22, 2024-03-08
|
|
4
4
|
// settings:
|
|
5
5
|
:idprefix:
|
|
6
6
|
:idseparator: -
|
|
@@ -16,7 +16,7 @@ ifdef::env-github[]
|
|
|
16
16
|
:warning-caption: :warning:
|
|
17
17
|
endif::[]
|
|
18
18
|
// Variables:
|
|
19
|
-
:release-version: 2.0.
|
|
19
|
+
:release-version: 2.0.22
|
|
20
20
|
// URLs:
|
|
21
21
|
:url-org: https://github.com/asciidoctor
|
|
22
22
|
:url-repo: {url-org}/asciidoctor
|
data/asciidoctor.gemspec
CHANGED
|
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
|
|
|
39
39
|
# erubi is needed for testing alternate eRuby impls
|
|
40
40
|
s.add_development_dependency 'erubi', '~> 1.10.0'
|
|
41
41
|
s.add_development_dependency 'haml', '~> 6.1.0'
|
|
42
|
-
s.add_development_dependency 'minitest', '~> 5.
|
|
42
|
+
s.add_development_dependency 'minitest', '~> 5.22.0'
|
|
43
43
|
s.add_development_dependency 'nokogiri', '~> 1.13.0'
|
|
44
44
|
s.add_development_dependency 'rake', '~> 12.3.0'
|
|
45
45
|
s.add_development_dependency 'slim', '~> 4.1.0'
|
data/data/reference/syntax.adoc
CHANGED
|
@@ -130,7 +130,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
|
|
|
130
130
|
#content::before{content:none}
|
|
131
131
|
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
|
132
132
|
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
|
133
|
-
#header>h1:only-child
|
|
133
|
+
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
|
|
134
134
|
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
|
|
135
135
|
#header .details span:first-child{margin-left:-.125em}
|
|
136
136
|
#header .details span.email a{color:rgba(0,0,0,.85)}
|
|
@@ -152,6 +152,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
|
|
|
152
152
|
#toctitle{color:#7a2518;font-size:1.2em}
|
|
153
153
|
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
|
154
154
|
body.toc2{padding-left:15em;padding-right:0}
|
|
155
|
+
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
|
155
156
|
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
|
156
157
|
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
|
157
158
|
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
|
@@ -317,7 +318,7 @@ a.image{text-decoration:none;display:inline-block}
|
|
|
317
318
|
a.image object{pointer-events:none}
|
|
318
319
|
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
|
319
320
|
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
|
320
|
-
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
|
321
|
+
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
|
|
321
322
|
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
|
322
323
|
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
|
323
324
|
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
|
@@ -354,8 +354,8 @@ class AbstractNode
|
|
|
354
354
|
#
|
|
355
355
|
# First, and foremost, the target image path is cleaned if the document safe mode level
|
|
356
356
|
# is set to at least SafeMode::SAFE (a condition which is true by default) to prevent access
|
|
357
|
-
# to ancestor paths in the filesystem. The image data is then read and converted to
|
|
358
|
-
#
|
|
357
|
+
# to ancestor paths in the filesystem. The image data is then read and converted to base64.
|
|
358
|
+
# Finally, a data URI is built which can be used in an image tag.
|
|
359
359
|
#
|
|
360
360
|
# target_image - A String path to the target image
|
|
361
361
|
# asset_dir_key - The String attribute key used to lookup the directory where
|
|
@@ -376,8 +376,8 @@ class AbstractNode
|
|
|
376
376
|
end
|
|
377
377
|
|
|
378
378
|
if ::File.readable? image_path
|
|
379
|
-
# NOTE
|
|
380
|
-
%(data:#{mimetype};base64,#{::
|
|
379
|
+
# NOTE pack 'm0' is equivalent to Base64.strict_encode64
|
|
380
|
+
%(data:#{mimetype};base64,#{[(::File.binread image_path)].pack 'm0'})
|
|
381
381
|
else
|
|
382
382
|
logger.warn %(image to embed not found or not readable: #{image_path})
|
|
383
383
|
%(data:#{mimetype};base64,)
|
|
@@ -410,8 +410,8 @@ class AbstractNode
|
|
|
410
410
|
|
|
411
411
|
begin
|
|
412
412
|
mimetype, bindata = ::OpenURI.open_uri(image_uri, URI_READ_MODE) {|f| [f.content_type, f.read] }
|
|
413
|
-
# NOTE
|
|
414
|
-
%(data:#{mimetype};base64,#{
|
|
413
|
+
# NOTE pack 'm0' is equivalent to Base64.strict_encode64
|
|
414
|
+
%(data:#{mimetype};base64,#{[bindata].pack 'm0'})
|
|
415
415
|
rescue
|
|
416
416
|
logger.warn %(could not retrieve image data from URI: #{image_uri})
|
|
417
417
|
image_uri
|
|
@@ -44,7 +44,8 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
44
44
|
end
|
|
45
45
|
root_tag_idx = result.size
|
|
46
46
|
id = node.id
|
|
47
|
-
|
|
47
|
+
abstract = find_root_abstract node
|
|
48
|
+
result << (document_info_tag node, abstract) unless node.noheader
|
|
48
49
|
if manpage
|
|
49
50
|
result << '<refentry>'
|
|
50
51
|
result << '<refmeta>'
|
|
@@ -61,7 +62,9 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
61
62
|
unless (docinfo_content = node.docinfo :header).empty?
|
|
62
63
|
result << docinfo_content
|
|
63
64
|
end
|
|
64
|
-
|
|
65
|
+
abstract = extract_abstract node, abstract if abstract
|
|
66
|
+
result << (node.blocks.map {|block| block.convert }.compact.join LF) if node.blocks?
|
|
67
|
+
restore_abstract abstract if abstract
|
|
65
68
|
unless (docinfo_content = node.docinfo :footer).empty?
|
|
66
69
|
result << docinfo_content
|
|
67
70
|
end
|
|
@@ -73,7 +76,15 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
73
76
|
result.join LF
|
|
74
77
|
end
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
def convert_embedded node
|
|
80
|
+
# NOTE in DocBook 5, the root abstract must be in the info tag and is thus not part of the body
|
|
81
|
+
if @backend == 'docbook5' && (abstract = find_root_abstract node)
|
|
82
|
+
abstract = extract_abstract node, abstract
|
|
83
|
+
end
|
|
84
|
+
result = node.blocks.map {|block| block.convert }.compact.join LF
|
|
85
|
+
restore_abstract abstract if abstract
|
|
86
|
+
result
|
|
87
|
+
end
|
|
77
88
|
|
|
78
89
|
def convert_section node
|
|
79
90
|
if node.document.doctype == 'manpage'
|
|
@@ -183,27 +194,11 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
183
194
|
end
|
|
184
195
|
|
|
185
196
|
def convert_image node
|
|
186
|
-
# NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
|
|
187
|
-
# See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
|
|
188
|
-
if node.attr? 'scaledwidth'
|
|
189
|
-
width_attribute = %( width="#{node.attr 'scaledwidth'}")
|
|
190
|
-
depth_attribute = ''
|
|
191
|
-
scale_attribute = ''
|
|
192
|
-
elsif node.attr? 'scale'
|
|
193
|
-
# QUESTION should we set the viewport using width and depth? (the scaled image would be contained within this box)
|
|
194
|
-
#width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
|
195
|
-
#depth_attribute = (node.attr? 'height') ? %( depth="#{node.attr 'height'}") : ''
|
|
196
|
-
scale_attribute = %( scale="#{node.attr 'scale'}")
|
|
197
|
-
else
|
|
198
|
-
width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
|
|
199
|
-
depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
|
|
200
|
-
scale_attribute = ''
|
|
201
|
-
end
|
|
202
197
|
align_attribute = (node.attr? 'align') ? %( align="#{node.attr 'align'}") : ''
|
|
203
198
|
|
|
204
199
|
mediaobject = %(<mediaobject>
|
|
205
200
|
<imageobject>
|
|
206
|
-
<imagedata fileref="#{node.image_uri
|
|
201
|
+
<imagedata fileref="#{node.image_uri node.attr 'target'}"#{image_size_attributes node.attributes}#{align_attribute}/>
|
|
207
202
|
</imageobject>
|
|
208
203
|
<textobject><phrase>#{node.alt}</phrase></textobject>
|
|
209
204
|
</mediaobject>)
|
|
@@ -308,13 +303,17 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
308
303
|
def convert_open node
|
|
309
304
|
case node.style
|
|
310
305
|
when 'abstract'
|
|
311
|
-
if node.parent == node.document && node.document.doctype == 'book'
|
|
312
|
-
logger.warn 'abstract block cannot be used in a document without a
|
|
306
|
+
if (parent = node.parent) == node.document && node.document.doctype == 'book'
|
|
307
|
+
logger.warn 'abstract block cannot be used in a document without a doctitle when doctype is book. Excluding block content.'
|
|
313
308
|
''
|
|
314
309
|
else
|
|
315
|
-
%(<abstract>
|
|
310
|
+
result = %(<abstract>
|
|
316
311
|
#{title_tag node}#{enclose_content node}
|
|
317
312
|
</abstract>)
|
|
313
|
+
if @backend == 'docbook5' && !(node.option? 'root') && (parent.context == :open ? parent.style == 'partintro' : parent.context == :section && parent.sectname == 'partintro') && node == parent.blocks[0]
|
|
314
|
+
result = %(<info>\n#{result}\n</info>)
|
|
315
|
+
end
|
|
316
|
+
result
|
|
318
317
|
end
|
|
319
318
|
when 'partintro'
|
|
320
319
|
if node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
|
|
@@ -536,11 +535,9 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
536
535
|
end
|
|
537
536
|
|
|
538
537
|
def convert_inline_image node
|
|
539
|
-
width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
|
|
540
|
-
depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
|
|
541
538
|
%(<inlinemediaobject#{common_attributes nil, node.role}>
|
|
542
539
|
<imageobject>
|
|
543
|
-
<imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{
|
|
540
|
+
<imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{image_size_attributes node.attributes}/>
|
|
544
541
|
</imageobject>
|
|
545
542
|
<textobject><phrase>#{node.alt}</phrase></textobject>
|
|
546
543
|
</inlinemediaobject>)
|
|
@@ -648,6 +645,23 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
648
645
|
end
|
|
649
646
|
end
|
|
650
647
|
|
|
648
|
+
def image_size_attributes attributes
|
|
649
|
+
# NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
|
|
650
|
+
# See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
|
|
651
|
+
if attributes.key? 'scaledwidth'
|
|
652
|
+
%( width="#{attributes['scaledwidth']}")
|
|
653
|
+
elsif attributes.key? 'scale'
|
|
654
|
+
# QUESTION should we set the viewport using width and depth? (the scaled image would be contained within this box)
|
|
655
|
+
#width_attribute = (attributes.key? 'width') ? %( width="#{attributes['width']}") : ''
|
|
656
|
+
#depth_attribute = (attributes.key? 'height') ? %( depth="#{attributes['height']}") : ''
|
|
657
|
+
%( scale="#{attributes['scale']}")
|
|
658
|
+
else
|
|
659
|
+
width_attribute = (attributes.key? 'width') ? %( contentwidth="#{attributes['width']}") : ''
|
|
660
|
+
depth_attribute = (attributes.key? 'height') ? %( contentdepth="#{attributes['height']}") : ''
|
|
661
|
+
%(#{width_attribute}#{depth_attribute})
|
|
662
|
+
end
|
|
663
|
+
end
|
|
664
|
+
|
|
651
665
|
def author_tag doc, author
|
|
652
666
|
result = []
|
|
653
667
|
result << '<author>'
|
|
@@ -661,7 +675,7 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
661
675
|
result.join LF
|
|
662
676
|
end
|
|
663
677
|
|
|
664
|
-
def document_info_tag doc
|
|
678
|
+
def document_info_tag doc, abstract
|
|
665
679
|
result = ['<info>']
|
|
666
680
|
unless doc.notitle
|
|
667
681
|
if (title = doc.doctitle partition: true, use_fallback: true).subtitle?
|
|
@@ -715,11 +729,37 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
715
729
|
result << docinfo_content
|
|
716
730
|
end
|
|
717
731
|
end
|
|
732
|
+
if abstract
|
|
733
|
+
abstract.set_option 'root'
|
|
734
|
+
result << (convert abstract, abstract.node_name)
|
|
735
|
+
abstract.remove_attr 'root-option'
|
|
736
|
+
end
|
|
718
737
|
result << '</info>'
|
|
719
738
|
|
|
720
739
|
result.join LF
|
|
721
740
|
end
|
|
722
741
|
|
|
742
|
+
def find_root_abstract doc
|
|
743
|
+
return unless doc.blocks?
|
|
744
|
+
if (first_block = doc.blocks[0]).context == :preamble
|
|
745
|
+
return unless (first_block = first_block.blocks[0])
|
|
746
|
+
elsif first_block.context == :section
|
|
747
|
+
return first_block if first_block.sectname == 'abstract'
|
|
748
|
+
return unless first_block.sectname == 'preface' && (first_block = first_block.blocks[0])
|
|
749
|
+
end
|
|
750
|
+
return first_block if first_block.style == 'abstract' && first_block.context == :open
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
def extract_abstract document, abstract
|
|
754
|
+
parent = abstract.parent
|
|
755
|
+
parent = parent.parent while parent != document && parent.blocks.length == 1
|
|
756
|
+
parent.blocks.delete_at 0
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
def restore_abstract abstract
|
|
760
|
+
abstract.parent.blocks.insert 0, abstract
|
|
761
|
+
end
|
|
762
|
+
|
|
723
763
|
def get_root_document node
|
|
724
764
|
while (node = node.document).nested?
|
|
725
765
|
node = node.parent_document
|
|
@@ -742,26 +782,18 @@ class Converter::DocBook5Converter < Converter::Base
|
|
|
742
782
|
|
|
743
783
|
def cover_tag doc, face, use_placeholder = false
|
|
744
784
|
if (cover_image = doc.attr %(#{face}-cover-image))
|
|
745
|
-
width_attr = ''
|
|
746
|
-
depth_attr = ''
|
|
747
785
|
if (cover_image.include? ':') && ImageMacroRx =~ cover_image
|
|
748
|
-
attrlist = $2
|
|
749
|
-
cover_image = doc.image_uri
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
width_attr = %( width="#{attrs['scaledwidth']}")
|
|
755
|
-
else
|
|
756
|
-
width_attr = %( contentwidth="#{attrs['width']}") if attrs.key? 'width'
|
|
757
|
-
depth_attr = %( contentdepth="#{attrs['height']}") if attrs.key? 'height'
|
|
758
|
-
end
|
|
759
|
-
end
|
|
786
|
+
target, attrlist = $1, $2
|
|
787
|
+
cover_image = doc.image_uri target
|
|
788
|
+
# NOTE scalefit="1" is the default for a cover image
|
|
789
|
+
size_attrs = image_size_attributes (AttributeList.new attrlist).parse %w(alt width height) if attrlist
|
|
790
|
+
else
|
|
791
|
+
size_attrs = ''
|
|
760
792
|
end
|
|
761
793
|
%(<cover role="#{face}">
|
|
762
794
|
<mediaobject>
|
|
763
795
|
<imageobject>
|
|
764
|
-
<imagedata fileref="#{cover_image}"#{
|
|
796
|
+
<imagedata fileref="#{cover_image}"#{size_attrs}/>
|
|
765
797
|
</imageobject>
|
|
766
798
|
</mediaobject>
|
|
767
799
|
</cover>)
|
|
@@ -748,7 +748,7 @@ Your browser does not support the audio tag.
|
|
|
748
748
|
def convert_open node
|
|
749
749
|
if (style = node.style) == 'abstract'
|
|
750
750
|
if node.parent == node.document && node.document.doctype == 'book'
|
|
751
|
-
logger.warn 'abstract block cannot be used in a document without a
|
|
751
|
+
logger.warn 'abstract block cannot be used in a document without a doctitle when doctype is book. Excluding block content.'
|
|
752
752
|
''
|
|
753
753
|
else
|
|
754
754
|
id_attr = node.id ? %( id="#{node.id}") : ''
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module Asciidoctor
|
|
3
|
-
# A built-in {Converter} implementation that generates the man page (
|
|
3
|
+
# A built-in {Converter} implementation that generates the man page (groff) format.
|
|
4
4
|
#
|
|
5
5
|
# The output of this converter adheres to the man definition as defined by
|
|
6
6
|
# groff and uses the manpage output of the DocBook toolchain as a foundation.
|
|
@@ -432,7 +432,7 @@ allbox tab(:);'
|
|
|
432
432
|
when :literal
|
|
433
433
|
cell_content = %(.nf#{LF}#{manify cell.text, whitespace: :preserve}#{LF}.fi)
|
|
434
434
|
else
|
|
435
|
-
cell_content =
|
|
435
|
+
cell_content = cell.content.map {|p| manify p, whitespace: :normalize }.join %(#{LF}.sp#{LF})
|
|
436
436
|
end
|
|
437
437
|
row_text[row_index] << %(#{cell_content}#{LF})
|
|
438
438
|
else # tsec == :head || tsec == :foot
|
|
@@ -476,21 +476,14 @@ allbox tab(:);'
|
|
|
476
476
|
end unless rows.empty?
|
|
477
477
|
end
|
|
478
478
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
# end
|
|
485
|
-
#end
|
|
486
|
-
# FIXME temporary fix to get basic table to display
|
|
487
|
-
result << LF
|
|
488
|
-
result << ('lt ' * row_header[0].size).chop
|
|
489
|
-
|
|
490
|
-
result << %(.#{LF})
|
|
491
|
-
row_text.each do |row|
|
|
492
|
-
result << row.join
|
|
479
|
+
if node.has_header_option && (header_row_text = row_text[0])
|
|
480
|
+
result << %(#{LF}#{row_header[0].join ' '}.)
|
|
481
|
+
result << %(#{LF}#{header_row_text.join})
|
|
482
|
+
result << '.T&'
|
|
483
|
+
row_text = row_text.slice 1, row_text.length
|
|
493
484
|
end
|
|
485
|
+
result << %(#{LF}#{row_header[0].map { 'lt' }.join ' '}.#{LF})
|
|
486
|
+
row_text.each {|row| result << row.join }
|
|
494
487
|
result << %(.TE#{LF}.sp)
|
|
495
488
|
result.join
|
|
496
489
|
end
|
|
@@ -712,40 +705,38 @@ allbox tab(:);'
|
|
|
712
705
|
else
|
|
713
706
|
str = str.tr_s WHITESPACE, ' '
|
|
714
707
|
end
|
|
715
|
-
str = str
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
.gsub(ESC_FS, '.') # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
|
|
748
|
-
.rstrip # strip trailing space
|
|
708
|
+
str = str.
|
|
709
|
+
gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' }. # literal backslash (not a troff escape sequence)
|
|
710
|
+
gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
|
|
711
|
+
gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
|
|
712
|
+
gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#{$1}"#{$2}") : %(.#{$1}"#{$2.rstrip}"#{LF}#{rest}) }. # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
|
|
713
|
+
gsub('-', '\-').
|
|
714
|
+
gsub('<', '<').
|
|
715
|
+
gsub('>', '>').
|
|
716
|
+
gsub('+', '+'). # plus sign; alternately could use \c(pl
|
|
717
|
+
gsub(' ', '\~'). # non-breaking space
|
|
718
|
+
gsub('©', '\(co'). # copyright sign
|
|
719
|
+
gsub('®', '\(rg'). # registered sign
|
|
720
|
+
gsub('™', '\(tm'). # trademark sign
|
|
721
|
+
gsub('°', '\(de'). # degree sign
|
|
722
|
+
gsub(' ', ' '). # thin space
|
|
723
|
+
gsub('–', '\(en'). # en dash
|
|
724
|
+
gsub(EmDashCharRefRx, '\(em'). # em dash
|
|
725
|
+
gsub('‘', '\(oq'). # left single quotation mark
|
|
726
|
+
gsub('’', '\(cq'). # right single quotation mark
|
|
727
|
+
gsub('“', '\(lq'). # left double quotation mark
|
|
728
|
+
gsub('”', '\(rq'). # right double quotation mark
|
|
729
|
+
gsub('←', '\(<-'). # leftwards arrow
|
|
730
|
+
gsub('→', '\(->'). # rightwards arrow
|
|
731
|
+
gsub('⇐', '\(lA'). # leftwards double arrow
|
|
732
|
+
gsub('⇒', '\(rA'). # rightwards double arrow
|
|
733
|
+
gsub('​', '\:'). # zero width space
|
|
734
|
+
gsub('&', '&'). # literal ampersand (NOTE must take place after any other replacement that includes &)
|
|
735
|
+
gsub('\'', '\*(Aq'). # apostrophe / neutral single quote
|
|
736
|
+
gsub(MockMacroRx, '\1'). # mock boundary
|
|
737
|
+
gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
|
|
738
|
+
gsub(ESC_FS, '.'). # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
|
|
739
|
+
rstrip # strip trailing space
|
|
749
740
|
opts[:append_newline] ? %(#{str}#{LF}) : str
|
|
750
741
|
end
|
|
751
742
|
|
data/lib/asciidoctor/logging.rb
CHANGED
|
@@ -40,6 +40,7 @@ class MemoryLogger < ::Logger
|
|
|
40
40
|
attr_reader :messages
|
|
41
41
|
|
|
42
42
|
def initialize
|
|
43
|
+
super nil
|
|
43
44
|
self.level = WARN
|
|
44
45
|
@messages = []
|
|
45
46
|
end
|
|
@@ -67,6 +68,7 @@ class NullLogger < ::Logger
|
|
|
67
68
|
attr_reader :max_severity
|
|
68
69
|
|
|
69
70
|
def initialize
|
|
71
|
+
super nil
|
|
70
72
|
self.level = WARN
|
|
71
73
|
end
|
|
72
74
|
|
data/lib/asciidoctor/parser.rb
CHANGED
|
@@ -43,6 +43,12 @@ class Parser
|
|
|
43
43
|
|
|
44
44
|
AuthorKeys = ['author', 'authorinitials', 'firstname', 'middlename', 'lastname', 'email']
|
|
45
45
|
|
|
46
|
+
ListContinuationMarker = ::Module.new
|
|
47
|
+
|
|
48
|
+
ListContinuationPlaceholder = ::String.new.extend ListContinuationMarker
|
|
49
|
+
|
|
50
|
+
ListContinuationString = (::String.new LIST_CONTINUATION).extend ListContinuationMarker
|
|
51
|
+
|
|
46
52
|
# Internal: A Hash mapping horizontal alignment abbreviations to alignments
|
|
47
53
|
# that can be applied to a table cell (or to all cells in a column)
|
|
48
54
|
TableCellHorzAlignments = {
|
|
@@ -555,6 +561,7 @@ class Parser
|
|
|
555
561
|
# process lines verbatim
|
|
556
562
|
if style && Compliance.strict_verbatim_paragraphs && (VERBATIM_STYLES.include? style)
|
|
557
563
|
block_context = style.to_sym
|
|
564
|
+
cloaked_context = :paragraph
|
|
558
565
|
reader.unshift_line this_line
|
|
559
566
|
# advance to block parsing =>
|
|
560
567
|
break
|
|
@@ -812,16 +819,17 @@ class Parser
|
|
|
812
819
|
unless block
|
|
813
820
|
case block_context
|
|
814
821
|
when :listing, :source
|
|
815
|
-
if block_context == :source || (
|
|
816
|
-
if language
|
|
822
|
+
if block_context == :source || (language = attributes[1] ? nil : attributes[2] || doc_attrs['source-language'])
|
|
823
|
+
if language # :listing
|
|
817
824
|
attributes['style'] = 'source'
|
|
818
825
|
attributes['language'] = language
|
|
819
826
|
AttributeList.rekey attributes, [nil, nil, 'linenums']
|
|
820
|
-
else
|
|
827
|
+
else # :source
|
|
821
828
|
AttributeList.rekey attributes, [nil, 'language', 'linenums']
|
|
822
829
|
if doc_attrs.key? 'source-language'
|
|
823
830
|
attributes['language'] = doc_attrs['source-language']
|
|
824
831
|
end unless attributes.key? 'language'
|
|
832
|
+
attributes['cloaked-context'] = cloaked_context unless cloaked_context == :listing
|
|
825
833
|
end
|
|
826
834
|
if attributes['linenums-option'] || doc_attrs['source-linenums-option']
|
|
827
835
|
attributes['linenums'] = ''
|
|
@@ -850,6 +858,7 @@ class Parser
|
|
|
850
858
|
else
|
|
851
859
|
attributes['language'] = language
|
|
852
860
|
end
|
|
861
|
+
attributes['cloaked-context'] = cloaked_context
|
|
853
862
|
if attributes['linenums-option'] || doc_attrs['source-linenums-option']
|
|
854
863
|
attributes['linenums'] = ''
|
|
855
864
|
end unless attributes.key? 'linenums'
|
|
@@ -1420,17 +1429,18 @@ class Parser
|
|
|
1420
1429
|
# the termination of the list
|
|
1421
1430
|
break if is_sibling_list_item?(this_line, list_type, sibling_trait)
|
|
1422
1431
|
|
|
1432
|
+
this_line = ListContinuationString if this_line == LIST_CONTINUATION
|
|
1423
1433
|
prev_line = buffer.empty? ? nil : buffer[-1]
|
|
1424
1434
|
|
|
1425
|
-
if
|
|
1435
|
+
if ListContinuationMarker === prev_line
|
|
1426
1436
|
if continuation == :inactive
|
|
1427
1437
|
continuation = :active
|
|
1428
1438
|
has_text = true
|
|
1429
|
-
buffer[-1] =
|
|
1439
|
+
buffer[-1] = ListContinuationPlaceholder unless within_nested_list
|
|
1430
1440
|
end
|
|
1431
1441
|
|
|
1432
1442
|
# dealing with adjacent list continuations (which is really a syntax error)
|
|
1433
|
-
if
|
|
1443
|
+
if ListContinuationMarker === this_line
|
|
1434
1444
|
if continuation != :frozen
|
|
1435
1445
|
continuation = :frozen
|
|
1436
1446
|
buffer << this_line
|
|
@@ -1489,7 +1499,7 @@ class Parser
|
|
|
1489
1499
|
(ch0 == '[' && (BlockAttributeLineRx.match? this_line)) || (ch0 == ':' && (AttributeEntryRx.match? this_line))
|
|
1490
1500
|
buffer << this_line
|
|
1491
1501
|
else
|
|
1492
|
-
if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx]
|
|
1502
|
+
if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line })
|
|
1493
1503
|
within_nested_list = true
|
|
1494
1504
|
if nested_list_type == :dlist && $3.nil_or_empty?
|
|
1495
1505
|
# get greedy again
|
|
@@ -1510,7 +1520,7 @@ class Parser
|
|
|
1510
1520
|
|
|
1511
1521
|
if this_line == LIST_CONTINUATION
|
|
1512
1522
|
detached_continuation = buffer.size
|
|
1513
|
-
buffer <<
|
|
1523
|
+
buffer << ListContinuationString
|
|
1514
1524
|
elsif has_text # has_text only relevant for dlist, which is more greedy until it has text for an item; has_text is always true for all other lists
|
|
1515
1525
|
# in this block, we have to see whether we stay in the list
|
|
1516
1526
|
# TODO any way to combine this with the check after skipping blank lines?
|
|
@@ -1543,6 +1553,9 @@ class Parser
|
|
|
1543
1553
|
buffer << this_line
|
|
1544
1554
|
has_text = true
|
|
1545
1555
|
end
|
|
1556
|
+
elsif ListContinuationMarker === this_line
|
|
1557
|
+
has_text = true
|
|
1558
|
+
buffer << this_line
|
|
1546
1559
|
else
|
|
1547
1560
|
has_text = true unless this_line.empty?
|
|
1548
1561
|
if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line })
|
|
@@ -1559,16 +1572,17 @@ class Parser
|
|
|
1559
1572
|
|
|
1560
1573
|
reader.unshift_line this_line if this_line
|
|
1561
1574
|
|
|
1562
|
-
buffer[detached_continuation] =
|
|
1575
|
+
buffer[detached_continuation] = ListContinuationPlaceholder if detached_continuation
|
|
1563
1576
|
|
|
1564
1577
|
until buffer.empty?
|
|
1578
|
+
# drop optional trailing continuation
|
|
1579
|
+
if ListContinuationMarker === (last_line = buffer[-1])
|
|
1580
|
+
buffer.pop
|
|
1581
|
+
break
|
|
1565
1582
|
# strip trailing blank lines to prevent empty blocks
|
|
1566
|
-
|
|
1583
|
+
elsif last_line.empty?
|
|
1567
1584
|
buffer.pop
|
|
1568
1585
|
else
|
|
1569
|
-
# drop optional trailing continuation
|
|
1570
|
-
# (a blank line would have served the same purpose in the document)
|
|
1571
|
-
buffer.pop if last_line == LIST_CONTINUATION
|
|
1572
1586
|
break
|
|
1573
1587
|
end
|
|
1574
1588
|
end
|
data/lib/asciidoctor/reader.rb
CHANGED
|
@@ -1039,6 +1039,7 @@ class PreprocessorReader < Reader
|
|
|
1039
1039
|
# if running in SafeMode::SECURE or greater, don't process this directive
|
|
1040
1040
|
# however, be friendly and at least make it a link to the source document
|
|
1041
1041
|
elsif doc.safe >= SafeMode::SECURE
|
|
1042
|
+
expanded_target = %(pass:c[#{expanded_target}]) if expanded_target.include? ' '
|
|
1042
1043
|
# FIXME we don't want to use a link macro if we are in a verbatim context
|
|
1043
1044
|
replace_next_line %(link:#{expanded_target}[role=include])
|
|
1044
1045
|
elsif @maxdepth
|
|
@@ -1238,7 +1239,10 @@ class PreprocessorReader < Reader
|
|
|
1238
1239
|
def resolve_include_path target, attrlist, attributes
|
|
1239
1240
|
doc = @document
|
|
1240
1241
|
if (Helpers.uriish? target) || (::String === @dir ? nil : (target = %(#{@dir}/#{target})))
|
|
1241
|
-
|
|
1242
|
+
unless doc.attr? 'allow-uri-read'
|
|
1243
|
+
target = %(pass:c[#{target}]) if target.include? ' '
|
|
1244
|
+
return replace_next_line %(link:#{target}[role=include])
|
|
1245
|
+
end
|
|
1242
1246
|
if doc.attr? 'cache-uri'
|
|
1243
1247
|
# caching requires the open-uri-cached gem to be installed
|
|
1244
1248
|
# processing will be automatically aborted if these libraries can't be opened
|
data/lib/asciidoctor/rx.rb
CHANGED
|
@@ -103,6 +103,7 @@ module Asciidoctor
|
|
|
103
103
|
# }
|
|
104
104
|
# // end::try-catch[]
|
|
105
105
|
# NOTE m flag is required for Asciidoctor.js
|
|
106
|
+
# NOTE the regex checks for \r to account of include files that use Windows newlines
|
|
106
107
|
TagDirectiveRx = /\b(?:tag|(e)nd)::(\S+?)\[\](?=$|[ \r])/m
|
|
107
108
|
|
|
108
109
|
## Attribute entries and references
|
|
@@ -513,12 +514,12 @@ module Asciidoctor
|
|
|
513
514
|
#
|
|
514
515
|
# https://github.com
|
|
515
516
|
# https://github.com[GitHub]
|
|
516
|
-
# <https://github.com>
|
|
517
|
+
# <https://github.com> <= angle brackets not included in autolink
|
|
517
518
|
# link:https://github.com[]
|
|
518
519
|
# "https://github.com[]"
|
|
519
520
|
# (https://github.com) <= parenthesis not included in autolink
|
|
520
521
|
#
|
|
521
|
-
InlineLinkRx = %r((^|link:|#{CG_BLANK}
|
|
522
|
+
InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?<()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]*?)>|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
|
|
522
523
|
|
|
523
524
|
# Match a link or e-mail inline macro.
|
|
524
525
|
#
|
|
@@ -445,7 +445,14 @@ module Substitutors
|
|
|
445
445
|
# indexterm:[Tigers,Big cats]
|
|
446
446
|
if (attrlist = normalize_text $2, true, true).include? '='
|
|
447
447
|
if (primary = (attrs = (AttributeList.new attrlist, self).parse)[1])
|
|
448
|
-
|
|
448
|
+
terms = [primary]
|
|
449
|
+
if (secondary = attrs[2])
|
|
450
|
+
terms << secondary
|
|
451
|
+
if (tertiary = attrs[3])
|
|
452
|
+
terms << tertiary
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
attrs['terms'] = terms
|
|
449
456
|
if (see_also = attrs['see-also'])
|
|
450
457
|
attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
|
|
451
458
|
end
|
|
@@ -524,97 +531,101 @@ module Substitutors
|
|
|
524
531
|
end
|
|
525
532
|
|
|
526
533
|
if found_colon && (text.include? '://')
|
|
527
|
-
# inline urls, target[text] (optionally prefixed with link:
|
|
534
|
+
# inline urls, target[text] (optionally prefixed with link: or enclosed in <>)
|
|
528
535
|
text = text.gsub InlineLinkRx do
|
|
529
|
-
if
|
|
530
|
-
# honor the
|
|
531
|
-
next
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
link_text = nil if (link_text = $4).empty?
|
|
536
|
+
if $2 && !$5
|
|
537
|
+
# honor the escapes
|
|
538
|
+
next $&.slice 1, $&.length if $1.start_with? RS
|
|
539
|
+
next %(#{$1}#{$&.slice $1.length + 1, $&.length}) if $3.start_with? RS
|
|
540
|
+
target = $3 + $6
|
|
541
|
+
next $& if target == $3
|
|
542
|
+
doc.register :links, target
|
|
543
|
+
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
|
544
|
+
(Inline.new self, :anchor, link_text, type: :link, target: target, attributes: { 'role' => 'bare' }).convert
|
|
539
545
|
else
|
|
540
|
-
#
|
|
541
|
-
#
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
# move trailing ); out of URL
|
|
554
|
-
target = target.chop
|
|
555
|
-
suffix = ');'
|
|
556
|
-
else
|
|
557
|
-
# move trailing ; out of URL
|
|
558
|
-
suffix = ';'
|
|
546
|
+
# honor the escape
|
|
547
|
+
next %(#{$1}#{$&.slice $1.length + 1, $&.length}) if $3.start_with? RS
|
|
548
|
+
prefix, target, suffix = $1, $3 + ($4 || $7), ''
|
|
549
|
+
# NOTE if $5 is set (the attrlist), we're looking at a formal macro (e.g., https://example.org[])
|
|
550
|
+
if $5
|
|
551
|
+
prefix = '' if prefix == 'link:'
|
|
552
|
+
link_text = nil if (link_text = $5).empty?
|
|
553
|
+
else
|
|
554
|
+
case prefix
|
|
555
|
+
# invalid macro syntax (link: prefix w/o trailing square brackets or URL enclosed in quotes)
|
|
556
|
+
# FIXME we probably shouldn't even get here when the link: prefix is present; the regex is doing too much
|
|
557
|
+
when 'link:', ?", ?'
|
|
558
|
+
next $&
|
|
559
559
|
end
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
560
|
+
case $8
|
|
561
|
+
when ';'
|
|
562
|
+
if (target = target.chop).end_with? ')'
|
|
563
|
+
# move trailing ); out of URL
|
|
564
|
+
target = target.chop
|
|
565
|
+
suffix = ');'
|
|
566
|
+
else
|
|
567
|
+
# move trailing ; out of URL
|
|
568
|
+
suffix = ';'
|
|
569
|
+
end
|
|
570
|
+
# NOTE handle case when modified target is a bare URI scheme (e.g., http://)
|
|
571
|
+
next $& if target == $3
|
|
572
|
+
when ':'
|
|
573
|
+
if (target = target.chop).end_with? ')'
|
|
574
|
+
# move trailing ): out of URL
|
|
575
|
+
target = target.chop
|
|
576
|
+
suffix = '):'
|
|
577
|
+
else
|
|
578
|
+
# move trailing : out of URL
|
|
579
|
+
suffix = ':'
|
|
580
|
+
end
|
|
581
|
+
# NOTE handle case when modified target is a bare URI scheme (e.g., http://)
|
|
582
|
+
next $& if target == $3
|
|
570
583
|
end
|
|
571
|
-
# NOTE handle case when modified target is a URI scheme (e.g., http://)
|
|
572
|
-
next $& if target.end_with? '://'
|
|
573
584
|
end
|
|
574
|
-
end
|
|
575
585
|
|
|
576
|
-
|
|
586
|
+
link_opts = { type: :link }
|
|
577
587
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
588
|
+
if link_text
|
|
589
|
+
new_link_text = link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
|
|
590
|
+
if !doc.compat_mode && (link_text.include? '=')
|
|
591
|
+
# NOTE if an equals sign (=) is present, extract attributes from link text
|
|
592
|
+
link_text, attrs = extract_attributes_from_text link_text, ''
|
|
593
|
+
new_link_text = link_text
|
|
594
|
+
link_opts[:id] = attrs['id']
|
|
595
|
+
end
|
|
586
596
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
597
|
+
if link_text.end_with? '^'
|
|
598
|
+
new_link_text = link_text = link_text.chop
|
|
599
|
+
if attrs
|
|
600
|
+
attrs['window'] ||= '_blank'
|
|
601
|
+
else
|
|
602
|
+
attrs = { 'window' => '_blank' }
|
|
603
|
+
end
|
|
593
604
|
end
|
|
594
|
-
end
|
|
595
605
|
|
|
596
|
-
|
|
597
|
-
|
|
606
|
+
if new_link_text && new_link_text.empty?
|
|
607
|
+
# NOTE the modified target will not be a bare URI scheme (e.g., http://) in this case
|
|
608
|
+
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
|
609
|
+
bare = true
|
|
610
|
+
end
|
|
611
|
+
else
|
|
612
|
+
# NOTE the modified target will not be a bare URI scheme (e.g., http://) in this case
|
|
598
613
|
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
|
599
614
|
bare = true
|
|
600
615
|
end
|
|
601
|
-
else
|
|
602
|
-
# NOTE it's not possible for the URI scheme to be bare in this case
|
|
603
|
-
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
|
|
604
|
-
bare = true
|
|
605
|
-
end
|
|
606
616
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
617
|
+
if bare
|
|
618
|
+
if attrs
|
|
619
|
+
attrs['role'] = (attrs.key? 'role') ? %(bare #{attrs['role']}) : 'bare'
|
|
620
|
+
else
|
|
621
|
+
attrs = { 'role' => 'bare' }
|
|
622
|
+
end
|
|
612
623
|
end
|
|
613
|
-
end
|
|
614
624
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
625
|
+
doc.register :links, (link_opts[:target] = target)
|
|
626
|
+
link_opts[:attributes] = attrs if attrs
|
|
627
|
+
%(#{prefix}#{(Inline.new self, :anchor, link_text, link_opts).convert}#{suffix})
|
|
628
|
+
end
|
|
618
629
|
end
|
|
619
630
|
end
|
|
620
631
|
|
data/lib/asciidoctor/version.rb
CHANGED
data/lib/asciidoctor.rb
CHANGED
|
@@ -6,7 +6,6 @@ if RUBY_ENGINE == 'opal'
|
|
|
6
6
|
# this require is satisfied by the Asciidoctor.js build; it augments the Ruby environment for Asciidoctor.js
|
|
7
7
|
require 'asciidoctor/js'
|
|
8
8
|
else
|
|
9
|
-
autoload :Base64, 'base64'
|
|
10
9
|
require 'cgi/util'
|
|
11
10
|
autoload :OpenURI, 'open-uri'
|
|
12
11
|
autoload :Pathname, 'pathname'
|
|
@@ -209,13 +208,13 @@ module Asciidoctor
|
|
|
209
208
|
BOM_BYTES_UTF_16BE = [0xfe, 0xff]
|
|
210
209
|
|
|
211
210
|
# The mode to use when opening a file for reading
|
|
212
|
-
FILE_READ_MODE = RUBY_ENGINE_OPAL ? 'r' : 'rb:
|
|
211
|
+
FILE_READ_MODE = RUBY_ENGINE_OPAL ? 'r' : 'rb:UTF-8:UTF-8'
|
|
213
212
|
|
|
214
213
|
# The mode to use when opening a URI for reading
|
|
215
214
|
URI_READ_MODE = FILE_READ_MODE
|
|
216
215
|
|
|
217
216
|
# The mode to use when opening a file for writing
|
|
218
|
-
FILE_WRITE_MODE = RUBY_ENGINE_OPAL ? 'w' : '
|
|
217
|
+
FILE_WRITE_MODE = RUBY_ENGINE_OPAL ? 'w' : 'wb:UTF-8'
|
|
219
218
|
|
|
220
219
|
# The default document type
|
|
221
220
|
# Can influence markup generated by the converters
|
data/man/asciidoctor.1
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'\" t
|
|
2
2
|
.\" Title: asciidoctor
|
|
3
3
|
.\" Author: Dan Allen, Sarah White
|
|
4
|
-
.\" Generator: Asciidoctor 2.0.
|
|
4
|
+
.\" Generator: Asciidoctor 2.0.21
|
|
5
5
|
.\" Date: 2018-03-20
|
|
6
6
|
.\" Manual: Asciidoctor Manual
|
|
7
|
-
.\" Source: Asciidoctor 2.0.
|
|
7
|
+
.\" Source: Asciidoctor 2.0.22
|
|
8
8
|
.\" Language: English
|
|
9
9
|
.\"
|
|
10
|
-
.TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.
|
|
10
|
+
.TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.22" "Asciidoctor Manual"
|
|
11
11
|
.ie \n(.g .ds Aq \(aq
|
|
12
12
|
.el .ds Aq '
|
|
13
13
|
.ss \n[.ss] 0
|
data/man/asciidoctor.adoc
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciidoctor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.22
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dan Allen
|
|
@@ -77,14 +77,14 @@ dependencies:
|
|
|
77
77
|
requirements:
|
|
78
78
|
- - "~>"
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: 5.
|
|
80
|
+
version: 5.22.0
|
|
81
81
|
type: :development
|
|
82
82
|
prerelease: false
|
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
|
85
85
|
- - "~>"
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: 5.
|
|
87
|
+
version: 5.22.0
|
|
88
88
|
- !ruby/object:Gem::Dependency
|
|
89
89
|
name: nokogiri
|
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -272,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
272
272
|
- !ruby/object:Gem::Version
|
|
273
273
|
version: '0'
|
|
274
274
|
requirements: []
|
|
275
|
-
rubygems_version: 3.
|
|
275
|
+
rubygems_version: 3.5.3
|
|
276
276
|
signing_key:
|
|
277
277
|
specification_version: 4
|
|
278
278
|
summary: An implementation of the AsciiDoc text processor and publishing toolchain
|