asciidoctor 1.5.8 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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