asciidoctor 2.0.12 → 2.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +39 -1
- data/LICENSE +1 -1
- data/README-de.adoc +15 -6
- data/README-fr.adoc +14 -8
- data/README-jp.adoc +15 -6
- data/README-zh_CN.adoc +14 -5
- data/README.adoc +128 -124
- data/asciidoctor.gemspec +5 -5
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-it.adoc +4 -4
- data/data/locale/attributes-nl.adoc +6 -6
- data/data/reference/syntax.adoc +14 -7
- data/data/stylesheets/asciidoctor-default.css +1 -4
- data/lib/asciidoctor.rb +2 -2
- data/lib/asciidoctor/abstract_node.rb +1 -1
- data/lib/asciidoctor/attribute_list.rb +5 -5
- data/lib/asciidoctor/cli/options.rb +7 -6
- data/lib/asciidoctor/converter/html5.rb +1 -1
- data/lib/asciidoctor/converter/manpage.rb +49 -27
- data/lib/asciidoctor/document.rb +3 -1
- data/lib/asciidoctor/extensions.rb +0 -2
- data/lib/asciidoctor/helpers.rb +3 -6
- data/lib/asciidoctor/load.rb +2 -2
- data/lib/asciidoctor/parser.rb +8 -5
- data/lib/asciidoctor/reader.rb +7 -7
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +2 -2
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +31 -25
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +7 -7
- data/man/asciidoctor.adoc +3 -3
- metadata +14 -13
data/asciidoctor.gemspec
CHANGED
@@ -34,21 +34,21 @@ Gem::Specification.new do |s|
|
|
34
34
|
#s.test_files = files.grep %r/^(?:features|test)\/.+$/
|
35
35
|
|
36
36
|
# asciimath is needed for testing AsciiMath in DocBook backend
|
37
|
-
s.add_development_dependency 'asciimath', '~>
|
37
|
+
s.add_development_dependency 'asciimath', '~> 2.0.0'
|
38
38
|
# coderay is needed for testing syntax highlighting
|
39
39
|
s.add_development_dependency 'coderay', '~> 1.1.0'
|
40
40
|
# concurrent-ruby, haml, slim, and tilt are needed for testing custom templates
|
41
41
|
s.add_development_dependency 'concurrent-ruby', '~> 1.1.0'
|
42
42
|
s.add_development_dependency 'cucumber', '~> 3.1.0'
|
43
43
|
# erubi is needed for testing alternate eRuby impls
|
44
|
-
s.add_development_dependency 'erubi', '~> 1.
|
45
|
-
s.add_development_dependency 'haml', '~> 5.
|
44
|
+
s.add_development_dependency 'erubi', '~> 1.10.0'
|
45
|
+
s.add_development_dependency 'haml', '~> 5.2.0'
|
46
46
|
s.add_development_dependency 'minitest', '~> 5.11.0'
|
47
47
|
s.add_development_dependency 'nokogiri', '~> 1.10.0'
|
48
48
|
s.add_development_dependency 'rake', '~> 12.3.0'
|
49
49
|
# Asciidoctor supports Rouge >= 2
|
50
|
-
s.add_development_dependency 'rouge', '~> 3.
|
50
|
+
s.add_development_dependency 'rouge', '~> 3.26.0'
|
51
51
|
s.add_development_dependency 'rspec-expectations', '~> 3.8.0'
|
52
|
-
s.add_development_dependency 'slim', '~> 4.
|
52
|
+
s.add_development_dependency 'slim', '~> 4.1.0'
|
53
53
|
s.add_development_dependency 'tilt', '~> 2.0.0'
|
54
54
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
// Belarusian translation, courtesy of Dexter Morganov <dexter.morganov@gmail.com>
|
2
|
+
:appendix-caption: Дадатак
|
3
|
+
:appendix-refsig: {appendix-caption}
|
4
|
+
:caution-caption: Увага
|
5
|
+
:chapter-signifier: Глава
|
6
|
+
:chapter-refsig: {chapter-signifier}
|
7
|
+
:example-caption: Прыклад
|
8
|
+
:figure-caption: Малюнак
|
9
|
+
:important-caption: Важна
|
10
|
+
:last-update-label: Апошняе абнаўленне
|
11
|
+
ifdef::listing-caption[:listing-caption: Лістынг]
|
12
|
+
ifdef::manname-title[:manname-title: Назва]
|
13
|
+
:note-caption: Заўвага
|
14
|
+
:part-signifier: Частка
|
15
|
+
:part-refsig: {part-signifier}
|
16
|
+
ifdef::preface-title[:preface-title: Прадмова]
|
17
|
+
:section-refsig: Раздзел
|
18
|
+
:table-caption: Табліца
|
19
|
+
:tip-caption: Падказка
|
20
|
+
:toc-title: Змест
|
21
|
+
:untitled-label: Без назвы
|
22
|
+
:version-label: Версія
|
23
|
+
:warning-caption: Папярэджанне
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// Italian translation, courtesy of Marco Ciampa <ciampix@
|
1
|
+
// Italian translation, courtesy of Marco Ciampa <ciampix@posteo.net>
|
2
2
|
:appendix-caption: Appendice
|
3
3
|
:appendix-refsig: {appendix-caption}
|
4
4
|
:caution-caption: Attenzione
|
@@ -11,10 +11,10 @@
|
|
11
11
|
ifdef::listing-caption[:listing-caption: Elenco]
|
12
12
|
ifdef::manname-title[:manname-title: Nome]
|
13
13
|
:note-caption: Nota
|
14
|
-
|
15
|
-
|
14
|
+
:part-signifier: Parte
|
15
|
+
:part-refsig: {part-signifier}
|
16
16
|
ifdef::preface-title[:preface-title: Prefazione]
|
17
|
-
|
17
|
+
:section-refsig: Sezione
|
18
18
|
:table-caption: Tabella
|
19
19
|
:tip-caption: Suggerimento
|
20
20
|
:toc-title: Indice
|
@@ -2,8 +2,8 @@
|
|
2
2
|
:appendix-caption: Bijlage
|
3
3
|
:appendix-refsig: {appendix-caption}
|
4
4
|
:caution-caption: Opgelet
|
5
|
-
|
6
|
-
|
5
|
+
:chapter-signifier: Hoofdstuk
|
6
|
+
:chapter-refsig: {chapter-signifier}
|
7
7
|
:example-caption: Voorbeeld
|
8
8
|
:figure-caption: Figuur
|
9
9
|
:important-caption: Belangrijk
|
@@ -11,13 +11,13 @@
|
|
11
11
|
ifdef::listing-caption[:listing-caption: Lijst]
|
12
12
|
ifdef::manname-title[:manname-title: Naam]
|
13
13
|
:note-caption: Noot
|
14
|
-
|
15
|
-
|
14
|
+
:part-signifier: Deel
|
15
|
+
:part-refsig: {part-signifier}
|
16
16
|
ifdef::preface-title[:preface-title: Inleiding]
|
17
|
-
|
17
|
+
:section-refsig: Paragraaf
|
18
18
|
:table-caption: Tabel
|
19
19
|
:tip-caption: Tip
|
20
|
-
:toc-title:
|
20
|
+
:toc-title: Inhoudsopgave
|
21
21
|
:untitled-label: Naamloos
|
22
22
|
:version-label: Versie
|
23
23
|
:warning-caption: Waarschuwing
|
data/data/reference/syntax.adoc
CHANGED
@@ -17,7 +17,7 @@ Line breaks are not preserved.
|
|
17
17
|
A blank line separates paragraphs.
|
18
18
|
|
19
19
|
[%hardbreaks]
|
20
|
-
This paragraph
|
20
|
+
This paragraph is marked with the `hardbreaks` option.
|
21
21
|
Notice how line breaks are now preserved.
|
22
22
|
|
23
23
|
An indented (literal) paragraph disables text formatting,
|
@@ -25,14 +25,14 @@ Notice how line breaks are now preserved.
|
|
25
25
|
monospaced font.
|
26
26
|
|
27
27
|
[sidebar#id.role]
|
28
|
-
|
28
|
+
Adding a style, ID, and/or role gives a paragraph (or block) special meaning, like this sidebar.
|
29
29
|
|
30
30
|
NOTE: An admonition paragraph, like this note, grabs the reader's attention.
|
31
31
|
|
32
32
|
TIP: Convert this document using the `asciidoctor` command to see the output produced from it.
|
33
33
|
|
34
34
|
== Text Formatting
|
35
|
-
:hardbreaks:
|
35
|
+
:hardbreaks-option:
|
36
36
|
|
37
37
|
.Constrained (applied at word boundaries)
|
38
38
|
*strong importance* (aka bold)
|
@@ -41,17 +41,24 @@ _stress emphasis_ (aka italic)
|
|
41
41
|
"`double`" and '`single`' typographic quotes
|
42
42
|
+passthrough text+ (substitutions disabled)
|
43
43
|
`+literal text+` (monospaced with substitutions disabled)
|
44
|
+
a #mark# to remember (highlighted for notation)
|
44
45
|
|
45
46
|
.Unconstrained (applied anywhere)
|
46
|
-
**C**reate
|
47
|
+
**C**reate, **R**ead, **U**pdate, and **D**elete (CRUD)
|
47
48
|
fan__freakin__tastic
|
48
49
|
``mono``culture
|
50
|
+
##mark##up your text
|
49
51
|
|
50
52
|
.Replacements
|
51
53
|
A long time ago in a galaxy far, far away...
|
52
54
|
(C) 1976 Arty Artisan
|
53
55
|
I believe I shall--no, actually I won't.
|
54
56
|
|
57
|
+
.ID and roles for phrases
|
58
|
+
[.line-through]#delete me#
|
59
|
+
the [.path]_images_ directory
|
60
|
+
a [#wibble.term]*wibble* does wobble
|
61
|
+
|
55
62
|
.Macros
|
56
63
|
// where c=specialchars, q=quotes, a=attributes, r=replacements, m=macros, p=post_replacements, etc.
|
57
64
|
The European icon:flag[role=blue] is blue & contains pass:[************] arranged in a icon:circle-o[role=yellow].
|
@@ -60,7 +67,7 @@ Since `pass:[++]` has strong priority in AsciiDoc, you can rewrite pass:c,a,r[C+
|
|
60
67
|
// activate stem support by adding `:stem:` to the document header
|
61
68
|
stem:[sqrt(4) = 2]
|
62
69
|
|
63
|
-
:!hardbreaks:
|
70
|
+
:!hardbreaks-option:
|
64
71
|
== Attributes
|
65
72
|
|
66
73
|
// define attributes in the document header; must be flush with left margin
|
@@ -242,7 +249,7 @@ comment - content which is not included in the output document
|
|
242
249
|
== Tables
|
243
250
|
|
244
251
|
.Table Attributes
|
245
|
-
[cols=>1h;2d,width=50%,frame=
|
252
|
+
[cols=>1h;2d,width=50%,frame=ends]
|
246
253
|
|===
|
247
254
|
| Attribute Name | Values
|
248
255
|
|
@@ -256,7 +263,7 @@ comment - content which is not included in the output document
|
|
256
263
|
| all \| cols \| rows \| none
|
257
264
|
|
258
265
|
| frame
|
259
|
-
| all \| sides \|
|
266
|
+
| all \| sides \| ends \| none
|
260
267
|
|
261
268
|
| stripes
|
262
269
|
| all \| even \| odd \| none
|
@@ -84,9 +84,6 @@ dl dd{margin-bottom:1.25em}
|
|
84
84
|
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
|
85
85
|
abbr{text-transform:none}
|
86
86
|
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
87
|
-
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
|
88
|
-
blockquote cite::before{content:"\2014 \0020"}
|
89
|
-
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
|
90
87
|
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
91
88
|
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
92
89
|
h1{font-size:2.75em}
|
@@ -251,7 +248,7 @@ pre.pygments .lineno::before{content:"";margin-right:-.125em}
|
|
251
248
|
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
|
252
249
|
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
|
253
250
|
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
|
254
|
-
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
|
251
|
+
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
|
255
252
|
p.tableblock:last-child{margin-bottom:0}
|
256
253
|
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
|
257
254
|
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
|
data/lib/asciidoctor.rb
CHANGED
@@ -136,8 +136,8 @@ module Asciidoctor
|
|
136
136
|
# Compliance value: true
|
137
137
|
define :underline_style_section_titles, true
|
138
138
|
|
139
|
-
# Asciidoctor will unwrap the content in a preamble
|
140
|
-
#
|
139
|
+
# Asciidoctor will unwrap the content in a preamble if the document has a
|
140
|
+
# title and no sections, then discard the empty preamble.
|
141
141
|
# Compliance value: false
|
142
142
|
define :unwrap_standalone_preamble, true
|
143
143
|
|
@@ -216,7 +216,7 @@ class AbstractNode
|
|
216
216
|
(val = @attributes['role']) ? (%( #{val} ).include? %( #{name} )) : false
|
217
217
|
end
|
218
218
|
|
219
|
-
# Public: Sets the value of the role attribute on this
|
219
|
+
# Public: Sets the value of the role attribute on this node.
|
220
220
|
#
|
221
221
|
# names - A single role name, a space-separated String of role names, or an Array of role names
|
222
222
|
#
|
@@ -27,7 +27,7 @@ class AttributeList
|
|
27
27
|
QUOT = '"'
|
28
28
|
|
29
29
|
# Public: Regular expressions for detecting the boundary of a value
|
30
|
-
|
30
|
+
BoundaryRx = {
|
31
31
|
QUOT => /.*?[^\\](?=")/,
|
32
32
|
APOS => /.*?[^\\](?=')/,
|
33
33
|
',' => /.*?(?=[ \t]*(,|$))/
|
@@ -46,7 +46,7 @@ class AttributeList
|
|
46
46
|
BlankRx = /[ \t]+/
|
47
47
|
|
48
48
|
# Public: Regular expressions for skipping delimiters
|
49
|
-
|
49
|
+
SkipRx = {
|
50
50
|
',' => /[ \t]*(,|$)/
|
51
51
|
}
|
52
52
|
|
@@ -54,8 +54,8 @@ class AttributeList
|
|
54
54
|
@scanner = ::StringScanner.new source
|
55
55
|
@block = block
|
56
56
|
@delimiter = delimiter
|
57
|
-
@delimiter_skip_pattern =
|
58
|
-
@delimiter_boundary_pattern =
|
57
|
+
@delimiter_skip_pattern = SkipRx[delimiter]
|
58
|
+
@delimiter_boundary_pattern = BoundaryRx[delimiter]
|
59
59
|
@attributes = nil
|
60
60
|
end
|
61
61
|
|
@@ -214,7 +214,7 @@ class AttributeList
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def scan_to_quote quote
|
217
|
-
@scanner.scan
|
217
|
+
@scanner.scan BoundaryRx[quote]
|
218
218
|
end
|
219
219
|
end
|
220
220
|
end
|
@@ -39,14 +39,15 @@ module Asciidoctor
|
|
39
39
|
# NOTE don't use squiggly heredoc to maintain compatibility with Ruby < 2.3
|
40
40
|
opts.banner = <<-'EOS'.gsub ' ', ''
|
41
41
|
Usage: asciidoctor [OPTION]... FILE...
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
Convert the AsciiDoc input FILE(s) to the backend output format (e.g., HTML 5, DocBook 5, etc.)
|
43
|
+
Unless specified otherwise, the output is written to a file whose name is derived from the input file.
|
44
|
+
Application log messages are printed to STDERR.
|
45
|
+
Example: asciidoctor input.adoc
|
45
46
|
|
46
47
|
EOS
|
47
48
|
|
48
|
-
opts.on('-b', '--backend BACKEND', 'set output format
|
49
|
-
'additional backends are supported via
|
49
|
+
opts.on('-b', '--backend BACKEND', 'set backend output format: [html5, xhtml5, docbook5, manpage] (default: html5)',
|
50
|
+
'additional backends are supported via extended converters (e.g., pdf, epub3)') do |backend|
|
50
51
|
self[:attributes]['backend'] = backend
|
51
52
|
end
|
52
53
|
opts.on('-d', '--doctype DOCTYPE', ['article', 'book', 'manpage', 'inline'],
|
@@ -128,7 +129,7 @@ module Asciidoctor
|
|
128
129
|
opts.on('--trace', 'include backtrace information when reporting errors (default: false)') do |trace|
|
129
130
|
self[:trace] = true
|
130
131
|
end
|
131
|
-
opts.on('-v', '--verbose', '
|
132
|
+
opts.on('-v', '--verbose', 'directs application messages logged at DEBUG or INFO level to STDERR (default: false)') do |verbose|
|
132
133
|
self[:verbose] = 2
|
133
134
|
end
|
134
135
|
opts.on('-w', '--warnings', 'turn on script warnings (default: false)') do |warnings|
|
@@ -1310,7 +1310,7 @@ Your browser does not support the video tag.
|
|
1310
1310
|
manname_id_attr = (manname_id = node.attr 'manname-id') ? %( id="#{manname_id}") : ''
|
1311
1311
|
%(<h2#{manname_id_attr}>#{manname_title}</h2>
|
1312
1312
|
<div class="sectionbody">
|
1313
|
-
<p>#{node.attr '
|
1313
|
+
<p>#{(node.attr 'mannames').join ', '} - #{node.attr 'manpurpose'}</p>
|
1314
1314
|
</div>)
|
1315
1315
|
end
|
1316
1316
|
|
@@ -2,8 +2,12 @@
|
|
2
2
|
module Asciidoctor
|
3
3
|
# A built-in {Converter} implementation that generates the man page (troff) format.
|
4
4
|
#
|
5
|
-
# The output
|
6
|
-
#
|
5
|
+
# The output of this converter adheres to the man definition as defined by
|
6
|
+
# groff and uses the manpage output of the DocBook toolchain as a foundation.
|
7
|
+
# That means if you've previously been generating man pages using the a2x tool
|
8
|
+
# from AsciiDoc Python, you should be able to achieve a very similar result
|
9
|
+
# using this converter. Though you'll also get to enjoy some notable
|
10
|
+
# enhancements that have been added since, such as the customizable linkstyle.
|
7
11
|
#
|
8
12
|
# See http://www.gnu.org/software/groff/manual/html_node/Man-usage.html#Man-usage
|
9
13
|
class Converter::ManPageConverter < Converter::Base
|
@@ -18,10 +22,13 @@ class Converter::ManPageConverter < Converter::Base
|
|
18
22
|
LiteralBackslashRx = /\A\\|(#{ESC})?\\/
|
19
23
|
LeadingPeriodRx = /^\./
|
20
24
|
EscapedMacroRx = /^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) "#{CC_ANY}*?" "#{CC_ANY}*?" )( |[^\s]*)(#{CC_ANY}*?)(?: *#{ESC}\\c)?$/
|
21
|
-
|
25
|
+
MalformedEscapedMacroRx = /(#{ESC}\\c) (#{ESC}\.(?:URL|MTO) )/
|
26
|
+
MockMacroRx = /<\/?(#{ESC}\\[^>]+)>/
|
22
27
|
EmDashCharRefRx = /—(?:​)?/
|
23
28
|
EllipsisCharRefRx = /…(?:​)?/
|
24
29
|
WrappedIndentRx = /#{CG_BLANK}*#{LF}#{CG_BLANK}*/
|
30
|
+
XMLMarkupRx = /&#?[a-z\d]+;|</
|
31
|
+
PCDATAFilterRx = /(&#?[a-z\d]+;|<[^>]+>)|([^&<]+)/
|
25
32
|
|
26
33
|
def initialize backend, opts = {}
|
27
34
|
@backend = backend
|
@@ -91,17 +98,14 @@ class Converter::ManPageConverter < Converter::Base
|
|
91
98
|
if node.attr? 'manpurpose'
|
92
99
|
mannames = node.attr 'mannames', [manname]
|
93
100
|
result << %(.SH "#{(node.attr 'manname-title', 'NAME').upcase}"
|
94
|
-
#{mannames.map {|n| manify n }.join ', '} \\- #{manify node.attr('manpurpose'), whitespace: :normalize})
|
101
|
+
#{mannames.map {|n| (manify n).gsub '\-', '-' }.join ', '} \\- #{manify node.attr('manpurpose'), whitespace: :normalize})
|
95
102
|
end
|
96
103
|
end
|
97
104
|
|
98
105
|
result << node.content
|
99
106
|
|
100
107
|
# QUESTION should NOTES come after AUTHOR(S)?
|
101
|
-
|
102
|
-
result << '.SH "NOTES"'
|
103
|
-
result.concat(node.footnotes.map {|fn| %(#{fn.index}. #{fn.text}) })
|
104
|
-
end
|
108
|
+
append_footnotes result, node
|
105
109
|
|
106
110
|
unless (authors = node.authors).empty?
|
107
111
|
if authors.size > 1
|
@@ -124,10 +128,7 @@ class Converter::ManPageConverter < Converter::Base
|
|
124
128
|
def convert_embedded node
|
125
129
|
result = [node.content]
|
126
130
|
|
127
|
-
|
128
|
-
result << '.SH "NOTES"'
|
129
|
-
result.concat(node.footnotes.map {|fn| %(#{fn.index}. #{fn.text}) })
|
130
|
-
end
|
131
|
+
append_footnotes result, node
|
131
132
|
|
132
133
|
# QUESTION should we add an AUTHOR(S) section?
|
133
134
|
|
@@ -142,7 +143,7 @@ class Converter::ManPageConverter < Converter::Base
|
|
142
143
|
stitle = node.captioned_title
|
143
144
|
else
|
144
145
|
macro = 'SH'
|
145
|
-
stitle = node.title
|
146
|
+
stitle = uppercase_pcdata node.title
|
146
147
|
end
|
147
148
|
result << %(.#{macro} "#{manify stitle}"
|
148
149
|
#{node.content})
|
@@ -315,8 +316,9 @@ r lw(\n(.lu*75u/100u).'
|
|
315
316
|
end
|
316
317
|
end
|
317
318
|
|
318
|
-
|
319
|
-
|
319
|
+
def convert_page_break node
|
320
|
+
'.bp'
|
321
|
+
end
|
320
322
|
|
321
323
|
def convert_paragraph node
|
322
324
|
if node.title?
|
@@ -531,12 +533,13 @@ allbox tab(:);'
|
|
531
533
|
result.join LF
|
532
534
|
end
|
533
535
|
|
534
|
-
# FIXME git uses [verse] for the synopsis; detect this special case
|
535
536
|
def convert_verse node
|
536
537
|
result = []
|
537
|
-
|
538
|
+
if node.title?
|
539
|
+
result << %(.sp
|
538
540
|
.B #{manify node.title}
|
539
|
-
.br)
|
541
|
+
.br)
|
542
|
+
end
|
540
543
|
attribution_line = (node.attr? 'citetitle') ? %(#{node.attr 'citetitle'} ) : nil
|
541
544
|
attribution_line = (node.attr? 'attribution') ? %[#{attribution_line}\\(em #{node.attr 'attribution'}] : nil
|
542
545
|
result << %(.sp
|
@@ -609,7 +612,6 @@ allbox tab(:);'
|
|
609
612
|
%(#{ESC_BS}fB(#{node.text})#{ESC_BS}fP)
|
610
613
|
end
|
611
614
|
|
612
|
-
# TODO supposedly groff has footnotes, but we're in search of an example
|
613
615
|
def convert_inline_footnote node
|
614
616
|
if (index = node.attr 'index')
|
615
617
|
%([#{index}])
|
@@ -647,19 +649,19 @@ allbox tab(:);'
|
|
647
649
|
end
|
648
650
|
end
|
649
651
|
|
650
|
-
# NOTE use fake
|
652
|
+
# NOTE use fake XML elements to prevent creating artificial word boundaries
|
651
653
|
def convert_inline_quoted node
|
652
654
|
case node.type
|
653
655
|
when :emphasis
|
654
|
-
%(
|
656
|
+
%(<#{ESC_BS}fI>#{node.text}</#{ESC_BS}fP>)
|
655
657
|
when :strong
|
656
|
-
%(
|
658
|
+
%(<#{ESC_BS}fB>#{node.text}</#{ESC_BS}fP>)
|
657
659
|
when :monospaced
|
658
|
-
%[
|
660
|
+
%[<#{ESC_BS}f(CR>#{node.text}</#{ESC_BS}fP>]
|
659
661
|
when :single
|
660
|
-
%[
|
662
|
+
%[<#{ESC_BS}(oq>#{node.text}</#{ESC_BS}(cq>]
|
661
663
|
when :double
|
662
|
-
%[
|
664
|
+
%[<#{ESC_BS}(lq>#{node.text}</#{ESC_BS}(rq>]
|
663
665
|
else
|
664
666
|
node.text
|
665
667
|
end
|
@@ -678,6 +680,22 @@ allbox tab(:);'
|
|
678
680
|
|
679
681
|
private
|
680
682
|
|
683
|
+
def append_footnotes result, node
|
684
|
+
if node.footnotes? && !(node.attr? 'nofootnotes')
|
685
|
+
result << '.SH "NOTES"'
|
686
|
+
node.footnotes.each_with_index do |fn, idx|
|
687
|
+
result << %(.IP [#{fn.index}])
|
688
|
+
# NOTE restore newline in escaped macro that gets removed by normalize_text in substitutor
|
689
|
+
if (text = fn.text).include? %(#{ESC}\\c #{ESC}.)
|
690
|
+
text = (manify %(#{text.gsub MalformedEscapedMacroRx, %(\\1#{LF}\\2)} ), whitespace: :normalize).chomp ' '
|
691
|
+
else
|
692
|
+
text = manify text, whitespace: :normalize
|
693
|
+
end
|
694
|
+
result << text
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
681
699
|
# Converts HTML entity references back to their original form, escapes
|
682
700
|
# special man characters and strips trailing whitespace.
|
683
701
|
#
|
@@ -704,7 +722,7 @@ allbox tab(:);'
|
|
704
722
|
gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
|
705
723
|
gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
|
706
724
|
# drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
|
707
|
-
gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"
|
725
|
+
gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#{$2.rstrip}"#{LF}#{rest}) }.
|
708
726
|
gsub('-', '\-').
|
709
727
|
gsub('<', '<').
|
710
728
|
gsub('>', '>').
|
@@ -726,13 +744,17 @@ allbox tab(:);'
|
|
726
744
|
gsub('​', '\:'). # zero width space
|
727
745
|
gsub('&', '&'). # literal ampersand (NOTE must take place after any other replacement that includes &)
|
728
746
|
gsub('\'', '\(aq'). # apostrophe-quote
|
729
|
-
gsub(
|
747
|
+
gsub(MockMacroRx, '\1'). # mock boundary
|
730
748
|
gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
|
731
749
|
gsub(ESC_FS, '.'). # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
|
732
750
|
rstrip # strip trailing space
|
733
751
|
opts[:append_newline] ? %(#{str}#{LF}) : str
|
734
752
|
end
|
735
753
|
|
754
|
+
def uppercase_pcdata string
|
755
|
+
(XMLMarkupRx.match? string) ? string.gsub(PCDATAFilterRx) { $2 ? $2.upcase : $1 } : string.upcase
|
756
|
+
end
|
757
|
+
|
736
758
|
def enclose_content node
|
737
759
|
node.content_model == :compound ? node.content : %(.sp#{LF}#{manify node.content, whitespace: :normalize})
|
738
760
|
end
|