asciidoctor 1.5.8 → 2.0.0.rc.1

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.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,211 +0,0 @@
1
- # encoding: UTF-8
2
- unless defined? ASCIIDOCTOR_PROJECT_DIR
3
- $: << File.dirname(__FILE__); $:.uniq!
4
- require 'test_helper'
5
- end
6
-
7
- context 'Logger' do
8
- MyLogger = Class.new Logger
9
-
10
- context 'LoggerManager' do
11
- test 'provides access to logger via static logger method' do
12
- logger = Asciidoctor::LoggerManager.logger
13
- refute_nil logger
14
- assert_kind_of Logger, logger
15
- end
16
-
17
- test 'allows logger instance to be changed' do
18
- old_logger = Asciidoctor::LoggerManager.logger
19
- new_logger = MyLogger.new $stdout
20
- begin
21
- Asciidoctor::LoggerManager.logger = new_logger
22
- assert_same new_logger, Asciidoctor::LoggerManager.logger
23
- ensure
24
- Asciidoctor::LoggerManager.logger = old_logger
25
- end
26
- end
27
-
28
- test 'setting logger instance to falsy value resets instance to default logger' do
29
- old_logger = Asciidoctor::LoggerManager.logger
30
- begin
31
- Asciidoctor::LoggerManager.logger = MyLogger.new $stdout
32
- Asciidoctor::LoggerManager.logger = nil
33
- refute_nil Asciidoctor::LoggerManager.logger
34
- assert_kind_of Logger, Asciidoctor::LoggerManager.logger
35
- ensure
36
- Asciidoctor::LoggerManager.logger = old_logger
37
- end
38
- end
39
-
40
- test 'creates logger instance from static logger_class property' do
41
- old_logger_class = Asciidoctor::LoggerManager.logger_class
42
- old_logger = Asciidoctor::LoggerManager.logger
43
- begin
44
- Asciidoctor::LoggerManager.logger_class = MyLogger
45
- Asciidoctor::LoggerManager.logger = nil
46
- refute_nil Asciidoctor::LoggerManager.logger
47
- assert_kind_of MyLogger, Asciidoctor::LoggerManager.logger
48
- ensure
49
- Asciidoctor::LoggerManager.logger_class = old_logger_class
50
- Asciidoctor::LoggerManager.logger = old_logger
51
- end
52
- end
53
- end
54
-
55
- context 'Logger' do
56
- test 'configures default logger with progname set to asciidoctor' do
57
- assert_equal 'asciidoctor', Asciidoctor::LoggerManager.logger.progname
58
- end
59
-
60
- test 'configures default logger with level set to WARN' do
61
- assert_equal Logger::Severity::WARN, Asciidoctor::LoggerManager.logger.level
62
- end
63
-
64
- test 'configures default logger to write messages to $stderr' do
65
- out_string, err_string = redirect_streams do |out, err|
66
- Asciidoctor::LoggerManager.logger.warn 'this is a call'
67
- [out.string, err.string]
68
- end
69
- assert_empty out_string
70
- refute_empty err_string
71
- assert_includes err_string, 'this is a call'
72
- end
73
-
74
- test 'configures default logger to use a formatter that matches traditional format' do
75
- err_string = redirect_streams do |_, err|
76
- Asciidoctor::LoggerManager.logger.warn 'this is a call'
77
- Asciidoctor::LoggerManager.logger.fatal 'it cannot be done'
78
- err.string
79
- end
80
- assert_includes err_string, %(asciidoctor: WARNING: this is a call)
81
- assert_includes err_string, %(asciidoctor: FAILED: it cannot be done)
82
- end
83
- end
84
-
85
- context ':logger API option' do
86
- test 'should be able to set logger when invoking load API' do
87
- old_logger = Asciidoctor::LoggerManager.logger
88
- new_logger = MyLogger.new $stdout
89
- begin
90
- Asciidoctor.load 'contents', :logger => new_logger
91
- assert_same new_logger, Asciidoctor::LoggerManager.logger
92
- ensure
93
- Asciidoctor::LoggerManager.logger = old_logger
94
- end
95
- end
96
-
97
- test 'should be able to set logger when invoking load_file API' do
98
- old_logger = Asciidoctor::LoggerManager.logger
99
- new_logger = MyLogger.new $stdout
100
- begin
101
- Asciidoctor.load_file fixture_path('basic.asciidoc'), :logger => new_logger
102
- assert_same new_logger, Asciidoctor::LoggerManager.logger
103
- ensure
104
- Asciidoctor::LoggerManager.logger = old_logger
105
- end
106
- end
107
-
108
- test 'should be able to set logger when invoking convert API' do
109
- old_logger = Asciidoctor::LoggerManager.logger
110
- new_logger = MyLogger.new $stdout
111
- begin
112
- Asciidoctor.convert 'contents', :logger => new_logger
113
- assert_same new_logger, Asciidoctor::LoggerManager.logger
114
- ensure
115
- Asciidoctor::LoggerManager.logger = old_logger
116
- end
117
- end
118
-
119
- test 'should be able to set logger when invoking convert_file API' do
120
- old_logger = Asciidoctor::LoggerManager.logger
121
- new_logger = MyLogger.new $stdout
122
- begin
123
- Asciidoctor.convert_file fixture_path('basic.asciidoc'), :to_file => false, :logger => new_logger
124
- assert_same new_logger, Asciidoctor::LoggerManager.logger
125
- ensure
126
- Asciidoctor::LoggerManager.logger = old_logger
127
- end
128
- end
129
- end
130
-
131
- context 'Logging' do
132
- test 'including Logging gives instance methods on module access to logging infrastructure' do
133
- module SampleModuleA
134
- include Asciidoctor::Logging
135
- def get_logger
136
- logger
137
- end
138
- end
139
-
140
- class SampleClassA
141
- include SampleModuleA
142
- end
143
- assert_same Asciidoctor::LoggerManager.logger, SampleClassA.new.get_logger
144
- assert SampleClassA.private_method_defined? :logger
145
- end
146
-
147
- test 'including Logging gives static methods on module access to logging infrastructure' do
148
- module SampleModuleB
149
- include Asciidoctor::Logging
150
- def self.get_logger
151
- logger
152
- end
153
- end
154
-
155
- assert_same Asciidoctor::LoggerManager.logger, SampleModuleB.get_logger
156
- end
157
-
158
- test 'including Logging gives instance methods on class access to logging infrastructure' do
159
- class SampleClassC
160
- include Asciidoctor::Logging
161
- def get_logger
162
- logger
163
- end
164
- end
165
-
166
- assert_same Asciidoctor::LoggerManager.logger, SampleClassC.new.get_logger
167
- assert SampleClassC.private_method_defined? :logger
168
- end
169
-
170
- test 'including Logging gives static methods on class access to logging infrastructure' do
171
- class SampleClassD
172
- include Asciidoctor::Logging
173
- def self.get_logger
174
- logger
175
- end
176
- end
177
-
178
- assert_same Asciidoctor::LoggerManager.logger, SampleClassD.get_logger
179
- end
180
-
181
- test 'can create an auto-formatting message with context' do
182
- class SampleClassE
183
- include Asciidoctor::Logging
184
- def create_message cursor
185
- message_with_context 'Asciidoctor was here', :source_location => cursor
186
- end
187
- end
188
-
189
- cursor = Asciidoctor::Reader::Cursor.new 'file.adoc', fixturedir, 'file.adoc', 5
190
- message = SampleClassE.new.create_message cursor
191
- assert_equal 'Asciidoctor was here', message[:text]
192
- assert_same cursor, message[:source_location]
193
- assert_equal 'file.adoc: line 5: Asciidoctor was here', message.inspect
194
- end
195
-
196
- test 'writes message prefixed with program name and source location to stderr' do
197
- input = <<-EOS
198
- [#first]
199
- first paragraph
200
-
201
- [#first]
202
- another first paragraph
203
- EOS
204
- messages = redirect_streams do |_, err|
205
- convert_string_to_embedded input
206
- err.string
207
- end
208
- assert_equal 'asciidoctor: WARNING: <stdin>: line 5: id assigned to block already in use: first', messages.chomp
209
- end
210
- end
211
- end
@@ -1,660 +0,0 @@
1
- # encoding: UTF-8
2
- unless defined? ASCIIDOCTOR_PROJECT_DIR
3
- $: << File.dirname(__FILE__); $:.uniq!
4
- require 'test_helper'
5
- end
6
-
7
- SAMPLE_MANPAGE_HEADER = <<-EOS.chomp
8
- = command (1)
9
- Author Name
10
- :doctype: manpage
11
- :man manual: Command Manual
12
- :man source: Command 1.2.3
13
-
14
- == NAME
15
-
16
- command - does stuff
17
-
18
- == SYNOPSIS
19
-
20
- *command* [_OPTION_]... _FILE_...
21
-
22
- == DESCRIPTION
23
- EOS
24
-
25
- context 'Manpage' do
26
- context 'Configuration' do
27
- test 'should set proper manpage-related attributes' do
28
- input = SAMPLE_MANPAGE_HEADER
29
- doc = Asciidoctor.load input, :backend => :manpage
30
- assert_equal 'man', doc.attributes['filetype']
31
- assert_equal '', doc.attributes['filetype-man']
32
- assert_equal '1', doc.attributes['manvolnum']
33
- assert_equal '.1', doc.attributes['outfilesuffix']
34
- assert_equal 'command', doc.attributes['manname']
35
- assert_equal 'command', doc.attributes['mantitle']
36
- assert_equal 'does stuff', doc.attributes['manpurpose']
37
- assert_equal 'command', doc.attributes['docname']
38
- end
39
-
40
- test 'should output multiple mannames in NAME section' do
41
- input = SAMPLE_MANPAGE_HEADER.sub(/^command - /, 'command, alt_command - ')
42
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
43
- assert_includes output.lines, %(command, alt_command \\- does stuff\n)
44
- end
45
-
46
- test 'should not parse NAME section if manname and manpurpose attributes are set' do
47
- input = <<-EOS
48
- = foobar (1)
49
- Author Name
50
- :doctype: manpage
51
- :man manual: Foo Bar Manual
52
- :man source: Foo Bar 1.0
53
-
54
- == SYNOPSIS
55
-
56
- *foobar* [_OPTIONS_]...
57
-
58
- == DESCRIPTION
59
-
60
- When you need to put some foo on the bar.
61
- EOS
62
-
63
- attrs = { 'manname' => 'foobar', 'manpurpose' => 'puts some foo on the bar' }
64
- doc = Asciidoctor.load input, :backend => :manpage, :header_footer => true, :attributes => attrs
65
- assert_equal 'foobar', (doc.attr 'manname')
66
- assert_equal ['foobar'], (doc.attr 'mannames')
67
- assert_equal 'puts some foo on the bar', (doc.attr 'manpurpose')
68
- assert_equal 'SYNOPSIS', doc.sections[0].title
69
- end
70
-
71
- test 'should normalize whitespace and skip line comments before and inside NAME section' do
72
- input = <<-EOS
73
- = foobar (1)
74
- Author Name
75
- :doctype: manpage
76
- :man manual: Foo Bar Manual
77
- :man source: Foo Bar 1.0
78
-
79
- // this is the name section
80
- == NAME
81
-
82
- // it follows the form `name - description`
83
- foobar - puts some foo
84
- on the bar
85
- // a little bit of this, a little bit of that
86
-
87
- == SYNOPSIS
88
-
89
- *foobar* [_OPTIONS_]...
90
-
91
- == DESCRIPTION
92
-
93
- When you need to put some foo on the bar.
94
- EOS
95
-
96
- doc = Asciidoctor.load input, :backend => :manpage, :header_footer => true
97
- assert_equal 'puts some foo on the bar', (doc.attr 'manpurpose')
98
- end
99
-
100
- test 'should parse malformed document with warnings' do
101
- input = 'garbage in'
102
- using_memory_logger do |logger|
103
- doc = Asciidoctor.load input, :backend => :manpage, :header_footer => true, :attributes => { 'docname' => 'cmd' }
104
- assert_equal 'cmd', doc.attr('manname')
105
- assert_equal ['cmd'], doc.attr('mannames')
106
- assert_equal '.1', doc.attr('outfilesuffix')
107
- output = doc.convert
108
- refute logger.messages.empty?
109
- assert_includes output, 'Title: cmd'
110
- assert output.end_with?('garbage in')
111
- end
112
- end
113
-
114
- test 'should warn if document title is non-conforming' do
115
- input = <<-EOS
116
- = command
117
-
118
- == Name
119
-
120
- command - does stuff
121
- EOS
122
-
123
- using_memory_logger do |logger|
124
- document_from_string input, :backend => :manpage
125
- assert_message logger, :ERROR, '<stdin>: line 1: non-conforming manpage title', Hash
126
- end
127
- end
128
-
129
- test 'should warn if first section is not name section' do
130
- input = <<-EOS
131
- = command(1)
132
-
133
- == Synopsis
134
-
135
- Does stuff.
136
- EOS
137
-
138
- using_memory_logger do |logger|
139
- doc = document_from_string input, :backend => :manpage
140
- assert_message logger, :ERROR, '<stdin>: line 3: non-conforming name section body', Hash
141
- refute_nil doc.sections[0]
142
- assert_equal 'Synopsis', doc.sections[0].title
143
- end
144
- end
145
-
146
- test 'should define default linkstyle' do
147
- input = SAMPLE_MANPAGE_HEADER
148
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
149
- assert_includes output.lines, %(. LINKSTYLE blue R < >\n)
150
- end
151
-
152
- test 'should use linkstyle defined by man-linkstyle attribute' do
153
- input = SAMPLE_MANPAGE_HEADER
154
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true,
155
- :attributes => { 'man-linkstyle' => 'cyan B \[fo] \[fc]' }
156
- assert_includes output.lines, %(. LINKSTYLE cyan B \\[fo] \\[fc]\n)
157
- end
158
-
159
- test 'should require specialchars in value of man-linkstyle attribute defined in document to be escaped' do
160
- input = %(:man-linkstyle: cyan R < >
161
- #{SAMPLE_MANPAGE_HEADER})
162
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
163
- assert_includes output.lines, %(. LINKSTYLE cyan R &lt; &gt;\n)
164
-
165
- input = %(:man-linkstyle: pass:[cyan R < >]
166
- #{SAMPLE_MANPAGE_HEADER})
167
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
168
- assert_includes output.lines, %(. LINKSTYLE cyan R < >\n)
169
- end
170
- end
171
-
172
- context 'Manify' do
173
- test 'should unescape literal ampersand' do
174
- input = %(#{SAMPLE_MANPAGE_HEADER}
175
-
176
- (C) & (R) are translated to character references, but not the &.)
177
- output = Asciidoctor.convert input, :backend => :manpage
178
- assert_equal '\\(co & \\(rg are translated to character references, but not the &.', output.lines.entries.last.chomp
179
- end
180
-
181
- test 'should replace em dashes' do
182
- input = %(#{SAMPLE_MANPAGE_HEADER}
183
-
184
- go -- to
185
-
186
- go--to)
187
- output = Asciidoctor.convert input, :backend => :manpage
188
- assert_includes output, 'go \\(em to'
189
- assert_includes output, 'go\\(emto'
190
- end
191
-
192
- test 'should escape lone period' do
193
- input = %(#{SAMPLE_MANPAGE_HEADER}
194
-
195
- .)
196
- output = Asciidoctor.convert input, :backend => :manpage
197
- assert_equal '\&.', output.lines.entries.last.chomp
198
- end
199
-
200
- test 'should escape raw macro' do
201
- input = %(#{SAMPLE_MANPAGE_HEADER}
202
-
203
- AAA this line of text should be show
204
- .if 1 .nx
205
- BBB this line and the one above it should be visible)
206
-
207
- output = Asciidoctor.convert input, :backend => :manpage
208
- assert_equal '\&.if 1 .nx', output.lines.entries[-2].chomp
209
- end
210
-
211
- test 'should normalize whitespace in a paragraph' do
212
- input = %(#{SAMPLE_MANPAGE_HEADER}
213
-
214
- Oh, here it goes again
215
- I should have known,
216
- should have known,
217
- should have known again)
218
-
219
- output = Asciidoctor.convert input, :backend => :manpage
220
- assert_includes output, %(Oh, here it goes again\nI should have known,\nshould have known,\nshould have known again)
221
- end
222
-
223
- test 'should normalize whitespace in a list item' do
224
- input = %(#{SAMPLE_MANPAGE_HEADER}
225
-
226
- * Oh, here it goes again
227
- I should have known,
228
- should have known,
229
- should have known again)
230
-
231
- output = Asciidoctor.convert input, :backend => :manpage
232
- assert_includes output, %(Oh, here it goes again\nI should have known,\nshould have known,\nshould have known again)
233
- end
234
-
235
- test 'should collapse whitespace in the man manual and man source' do
236
- input = %(#{SAMPLE_MANPAGE_HEADER}
237
-
238
- Describe this thing.)
239
-
240
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true, :attributes => {
241
- 'manmanual' => %(General\nCommands\nManual),
242
- 'mansource' => %(Control\nAll\nThe\nThings\n5.0)
243
- }
244
- assert_includes output, 'Manual: General Commands Manual'
245
- assert_includes output, 'Source: Control All The Things 5.0'
246
- assert_includes output, '"Control All The Things 5.0" "General Commands Manual"'
247
- end
248
- end
249
-
250
- context 'Backslash' do
251
- test 'should not escape spaces for empty manual or source fields' do
252
- input = SAMPLE_MANPAGE_HEADER.lines.select {|l| !l.start_with?(':man ') }
253
- output = Asciidoctor.convert input, :backend => :manpage, :header_footer => true
254
- assert_match ' Manual: \ \&', output
255
- assert_match ' Source: \ \&', output
256
- assert_match(/^\.TH "COMMAND" .* "\\ \\&" "\\ \\&"$/, output)
257
- end
258
-
259
- test 'should preserve backslashes in escape sequences' do
260
- input = %(#{SAMPLE_MANPAGE_HEADER}
261
-
262
- "`hello`" '`goodbye`' *strong* _weak_ `even`)
263
- output = Asciidoctor.convert input, :backend => :manpage
264
- assert_equal '\(lqhello\(rq \(oqgoodbye\(cq \fBstrong\fP \fIweak\fP \f(CReven\fP', output.lines.entries.last.chomp
265
- end
266
-
267
- test 'should escape backslashes in content' do
268
- input = %(#{SAMPLE_MANPAGE_HEADER}
269
-
270
- \\.foo \\ bar\\
271
- baz)
272
- output = Asciidoctor.convert input, :backend => :manpage
273
- assert_equal '\(rs.foo \(rs bar\(rs', output.lines.entries[-2].chomp
274
- end
275
-
276
- test 'should escape literal escape sequence' do
277
- input = %(#{SAMPLE_MANPAGE_HEADER}
278
-
279
- \\fB makes text bold)
280
- output = Asciidoctor.convert input, :backend => :manpage
281
- assert_match '\(rsfB makes text bold', output
282
- end
283
-
284
- test 'should preserve inline breaks' do
285
- input = %(#{SAMPLE_MANPAGE_HEADER}
286
-
287
- Before break. +
288
- After break.)
289
- output = Asciidoctor.convert input, :backend => :manpage
290
- assert_equal 'Before break.
291
- .br
292
- After break.', output.lines.entries[-3..-1].join
293
- end
294
- end
295
-
296
- context 'URL macro' do
297
- test 'should not leave blank line before URL macro' do
298
- input = %(#{SAMPLE_MANPAGE_HEADER}
299
- First paragraph.
300
-
301
- http://asciidoc.org[AsciiDoc])
302
- output = Asciidoctor.convert input, :backend => :manpage
303
- assert_equal '.sp
304
- First paragraph.
305
- .sp
306
- .URL "http://asciidoc.org" "AsciiDoc" ""', output.lines.entries[-4..-1].join
307
- end
308
-
309
- test 'should not swallow content following URL' do
310
- input = %(#{SAMPLE_MANPAGE_HEADER}
311
-
312
- http://asciidoc.org[AsciiDoc] can be used to create man pages.)
313
- output = Asciidoctor.convert input, :backend => :manpage
314
- assert_equal '.URL "http://asciidoc.org" "AsciiDoc" " "
315
- can be used to create man pages.', output.lines.entries[-2..-1].join
316
- end
317
-
318
- test 'should pass adjacent character as final argument of URL macro' do
319
- input = %(#{SAMPLE_MANPAGE_HEADER}
320
-
321
- This is http://asciidoc.org[AsciiDoc].)
322
- output = Asciidoctor.convert input, :backend => :manpage
323
- assert_equal 'This is \c
324
- .URL "http://asciidoc.org" "AsciiDoc" "."', output.lines.entries[-2..-1].join
325
- end
326
-
327
- test 'should pass adjacent character as final argument of URL macro and move trailing content to next line' do
328
- input = %(#{SAMPLE_MANPAGE_HEADER}
329
-
330
- This is http://asciidoc.org[AsciiDoc], which can be used to write content.)
331
- output = Asciidoctor.convert input, :backend => :manpage
332
- assert_equal 'This is \c
333
- .URL "http://asciidoc.org" "AsciiDoc" ","
334
- which can be used to write content.', output.lines.entries[-3..-1].join
335
- end
336
-
337
- test 'should not leave blank lines between URLs on contiguous lines of input' do
338
- input = %(#{SAMPLE_MANPAGE_HEADER}
339
-
340
- The corresponding implementations are
341
- http://clisp.sf.net[CLISP],
342
- http://ccl.clozure.com[Clozure CL],
343
- http://cmucl.org[CMUCL],
344
- http://ecls.sf.net[ECL],
345
- and http://sbcl.sf.net[SBCL].)
346
- output = Asciidoctor.convert input, :backend => :manpage
347
- assert_equal '.sp
348
- The corresponding implementations are
349
- .URL "http://clisp.sf.net" "CLISP" ","
350
- .URL "http://ccl.clozure.com" "Clozure CL" ","
351
- .URL "http://cmucl.org" "CMUCL" ","
352
- .URL "http://ecls.sf.net" "ECL" ","
353
- and \c
354
- .URL "http://sbcl.sf.net" "SBCL" "."', output.lines.entries[-8..-1].join
355
- end
356
-
357
- test 'should not leave blank lines between URLs on same line of input' do
358
- input = %(#{SAMPLE_MANPAGE_HEADER}
359
-
360
- The corresponding implementations are http://clisp.sf.net[CLISP], http://ccl.clozure.com[Clozure CL], http://cmucl.org[CMUCL], http://ecls.sf.net[ECL], and http://sbcl.sf.net[SBCL].)
361
- output = Asciidoctor.convert input, :backend => :manpage
362
- assert_equal '.sp
363
- The corresponding implementations are \c
364
- .URL "http://clisp.sf.net" "CLISP" ","
365
- .URL "http://ccl.clozure.com" "Clozure CL" ","
366
- .URL "http://cmucl.org" "CMUCL" ","
367
- .URL "http://ecls.sf.net" "ECL" ","
368
- and
369
- .URL "http://sbcl.sf.net" "SBCL" "."', output.lines.entries[-8..-1].join
370
- end
371
-
372
- test 'should not insert space between link and non-whitespace characters surrounding it' do
373
- input = %(#{SAMPLE_MANPAGE_HEADER}
374
-
375
- Please search |link:http://discuss.asciidoctor.org[the forums]| before asking.)
376
- output = Asciidoctor.convert input, :backend => :manpage
377
- assert_equal '.sp
378
- Please search |\c
379
- .URL "http://discuss.asciidoctor.org" "the forums" "|"
380
- before asking.', output.lines.entries[-4..-1].join
381
- end
382
-
383
- test 'should be able to use monospaced text inside a link' do
384
- input = %(#{SAMPLE_MANPAGE_HEADER}
385
-
386
- Enter the link:cat[`cat`] command.)
387
- output = Asciidoctor.convert input, :backend => :manpage
388
- assert_equal '.sp
389
- Enter the \c
390
- .URL "cat" "\f(CRcat\fP" " "
391
- command.', output.lines.entries[-4..-1].join
392
- end
393
- end
394
-
395
- context 'MTO macro' do
396
- test 'should convert inline email macro into MTO macro' do
397
- input = %(#{SAMPLE_MANPAGE_HEADER}
398
- First paragraph.
399
-
400
- mailto:doc@example.org[Contact the doc])
401
- output = Asciidoctor.convert input, :backend => :manpage
402
- assert_equal '.sp
403
- First paragraph.
404
- .sp
405
- .MTO "doc\\(atexample.org" "Contact the doc" ""', output.lines.entries[-4..-1].join
406
- end
407
-
408
- test 'should set text of MTO macro to blank for implicit email' do
409
- input = %(#{SAMPLE_MANPAGE_HEADER}
410
- Bugs fixed daily by doc@example.org.)
411
- output = Asciidoctor.convert input, :backend => :manpage
412
- assert output.end_with? 'Bugs fixed daily by \\c
413
- .MTO "doc\\(atexample.org" "" "."'
414
- end
415
- end
416
-
417
- context 'Table' do
418
- test 'should create header, body, and footer rows in correct order' do
419
- input = %(#{SAMPLE_MANPAGE_HEADER}
420
-
421
- [%header%footer]
422
- |===
423
- |Header
424
- |Body 1
425
- |Body 2
426
- |Footer
427
- |===)
428
- output = Asciidoctor.convert input, :backend => :manpage
429
- assert output.end_with? 'allbox tab(:);
430
- lt.
431
- T{
432
- .sp
433
- Header
434
- T}
435
- T{
436
- .sp
437
- Body 1
438
- T}
439
- T{
440
- .sp
441
- Body 2
442
- T}
443
- T{
444
- .sp
445
- Footer
446
- T}
447
- .TE
448
- .sp'
449
- end
450
-
451
- test 'should manify normal table cell content' do
452
- input = %(#{SAMPLE_MANPAGE_HEADER}
453
-
454
- |===
455
- |*Col A* |_Col B_
456
-
457
- |*bold* |`mono`
458
- |_italic_ | #mark#
459
- |===)
460
- output = Asciidoctor.convert input, :backend => :manpage
461
- refute_match(/<\/?BOUNDARY>/, output)
462
- end
463
-
464
- test 'should manify table title' do
465
- input = %(#{SAMPLE_MANPAGE_HEADER}
466
-
467
- .Table of options
468
- |===
469
- | Name | Description | Default
470
-
471
- | dim
472
- | dimension of the object
473
- | 3
474
- |===)
475
- output = Asciidoctor.convert input, :backend => :manpage
476
- assert output.end_with? '.it 1 an-trap
477
- .nr an-no-space-flag 1
478
- .nr an-break-flag 1
479
- .br
480
- .B Table 1. Table of options
481
- .TS
482
- allbox tab(:);
483
- lt lt lt.
484
- T{
485
- .sp
486
- Name
487
- T}:T{
488
- .sp
489
- Description
490
- T}:T{
491
- .sp
492
- Default
493
- T}
494
- T{
495
- .sp
496
- dim
497
- T}:T{
498
- .sp
499
- dimension of the object
500
- T}:T{
501
- .sp
502
- 3
503
- T}
504
- .TE
505
- .sp'
506
- end
507
-
508
- test 'should manify and preserve whitespace in literal table cell' do
509
- input = %(#{SAMPLE_MANPAGE_HEADER}
510
-
511
- |===
512
- |a l|b
513
- c _d_
514
- .
515
- |===)
516
- output = Asciidoctor.convert input, :backend => :manpage
517
- assert output.end_with? '.TS
518
- allbox tab(:);
519
- lt lt.
520
- T{
521
- .sp
522
- a
523
- T}:T{
524
- .sp
525
- .nf
526
- b
527
- c _d_
528
- \\&.
529
- .fi
530
- T}
531
- .TE
532
- .sp'
533
- end
534
-
535
- test 'should manify and preserve whitespace in verse table cell' do
536
- input = %(#{SAMPLE_MANPAGE_HEADER}
537
-
538
- |===
539
- |a v|b
540
- c _d_
541
- .
542
- |===)
543
- output = Asciidoctor.convert input, :backend => :manpage
544
- assert output.end_with? '.TS
545
- allbox tab(:);
546
- lt lt.
547
- T{
548
- .sp
549
- a
550
- T}:T{
551
- .sp
552
- .nf
553
- b
554
- c \\fId\\fP
555
- \\&.
556
- .fi
557
- T}
558
- .TE
559
- .sp'
560
- end
561
- end
562
-
563
- context 'Images' do
564
- test 'should replace inline image with alt text' do
565
- input = %(#{SAMPLE_MANPAGE_HEADER}
566
-
567
- The Magic 8 Ball says image:signs-point-to-yes.jpg[].)
568
- output = Asciidoctor.convert input, :backend => :manpage
569
- assert_includes output, 'The Magic 8 Ball says [signs point to yes].'
570
- end
571
-
572
- test 'should place link after alt text for inline image if link is defined' do
573
- input = %(#{SAMPLE_MANPAGE_HEADER}
574
-
575
- The Magic 8 Ball says image:signs-point-to-yes.jpg[link=https://en.wikipedia.org/wiki/Magic_8-Ball].)
576
- output = Asciidoctor.convert input, :backend => :manpage
577
- assert_includes output, 'The Magic 8 Ball says [signs point to yes] <https://en.wikipedia.org/wiki/Magic_8\-Ball>.'
578
- end
579
- end
580
-
581
- context 'Quote Block' do
582
- test 'should indent quote block' do
583
- input = %(#{SAMPLE_MANPAGE_HEADER}
584
-
585
- [,James Baldwin]
586
- ____
587
- Not everything that is faced can be changed.
588
- But nothing can be changed until it is faced.
589
- ____)
590
- output = Asciidoctor.convert input, :backend => :manpage
591
- assert output.end_with? '.RS 3
592
- .ll -.6i
593
- .sp
594
- Not everything that is faced can be changed.
595
- But nothing can be changed until it is faced.
596
- .br
597
- .RE
598
- .ll
599
- .RS 5
600
- .ll -.10i
601
- \(em James Baldwin
602
- .RE
603
- .ll'
604
- end
605
- end
606
-
607
- context 'Callout List' do
608
- test 'should generate callout list using proper formatting commands' do
609
- input = %(#{SAMPLE_MANPAGE_HEADER}
610
-
611
- ----
612
- $ gem install asciidoctor # <1>
613
- ----
614
- <1> Installs the asciidoctor gem from RubyGems.org)
615
- output = Asciidoctor.convert input, :backend => :manpage
616
- assert output.end_with? '.TS
617
- tab(:);
618
- r lw(\n(.lu*75u/100u).
619
- \fB(1)\fP\h\'-2n\':T{
620
- Installs the asciidoctor gem from RubyGems.org
621
- T}
622
- .TE'
623
- end
624
- end
625
-
626
- context 'Environment' do
627
- test 'should use SOURCE_DATE_EPOCH as modified time of input file and local time' do
628
- old_source_date_epoch = ENV.delete 'SOURCE_DATE_EPOCH'
629
- begin
630
- ENV['SOURCE_DATE_EPOCH'] = '1234123412'
631
- output = Asciidoctor.convert SAMPLE_MANPAGE_HEADER, :backend => :manpage, :header_footer => true
632
- assert_match(/Date: 2009-02-08/, output)
633
- assert_match(/^\.TH "COMMAND" "1" "2009-02-08" "Command 1.2.3" "Command Manual"$/, output)
634
- ensure
635
- if old_source_date_epoch
636
- ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch
637
- else
638
- ENV.delete 'SOURCE_DATE_EPOCH'
639
- end
640
- end
641
- end
642
-
643
- test 'should fail if SOURCE_DATE_EPOCH is malformed' do
644
- old_source_date_epoch = ENV.delete 'SOURCE_DATE_EPOCH'
645
- begin
646
- ENV['SOURCE_DATE_EPOCH'] = 'aaaaaaaa'
647
- Asciidoctor.convert SAMPLE_MANPAGE_HEADER, :backend => :manpage, :header_footer => true
648
- assert false
649
- rescue
650
- assert true
651
- ensure
652
- if old_source_date_epoch
653
- ENV['SOURCE_DATE_EPOCH'] = old_source_date_epoch
654
- else
655
- ENV.delete 'SOURCE_DATE_EPOCH'
656
- end
657
- end
658
- end
659
- end
660
- end