asciidoctor 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +10 -0
- data/Guardfile +18 -0
- data/LICENSE +1 -1
- data/README.adoc +65 -21
- data/Rakefile +10 -0
- data/asciidoctor.gemspec +17 -35
- data/compat/asciidoc.conf +130 -13
- data/lib/asciidoctor.rb +107 -87
- data/lib/asciidoctor/abstract_block.rb +6 -2
- data/lib/asciidoctor/abstract_node.rb +21 -13
- data/lib/asciidoctor/attribute_list.rb +2 -5
- data/{stylesheets/asciidoctor.css → lib/asciidoctor/backends/_stylesheets.rb} +96 -46
- data/lib/asciidoctor/backends/base_template.rb +9 -4
- data/lib/asciidoctor/backends/docbook45.rb +246 -138
- data/lib/asciidoctor/backends/html5.rb +580 -381
- data/lib/asciidoctor/block.rb +2 -50
- data/lib/asciidoctor/cli/options.rb +9 -8
- data/lib/asciidoctor/document.rb +35 -45
- data/lib/asciidoctor/helpers.rb +10 -0
- data/lib/asciidoctor/lexer.rb +456 -148
- data/lib/asciidoctor/list_item.rb +0 -21
- data/lib/asciidoctor/path_resolver.rb +18 -12
- data/lib/asciidoctor/reader.rb +71 -26
- data/lib/asciidoctor/renderer.rb +2 -19
- data/lib/asciidoctor/section.rb +0 -1
- data/lib/asciidoctor/substituters.rb +150 -36
- data/lib/asciidoctor/table.rb +30 -24
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +22 -16
- data/man/asciidoctor.ad +24 -16
- data/test/attributes_test.rb +50 -0
- data/test/blocks_test.rb +660 -9
- data/test/document_test.rb +191 -14
- data/test/fixtures/encoding.asciidoc +8 -0
- data/test/invoker_test.rb +47 -0
- data/test/lexer_test.rb +172 -0
- data/test/links_test.rb +28 -0
- data/test/lists_test.rb +172 -13
- data/test/options_test.rb +29 -2
- data/test/paragraphs_test.rb +105 -47
- data/test/paths_test.rb +3 -3
- data/test/reader_test.rb +46 -0
- data/test/sections_test.rb +365 -12
- data/test/substitutions_test.rb +127 -11
- data/test/tables_test.rb +81 -14
- data/test/test_helper.rb +18 -7
- data/test/text_test.rb +17 -5
- metadata +9 -36
data/lib/asciidoctor/table.rb
CHANGED
@@ -44,12 +44,6 @@ class Table < AbstractBlock
|
|
44
44
|
}
|
45
45
|
}
|
46
46
|
|
47
|
-
# Public: A compiled Regexp to match a blank line
|
48
|
-
BLANK_LINE_PATTERN = /\n[[:blank:]]*\n/
|
49
|
-
|
50
|
-
# Public: Get/Set the String caption (unused, necessary for compatibility w/ next_block)
|
51
|
-
attr_accessor :caption
|
52
|
-
|
53
47
|
# Public: Get/Set the columns for this table
|
54
48
|
attr_accessor :columns
|
55
49
|
|
@@ -57,23 +51,24 @@ class Table < AbstractBlock
|
|
57
51
|
# and body rows)
|
58
52
|
attr_accessor :rows
|
59
53
|
|
54
|
+
# Public: Boolean specifies whether this table has a header row
|
55
|
+
attr_reader :header_option
|
56
|
+
|
60
57
|
def initialize(parent, attributes)
|
61
58
|
super(parent, :table)
|
62
|
-
# QUESTION since caption is on block, should it go to AbstractBlock?
|
63
|
-
@caption = nil
|
64
59
|
@rows = Rows.new([], [], [])
|
65
60
|
@columns = []
|
66
61
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
@attributes['tablepcwidth'] = pcwidth_intval
|
62
|
+
@has_header_option = attributes.has_key? 'header-option'
|
63
|
+
|
64
|
+
# smell like we need a utility method here
|
65
|
+
# to resolve an integer width from potential bogus input
|
66
|
+
pcwidth = attributes['width']
|
67
|
+
pcwidth_intval = pcwidth.to_i.abs
|
68
|
+
if pcwidth_intval == 0 && pcwidth != "0" || pcwidth_intval > 100
|
69
|
+
pcwidth_intval = 100
|
76
70
|
end
|
71
|
+
@attributes['tablepcwidth'] = pcwidth_intval
|
77
72
|
|
78
73
|
if @document.attributes.has_key? 'pagewidth'
|
79
74
|
@attributes['tableabswidth'] ||=
|
@@ -81,6 +76,12 @@ class Table < AbstractBlock
|
|
81
76
|
end
|
82
77
|
end
|
83
78
|
|
79
|
+
# Internal: Returns whether the current row being processed is
|
80
|
+
# the header row
|
81
|
+
def header_row?
|
82
|
+
@has_header_option && @rows.body.size == 0
|
83
|
+
end
|
84
|
+
|
84
85
|
# Internal: Creates the Column objects from the column spec
|
85
86
|
#
|
86
87
|
# returns nothing
|
@@ -130,9 +131,6 @@ class Table < AbstractBlock
|
|
130
131
|
# rendered and returned as content that can be included in the
|
131
132
|
# parent block's template.
|
132
133
|
def render
|
133
|
-
Debug.debug { "Now attempting to render for table my own bad #{self}" }
|
134
|
-
Debug.debug { "Parent is #{@parent}" }
|
135
|
-
Debug.debug { "Renderer is #{renderer}" }
|
136
134
|
@document.playback_attributes @attributes
|
137
135
|
renderer.render('block_table', self)
|
138
136
|
end
|
@@ -154,6 +152,9 @@ class Table::Column < AbstractNode
|
|
154
152
|
update_attributes(attributes)
|
155
153
|
end
|
156
154
|
|
155
|
+
# Public: An alias to the parent block (which is always a Table)
|
156
|
+
alias :table :parent
|
157
|
+
|
157
158
|
# Internal: Calculate and assign the widths (percentage and absolute) for this column
|
158
159
|
#
|
159
160
|
# This method assigns the colpcwidth and colabswidth attributes.
|
@@ -209,14 +210,19 @@ class Table::Cell < AbstractNode
|
|
209
210
|
end
|
210
211
|
update_attributes(attributes)
|
211
212
|
end
|
212
|
-
|
213
|
+
# only allow AsciiDoc cells in non-header rows
|
214
|
+
if @attributes['style'] == :asciidoc && !column.table.header_row?
|
215
|
+
# FIXME hide doctitle from nested document; temporary workaround to fix
|
216
|
+
# nested document seeing doctitle and assuming it has its own document title
|
217
|
+
parent_doctitle = @document.attributes.delete('doctitle')
|
213
218
|
@inner_document = Document.new(@text, :header_footer => false, :parent => @document)
|
219
|
+
@document.attributes['doctitle'] = parent_doctitle unless parent_doctitle.nil?
|
214
220
|
end
|
215
221
|
end
|
216
222
|
|
217
223
|
# Public: Get the text with normal substitutions applied for this cell. Used for cells in the head rows
|
218
224
|
def text
|
219
|
-
apply_normal_subs(@text)
|
225
|
+
apply_normal_subs(@text).strip
|
220
226
|
end
|
221
227
|
|
222
228
|
# Public: Handles the body data (tbody, tfoot), applying styles and partitioning into paragraphs
|
@@ -225,7 +231,7 @@ class Table::Cell < AbstractNode
|
|
225
231
|
if style == :asciidoc
|
226
232
|
@inner_document.render
|
227
233
|
else
|
228
|
-
text.split(
|
234
|
+
text.split(BLANK_LINE_PATTERN).map {|p|
|
229
235
|
!style || style == :header ? p : Inline.new(parent, :quoted, p, :type => attr('style')).render
|
230
236
|
}
|
231
237
|
end
|
@@ -314,7 +320,7 @@ class Table::ParserContext
|
|
314
320
|
#
|
315
321
|
# returns the String after the match
|
316
322
|
def skip_matched_delimiter(match, escaped = false)
|
317
|
-
@buffer
|
323
|
+
@buffer = %(#@buffer#{escaped ? match.pre_match.chop : match.pre_match}#@delimiter)
|
318
324
|
match.post_match
|
319
325
|
end
|
320
326
|
|
data/lib/asciidoctor/version.rb
CHANGED
data/man/asciidoctor.1
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
.\" Title: asciidoctor
|
3
3
|
.\" Author: [see the "AUTHORS" section]
|
4
4
|
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
|
5
|
-
.\" Date:
|
5
|
+
.\" Date: 05/30/2013
|
6
6
|
.\" Manual: \ \&
|
7
7
|
.\" Source: \ \&
|
8
8
|
.\" Language: English
|
9
9
|
.\"
|
10
|
-
.TH "ASCIIDOCTOR" "1" "
|
10
|
+
.TH "ASCIIDOCTOR" "1" "05/30/2013" "\ \&" "\ \&"
|
11
11
|
.\" -----------------------------------------------------------------
|
12
12
|
.\" * Define some portability stuff
|
13
13
|
.\" -----------------------------------------------------------------
|
@@ -71,20 +71,22 @@ when Asciidoctor is invoked using this script\&.
|
|
71
71
|
Define, override or delete a document attribute\&. Command\-line attributes take precedence over attributes defined in the source file\&.
|
72
72
|
.sp
|
73
73
|
\fIATTRIBUTE\fR
|
74
|
-
is formatted as a key\-value pair, in the form
|
75
|
-
\fINAME=VALUE\fR\&.
|
74
|
+
is normally formatted as a key\-value pair, in the form
|
75
|
+
\fINAME=VALUE\fR\&. Alternate acceptable forms are
|
76
76
|
\fINAME\fR
|
77
|
-
(the
|
77
|
+
(where the
|
78
78
|
\fIVALUE\fR
|
79
79
|
defaults to an empty string),
|
80
80
|
\fINAME!\fR
|
81
|
-
(
|
81
|
+
(unassigns the
|
82
82
|
\fINAME\fR
|
83
83
|
attribute) and
|
84
84
|
\fINAME=VALUE@\fR
|
85
|
-
(
|
85
|
+
(where
|
86
|
+
\fIVALUE\fR
|
87
|
+
does not override value of
|
86
88
|
\fINAME\fR
|
87
|
-
attribute if already defined in the source
|
89
|
+
attribute if it\(cqs already defined in the source document)\&. Values containing spaces should be enclosed in quotes\&.
|
88
90
|
.sp
|
89
91
|
This option may be specified more than once\&.
|
90
92
|
.RE
|
@@ -94,28 +96,32 @@ This option may be specified more than once\&.
|
|
94
96
|
Backend output file format:
|
95
97
|
\fIdocbook45\fR
|
96
98
|
or
|
97
|
-
\fIhtml5\fR
|
99
|
+
\fIhtml5\fR
|
100
|
+
supported out of the box\&. You can also use the backend alias names
|
98
101
|
\fIhtml\fR
|
99
102
|
(aliased to
|
100
103
|
\fIhtml5\fR) or
|
101
104
|
\fIdocbook\fR
|
102
105
|
(aliased to
|
103
106
|
\fIdocbook45\fR)\&. Defaults to
|
104
|
-
\fIhtml5\fR\&.
|
107
|
+
\fIhtml5\fR\&. Other options can be passed, but if Asciidoctor cannot find the backend, it will fail during rendering\&.
|
105
108
|
.RE
|
106
109
|
.PP
|
107
110
|
\fB\-d, \-\-doctype\fR=\fIDOCTYPE\fR
|
108
111
|
.RS 4
|
109
112
|
Document type:
|
110
|
-
\fIarticle\fR
|
113
|
+
\fIarticle\fR,
|
114
|
+
\fIbook\fR
|
111
115
|
or
|
112
|
-
\
|
116
|
+
\fIinline\fR\&. Sets the root element when using the
|
113
117
|
\fIdocbook\fR
|
114
118
|
backend and the style class on the HTML body element when using the
|
115
119
|
\fIhtml\fR
|
116
120
|
backend\&. The
|
117
121
|
\fIbook\fR
|
118
|
-
document type allows multiple level\-0 section titles in a single document\&.
|
122
|
+
document type allows multiple level\-0 section titles in a single document\&. The
|
123
|
+
\fIinline\fR
|
124
|
+
document type allows the content of a single paragraph to be formatted and returned without wrapping it in a containing element\&. Defaults to
|
119
125
|
\fIarticle\fR\&.
|
120
126
|
.RE
|
121
127
|
.SS "Rendering Control"
|
@@ -164,7 +170,7 @@ Suppress the document header and footer in the output\&.
|
|
164
170
|
.PP
|
165
171
|
\fB\-T, \-\-template\-dir\fR=\fIDIR\fR
|
166
172
|
.RS 4
|
167
|
-
Directory containing custom render templates that override one or more templates from the
|
173
|
+
Directory containing custom render templates that override one or more templates from the built\-in set\&. If there is a folder in the directory that matches the backend, the templates from that folder will be used\&.
|
168
174
|
.RE
|
169
175
|
.SS "Processing Information"
|
170
176
|
.PP
|
@@ -204,7 +210,7 @@ Failure (syntax or usage error; configuration error; document processing failure
|
|
204
210
|
See the \fBAsciidoctor\fR issue tracker: <\fBhttps://github\&.com/asciidoctor/asciidoctor/issues?state=open\fR>
|
205
211
|
.SH "AUTHORS"
|
206
212
|
.sp
|
207
|
-
\fBAsciidoctor\fR was written by Ryan Waldron,
|
213
|
+
\fBAsciidoctor\fR was written by Dan Allen, Ryan Waldron, Jason Porter, Nick Hengeveld and other contributors\&.
|
208
214
|
.sp
|
209
215
|
\fBAsciiDoc\fR was written by Stuart Rackham and has received contributions from many other individuals\&.
|
210
216
|
.SH "RESOURCES"
|
@@ -218,4 +224,4 @@ GitHub organization: <\fBhttp://github\&.com/asciidoctor\fR>
|
|
218
224
|
Mailinglist / forum: <\fBhttp://discuss\&.asciidoctor\&.org\fR>
|
219
225
|
.SH "COPYING"
|
220
226
|
.sp
|
221
|
-
Copyright (C)
|
227
|
+
Copyright (C) 2012\-2013 Dan Allen and Ryan Waldron\&. Free use of this software is granted under the terms of the MIT License\&.
|
data/man/asciidoctor.ad
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
asciidoctor(1)
|
2
2
|
==============
|
3
3
|
:doctype: manpage
|
4
|
+
:awestruct-layout: base
|
4
5
|
|
5
6
|
|
6
7
|
NAME
|
@@ -52,24 +53,28 @@ Document Settings
|
|
52
53
|
Define, override or delete a document attribute. Command-line attributes
|
53
54
|
take precedence over attributes defined in the source file.
|
54
55
|
+
|
55
|
-
'ATTRIBUTE' is formatted as a key-value pair, in the form 'NAME=VALUE'.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
'ATTRIBUTE' is normally formatted as a key-value pair, in the form 'NAME=VALUE'.
|
57
|
+
Alternate acceptable forms are 'NAME' (where the 'VALUE' defaults to an empty
|
58
|
+
string), 'NAME!' (unassigns the 'NAME' attribute) and 'NAME=VALUE@' (where
|
59
|
+
'VALUE' does not override value of 'NAME' attribute if it's already defined in
|
60
|
+
the source document). Values containing spaces should be enclosed in quotes.
|
60
61
|
+
|
61
62
|
This option may be specified more than once.
|
62
63
|
|
63
64
|
*-b, --backend*='BACKEND'::
|
64
|
-
Backend output file format: 'docbook45' or 'html5'
|
65
|
-
backend alias names 'html' (aliased to 'html5') or
|
66
|
-
'docbook45'). Defaults to 'html5'.
|
65
|
+
Backend output file format: 'docbook45' or 'html5' supported out of the box.
|
66
|
+
You can also use the backend alias names 'html' (aliased to 'html5') or
|
67
|
+
'docbook' (aliased to 'docbook45'). Defaults to 'html5'. Other options can
|
68
|
+
be passed, but if Asciidoctor cannot find the backend, it will fail during
|
69
|
+
rendering.
|
67
70
|
|
68
71
|
*-d, --doctype*='DOCTYPE'::
|
69
|
-
Document type: 'article' or '
|
70
|
-
'docbook' backend and the style class on the HTML body element
|
71
|
-
the 'html' backend. The 'book' document type allows multiple
|
72
|
-
section titles in a single document.
|
72
|
+
Document type: 'article', 'book' or 'inline'. Sets the root element when
|
73
|
+
using the 'docbook' backend and the style class on the HTML body element
|
74
|
+
when using the 'html' backend. The 'book' document type allows multiple
|
75
|
+
level-0 section titles in a single document. The 'inline' document type
|
76
|
+
allows the content of a single paragraph to be formatted and returned
|
77
|
+
without wrapping it in a containing element. Defaults to 'article'.
|
73
78
|
|
74
79
|
Rendering Control
|
75
80
|
~~~~~~~~~~~~~~~~~
|
@@ -101,7 +106,7 @@ Rendering Control
|
|
101
106
|
|
102
107
|
*-T, --template-dir*='DIR'::
|
103
108
|
Directory containing custom render templates that override one or more
|
104
|
-
templates from the
|
109
|
+
templates from the built-in set. If there is a folder in the directory
|
105
110
|
that matches the backend, the templates from that folder will be used.
|
106
111
|
|
107
112
|
Processing Information
|
@@ -141,7 +146,8 @@ See the *Asciidoctor* issue tracker: <**https://github.com/asciidoctor/asciidoct
|
|
141
146
|
|
142
147
|
AUTHORS
|
143
148
|
-------
|
144
|
-
*Asciidoctor* was written by Ryan Waldron,
|
149
|
+
*Asciidoctor* was written by Dan Allen, Ryan Waldron, Jason Porter, Nick
|
150
|
+
Hengeveld and other contributors.
|
145
151
|
|
146
152
|
*AsciiDoc* was written by Stuart Rackham and has received contributions from
|
147
153
|
many other individuals.
|
@@ -160,5 +166,7 @@ Mailinglist / forum: <**http://discuss.asciidoctor.org**>
|
|
160
166
|
|
161
167
|
COPYING
|
162
168
|
-------
|
163
|
-
Copyright \(C)
|
164
|
-
under the terms of the MIT License.
|
169
|
+
Copyright \(C) 2012-2013 Dan Allen and Ryan Waldron. Free use of this
|
170
|
+
software is granted under the terms of the MIT License.
|
171
|
+
|
172
|
+
// vim: tw=80
|
data/test/attributes_test.rb
CHANGED
@@ -332,6 +332,34 @@ of the attribute named foo in your document.
|
|
332
332
|
assert_xpath %(//li[1]/p[text()="docdir: #{docdir}"]), output, 1
|
333
333
|
assert_xpath %(//li[2]/p[text()="docfile: #{docfile}"]), output, 1
|
334
334
|
end
|
335
|
+
|
336
|
+
test 'assigns attribute defined in attribute reference with set prefix and value' do
|
337
|
+
input = '{set:foo:bar}{foo}'
|
338
|
+
output = render_embedded_string input
|
339
|
+
assert_xpath '//p', output, 1
|
340
|
+
assert_xpath '//p[text()="bar"]', output, 1
|
341
|
+
end
|
342
|
+
|
343
|
+
test 'assigns attribute defined in attribute reference with set prefix and no value' do
|
344
|
+
input = "{set:foo}\n{foo}yes"
|
345
|
+
output = render_embedded_string input
|
346
|
+
assert_xpath '//p', output, 1
|
347
|
+
assert_xpath '//p[normalize-space(text())="yes"]', output, 1
|
348
|
+
end
|
349
|
+
|
350
|
+
test 'assigns attribute defined in attribute reference with set prefix and empty value' do
|
351
|
+
input = "{set:foo:}\n{foo}yes"
|
352
|
+
output = render_embedded_string input
|
353
|
+
assert_xpath '//p', output, 1
|
354
|
+
assert_xpath '//p[normalize-space(text())="yes"]', output, 1
|
355
|
+
end
|
356
|
+
|
357
|
+
test 'unassigns attribute defined in attribute reference with set prefix' do
|
358
|
+
input = ":foo:\n\n{set:foo!}\n{foo}yes"
|
359
|
+
output = render_embedded_string input
|
360
|
+
assert_xpath '//p', output, 1
|
361
|
+
assert_xpath '//p/child::text()', output, 0
|
362
|
+
end
|
335
363
|
end
|
336
364
|
|
337
365
|
context "Intrinsic attributes" do
|
@@ -531,6 +559,28 @@ A paragraph
|
|
531
559
|
assert_equal 'lead', para.attributes['role']
|
532
560
|
end
|
533
561
|
|
562
|
+
test 'id and role attributes can be specified on block style using shorthand syntax' do
|
563
|
+
input = <<-EOS
|
564
|
+
[normal#first.lead]
|
565
|
+
A normal paragraph.
|
566
|
+
EOS
|
567
|
+
doc = document_from_string(input)
|
568
|
+
para = doc.blocks.first
|
569
|
+
assert_equal 'first', para.attributes['id']
|
570
|
+
assert_equal 'lead', para.attributes['role']
|
571
|
+
end
|
572
|
+
|
573
|
+
test 'id and role attributes can be specified on section style using shorthand syntax' do
|
574
|
+
input = <<-EOS
|
575
|
+
[dedication#dedication.small]
|
576
|
+
== Section
|
577
|
+
Content.
|
578
|
+
EOS
|
579
|
+
output = render_embedded_string input
|
580
|
+
assert_xpath '/div[@class="sect1 small"]', output, 1
|
581
|
+
assert_xpath '/div[@class="sect1 small"]/h2[@id="dedication"]', output, 1
|
582
|
+
end
|
583
|
+
|
534
584
|
test "Block attributes are additive" do
|
535
585
|
input = <<-EOS
|
536
586
|
[id='foo']
|
data/test/blocks_test.rb
CHANGED
@@ -117,6 +117,252 @@ block comment
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
context 'Quote and Verse Blocks' do
|
121
|
+
test 'quote block with no attribution' do
|
122
|
+
input = <<-EOS
|
123
|
+
____
|
124
|
+
A famous quote.
|
125
|
+
____
|
126
|
+
EOS
|
127
|
+
output = render_string input
|
128
|
+
assert_css '.quoteblock', output, 1
|
129
|
+
assert_css '.quoteblock > blockquote', output, 1
|
130
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
131
|
+
assert_css '.quoteblock > .attribution', output, 0
|
132
|
+
assert_xpath '//*[@class = "quoteblock"]//p[text() = "A famous quote."]', output, 1
|
133
|
+
end
|
134
|
+
|
135
|
+
test 'quote block with attribution' do
|
136
|
+
input = <<-EOS
|
137
|
+
[quote, Famous Person, Famous Book (1999)]
|
138
|
+
____
|
139
|
+
A famous quote.
|
140
|
+
____
|
141
|
+
EOS
|
142
|
+
output = render_string input
|
143
|
+
assert_css '.quoteblock', output, 1
|
144
|
+
assert_css '.quoteblock > blockquote', output, 1
|
145
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
146
|
+
assert_css '.quoteblock > .attribution', output, 1
|
147
|
+
assert_css '.quoteblock > .attribution > cite', output, 1
|
148
|
+
assert_css '.quoteblock > .attribution > cite + br', output, 1
|
149
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Book (1999)"]', output, 1
|
150
|
+
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
151
|
+
author = attribution.children.last
|
152
|
+
assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
|
153
|
+
end
|
154
|
+
|
155
|
+
test 'quote block with attribute and id and role shorthand' do
|
156
|
+
input = <<-EOS
|
157
|
+
[quote#think.big, Donald Trump]
|
158
|
+
____
|
159
|
+
As long as your going to be thinking anyway, think big.
|
160
|
+
____
|
161
|
+
EOS
|
162
|
+
|
163
|
+
output = render_embedded_string input
|
164
|
+
assert_css '.quoteblock', output, 1
|
165
|
+
assert_css '#think.quoteblock.big', output, 1
|
166
|
+
assert_css '.quoteblock > .attribution', output, 1
|
167
|
+
end
|
168
|
+
|
169
|
+
test 'quote block with complex content' do
|
170
|
+
input = <<-EOS
|
171
|
+
____
|
172
|
+
A famous quote.
|
173
|
+
|
174
|
+
NOTE: _That_ was inspiring.
|
175
|
+
____
|
176
|
+
EOS
|
177
|
+
output = render_string input
|
178
|
+
assert_css '.quoteblock', output, 1
|
179
|
+
assert_css '.quoteblock > blockquote', output, 1
|
180
|
+
assert_css '.quoteblock > blockquote > .paragraph', output, 1
|
181
|
+
assert_css '.quoteblock > blockquote > .paragraph + .admonitionblock', output, 1
|
182
|
+
end
|
183
|
+
|
184
|
+
test 'quote block using air quotes with no attribution' do
|
185
|
+
input = <<-EOS
|
186
|
+
""
|
187
|
+
A famous quote.
|
188
|
+
""
|
189
|
+
EOS
|
190
|
+
output = render_string input
|
191
|
+
assert_css '.quoteblock', output, 1
|
192
|
+
assert_css '.quoteblock > blockquote', output, 1
|
193
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
194
|
+
assert_css '.quoteblock > .attribution', output, 0
|
195
|
+
assert_xpath '//*[@class = "quoteblock"]//p[text() = "A famous quote."]', output, 1
|
196
|
+
end
|
197
|
+
|
198
|
+
test 'markdown-style quote block with single paragraph and no attribution' do
|
199
|
+
input = <<-EOS
|
200
|
+
> A famous quote.
|
201
|
+
> Some more inspiring words.
|
202
|
+
EOS
|
203
|
+
output = render_string input
|
204
|
+
assert_css '.quoteblock', output, 1
|
205
|
+
assert_css '.quoteblock > blockquote', output, 1
|
206
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
207
|
+
assert_css '.quoteblock > .attribution', output, 0
|
208
|
+
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
209
|
+
end
|
210
|
+
|
211
|
+
test 'lazy markdown-style quote block with single paragraph and no attribution' do
|
212
|
+
input = <<-EOS
|
213
|
+
> A famous quote.
|
214
|
+
Some more inspiring words.
|
215
|
+
EOS
|
216
|
+
output = render_string input
|
217
|
+
assert_css '.quoteblock', output, 1
|
218
|
+
assert_css '.quoteblock > blockquote', output, 1
|
219
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
220
|
+
assert_css '.quoteblock > .attribution', output, 0
|
221
|
+
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
222
|
+
end
|
223
|
+
|
224
|
+
test 'markdown-style quote block with multiple paragraphs and no attribution' do
|
225
|
+
input = <<-EOS
|
226
|
+
> A famous quote.
|
227
|
+
>
|
228
|
+
> Some more inspiring words.
|
229
|
+
EOS
|
230
|
+
output = render_string input
|
231
|
+
assert_css '.quoteblock', output, 1
|
232
|
+
assert_css '.quoteblock > blockquote', output, 1
|
233
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 2
|
234
|
+
assert_css '.quoteblock > .attribution', output, 0
|
235
|
+
assert_xpath %((//*[@class = "quoteblock"]//p)[1][text() = "A famous quote."]), output, 1
|
236
|
+
assert_xpath %((//*[@class = "quoteblock"]//p)[2][text() = "Some more inspiring words."]), output, 1
|
237
|
+
end
|
238
|
+
|
239
|
+
test 'markdown-style quote block with multiple blocks and no attribution' do
|
240
|
+
input = <<-EOS
|
241
|
+
> A famous quote.
|
242
|
+
>
|
243
|
+
> NOTE: Some more inspiring words.
|
244
|
+
EOS
|
245
|
+
output = render_string input
|
246
|
+
assert_css '.quoteblock', output, 1
|
247
|
+
assert_css '.quoteblock > blockquote', output, 1
|
248
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
249
|
+
assert_css '.quoteblock > blockquote > .admonitionblock', output, 1
|
250
|
+
assert_css '.quoteblock > .attribution', output, 0
|
251
|
+
assert_xpath %((//*[@class = "quoteblock"]//p)[1][text() = "A famous quote."]), output, 1
|
252
|
+
assert_xpath %((//*[@class = "quoteblock"]//*[@class = "admonitionblock note"]//*[@class="content"])[1][normalize-space(text()) = "Some more inspiring words."]), output, 1
|
253
|
+
end
|
254
|
+
|
255
|
+
test 'markdown-style quote block with single paragraph and attribution' do
|
256
|
+
input = <<-EOS
|
257
|
+
> A famous quote.
|
258
|
+
> Some more inspiring words.
|
259
|
+
> -- Famous Person, Famous Source (1999)
|
260
|
+
EOS
|
261
|
+
output = render_string input
|
262
|
+
assert_css '.quoteblock', output, 1
|
263
|
+
assert_css '.quoteblock > blockquote', output, 1
|
264
|
+
assert_css '.quoteblock > blockquote > .paragraph > p', output, 1
|
265
|
+
assert_xpath %(//*[@class = "quoteblock"]//p[text() = "A famous quote.\nSome more inspiring words."]), output, 1
|
266
|
+
assert_css '.quoteblock > .attribution', output, 1
|
267
|
+
assert_css '.quoteblock > .attribution > cite', output, 1
|
268
|
+
assert_css '.quoteblock > .attribution > cite + br', output, 1
|
269
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source (1999)"]', output, 1
|
270
|
+
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
271
|
+
author = attribution.children.last
|
272
|
+
assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
|
273
|
+
end
|
274
|
+
|
275
|
+
test 'quoted paragraph-style quote block with attribution' do
|
276
|
+
input = <<-EOS
|
277
|
+
"A famous quote.
|
278
|
+
Some more inspiring words."
|
279
|
+
-- Famous Person, Famous Source (1999)
|
280
|
+
EOS
|
281
|
+
output = render_string input
|
282
|
+
assert_css '.quoteblock', output, 1
|
283
|
+
assert_css '.quoteblock > blockquote', output, 1
|
284
|
+
assert_xpath %(//*[@class = "quoteblock"]/blockquote[normalize-space(text()) = "A famous quote. Some more inspiring words."]), output, 1
|
285
|
+
assert_css '.quoteblock > .attribution', output, 1
|
286
|
+
assert_css '.quoteblock > .attribution > cite', output, 1
|
287
|
+
assert_css '.quoteblock > .attribution > cite + br', output, 1
|
288
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source (1999)"]', output, 1
|
289
|
+
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
290
|
+
author = attribution.children.last
|
291
|
+
assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
|
292
|
+
end
|
293
|
+
|
294
|
+
test 'single-line verse block without attribution' do
|
295
|
+
input = <<-EOS
|
296
|
+
[verse]
|
297
|
+
____
|
298
|
+
A famous verse.
|
299
|
+
____
|
300
|
+
EOS
|
301
|
+
output = render_string input
|
302
|
+
assert_css '.verseblock', output, 1
|
303
|
+
assert_css '.verseblock > pre', output, 1
|
304
|
+
assert_css '.verseblock > .attribution', output, 0
|
305
|
+
assert_css '.verseblock p', output, 0
|
306
|
+
assert_xpath '//*[@class = "verseblock"]/pre[normalize-space(text()) = "A famous verse."]', output, 1
|
307
|
+
end
|
308
|
+
|
309
|
+
test 'single-line verse block with attribution' do
|
310
|
+
input = <<-EOS
|
311
|
+
[verse, Famous Poet, Famous Poem]
|
312
|
+
____
|
313
|
+
A famous verse.
|
314
|
+
____
|
315
|
+
EOS
|
316
|
+
output = render_string input
|
317
|
+
assert_css '.verseblock', output, 1
|
318
|
+
assert_css '.verseblock p', output, 0
|
319
|
+
assert_css '.verseblock > pre', output, 1
|
320
|
+
assert_css '.verseblock > .attribution', output, 1
|
321
|
+
assert_css '.verseblock > .attribution > cite', output, 1
|
322
|
+
assert_css '.verseblock > .attribution > cite + br', output, 1
|
323
|
+
assert_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]/cite[text() = "Famous Poem"]', output, 1
|
324
|
+
attribution = xmlnodes_at_xpath '//*[@class = "verseblock"]/*[@class = "attribution"]', output, 1
|
325
|
+
author = attribution.children.last
|
326
|
+
assert_equal "#{expand_entity 8212} Famous Poet", author.text.strip
|
327
|
+
end
|
328
|
+
|
329
|
+
test 'multi-stanza verse block' do
|
330
|
+
input = <<-EOS
|
331
|
+
[verse]
|
332
|
+
____
|
333
|
+
A famous verse.
|
334
|
+
|
335
|
+
Stanza two.
|
336
|
+
____
|
337
|
+
EOS
|
338
|
+
output = render_string input
|
339
|
+
assert_xpath '//*[@class = "verseblock"]', output, 1
|
340
|
+
assert_xpath '//*[@class = "verseblock"]/pre', output, 1
|
341
|
+
assert_xpath '//*[@class = "verseblock"]//p', output, 0
|
342
|
+
assert_xpath '//*[@class = "verseblock"]/pre[contains(text(), "A famous verse.")]', output, 1
|
343
|
+
assert_xpath '//*[@class = "verseblock"]/pre[contains(text(), "Stanza two.")]', output, 1
|
344
|
+
end
|
345
|
+
|
346
|
+
test 'verse block does not contain block elements' do
|
347
|
+
input = <<-EOS
|
348
|
+
[verse]
|
349
|
+
____
|
350
|
+
A famous verse.
|
351
|
+
|
352
|
+
....
|
353
|
+
not a literal
|
354
|
+
....
|
355
|
+
____
|
356
|
+
EOS
|
357
|
+
output = render_string input
|
358
|
+
assert_css '.verseblock', output, 1
|
359
|
+
assert_css '.verseblock > pre', output, 1
|
360
|
+
assert_css '.verseblock p', output, 0
|
361
|
+
assert_css '.verseblock .literalblock', output, 0
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
120
366
|
context "Example Blocks" do
|
121
367
|
test "can render example block" do
|
122
368
|
input = <<-EOS
|
@@ -198,6 +444,20 @@ You just write.
|
|
198
444
|
assert !doc.attributes.has_key?('example-number')
|
199
445
|
end
|
200
446
|
|
447
|
+
test 'explicit caption is set on block even if block has no title' do
|
448
|
+
input = <<-EOS
|
449
|
+
[caption="Look!"]
|
450
|
+
====
|
451
|
+
Just write.
|
452
|
+
====
|
453
|
+
EOS
|
454
|
+
|
455
|
+
doc = document_from_string input
|
456
|
+
assert_equal 'Look!', doc.blocks.first.caption
|
457
|
+
output = doc.render
|
458
|
+
assert_no_match(/Look/, output)
|
459
|
+
end
|
460
|
+
|
201
461
|
test 'automatic caption can be turned off and on and modified' do
|
202
462
|
input = <<-EOS
|
203
463
|
.first example
|
@@ -400,6 +660,60 @@ source line 2\r
|
|
400
660
|
assert_xpath %(/*[@class="listingblock"]//pre/code[text()="source line 1\nsource line 2"]), output, 1
|
401
661
|
end
|
402
662
|
|
663
|
+
test 'should remove block indent if indent attribute is 0' do
|
664
|
+
input = <<-EOS
|
665
|
+
[indent="0"]
|
666
|
+
----
|
667
|
+
def names
|
668
|
+
|
669
|
+
@names.split ' '
|
670
|
+
|
671
|
+
end
|
672
|
+
----
|
673
|
+
EOS
|
674
|
+
|
675
|
+
expected = <<-EOS
|
676
|
+
def names
|
677
|
+
|
678
|
+
@names.split ' '
|
679
|
+
|
680
|
+
end
|
681
|
+
EOS
|
682
|
+
|
683
|
+
output = render_embedded_string input
|
684
|
+
assert_css 'pre', output, 1
|
685
|
+
assert_css '.listingblock pre', output, 1
|
686
|
+
result = xmlnodes_at_xpath('//pre', output, 1).text
|
687
|
+
assert_equal expected.chomp, result
|
688
|
+
end
|
689
|
+
|
690
|
+
test 'should set block indent to value specified by indent attribute' do
|
691
|
+
input = <<-EOS
|
692
|
+
[indent="1"]
|
693
|
+
----
|
694
|
+
def names
|
695
|
+
|
696
|
+
@names.split ' '
|
697
|
+
|
698
|
+
end
|
699
|
+
----
|
700
|
+
EOS
|
701
|
+
|
702
|
+
expected = <<-EOS
|
703
|
+
def names
|
704
|
+
|
705
|
+
@names.split ' '
|
706
|
+
|
707
|
+
end
|
708
|
+
EOS
|
709
|
+
|
710
|
+
output = render_embedded_string input
|
711
|
+
assert_css 'pre', output, 1
|
712
|
+
assert_css '.listingblock pre', output, 1
|
713
|
+
result = xmlnodes_at_xpath('//pre', output, 1).text
|
714
|
+
assert_equal expected.chomp, result
|
715
|
+
end
|
716
|
+
|
403
717
|
test 'literal block should honor explicit subs list' do
|
404
718
|
input = <<-EOS
|
405
719
|
[subs="verbatim,quotes"]
|
@@ -447,6 +761,58 @@ AssertionError
|
|
447
761
|
# so rstrip is necessary
|
448
762
|
assert_equal output.rstrip, output2.rstrip
|
449
763
|
end
|
764
|
+
|
765
|
+
test 'listing block without title should generate screen element in docbook' do
|
766
|
+
input = <<-EOS
|
767
|
+
----
|
768
|
+
listing block
|
769
|
+
----
|
770
|
+
EOS
|
771
|
+
|
772
|
+
output = render_embedded_string input, :backend => 'docbook'
|
773
|
+
assert_xpath '/screen[text()="listing block"]', output, 1
|
774
|
+
end
|
775
|
+
|
776
|
+
test 'listing block with title should generate screen element inside formalpara element in docbook' do
|
777
|
+
input = <<-EOS
|
778
|
+
.title
|
779
|
+
----
|
780
|
+
listing block
|
781
|
+
----
|
782
|
+
EOS
|
783
|
+
|
784
|
+
output = render_embedded_string input, :backend => 'docbook'
|
785
|
+
assert_xpath '/formalpara', output, 1
|
786
|
+
assert_xpath '/formalpara/title[text()="title"]', output, 1
|
787
|
+
assert_xpath '/formalpara/para/screen[text()="listing block"]', output, 1
|
788
|
+
end
|
789
|
+
|
790
|
+
test 'source block with no title or language should generate screen element in docbook' do
|
791
|
+
input = <<-EOS
|
792
|
+
[source]
|
793
|
+
----
|
794
|
+
listing block
|
795
|
+
----
|
796
|
+
EOS
|
797
|
+
|
798
|
+
output = render_embedded_string input, :backend => 'docbook'
|
799
|
+
assert_xpath '/screen[text()="listing block"]', output, 1
|
800
|
+
end
|
801
|
+
|
802
|
+
test 'source block with title and no language should generate screen element inside formalpara element in docbook' do
|
803
|
+
input = <<-EOS
|
804
|
+
[source]
|
805
|
+
.title
|
806
|
+
----
|
807
|
+
listing block
|
808
|
+
----
|
809
|
+
EOS
|
810
|
+
|
811
|
+
output = render_embedded_string input, :backend => 'docbook'
|
812
|
+
assert_xpath '/formalpara', output, 1
|
813
|
+
assert_xpath '/formalpara/title[text()="title"]', output, 1
|
814
|
+
assert_xpath '/formalpara/para/screen[text()="listing block"]', output, 1
|
815
|
+
end
|
450
816
|
end
|
451
817
|
|
452
818
|
context "Open Blocks" do
|
@@ -542,15 +908,25 @@ paragraph
|
|
542
908
|
assert_xpath '//*[@class="paragraph"]/p[text() = "paragraph"]', output, 1
|
543
909
|
end
|
544
910
|
|
545
|
-
test 'block title above document title
|
911
|
+
test 'block title above document title demotes document title to a section title' do
|
546
912
|
input = <<-EOS
|
547
913
|
.Block title
|
548
|
-
=
|
549
|
-
|
550
|
-
|
551
|
-
EOS
|
552
|
-
output =
|
553
|
-
|
914
|
+
= Section Title
|
915
|
+
|
916
|
+
section paragraph
|
917
|
+
EOS
|
918
|
+
output, errors = nil
|
919
|
+
redirect_streams do |stdout, stderr|
|
920
|
+
output = render_string input
|
921
|
+
errors = stdout.string
|
922
|
+
end
|
923
|
+
assert_xpath '//*[@id="header"]/*', output, 0
|
924
|
+
assert_xpath '//*[@id="preamble"]/*', output, 0
|
925
|
+
assert_xpath '//*[@id="content"]/h1[text()="Section Title"]', output, 1
|
926
|
+
assert_xpath '//*[@class="paragraph"]', output, 1
|
927
|
+
assert_xpath '//*[@class="paragraph"]/*[@class="title"][text()="Block title"]', output, 1
|
928
|
+
assert !errors.empty?
|
929
|
+
assert_match(/only book doctypes can contain level 0 sections/, errors)
|
554
930
|
end
|
555
931
|
|
556
932
|
test 'block title above document title gets carried over to first block in first section if no preamble' do
|
@@ -959,6 +1335,18 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
959
1335
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'docdir' => File.dirname(__FILE__)}
|
960
1336
|
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
961
1337
|
end
|
1338
|
+
|
1339
|
+
test 'can use font-based icons' do
|
1340
|
+
input = <<-EOS
|
1341
|
+
:icons: font
|
1342
|
+
|
1343
|
+
[TIP]
|
1344
|
+
You can use icons for admonitions by setting the 'icons' attribute.
|
1345
|
+
EOS
|
1346
|
+
|
1347
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1348
|
+
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="icon-tip"]', output, 1
|
1349
|
+
end
|
962
1350
|
end
|
963
1351
|
|
964
1352
|
context 'Image paths' do
|
@@ -1050,7 +1438,7 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
|
1050
1438
|
----
|
1051
1439
|
EOS
|
1052
1440
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1053
|
-
assert_xpath '//pre[@class="
|
1441
|
+
assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
1054
1442
|
assert_match(/\.CodeRay \{/, output)
|
1055
1443
|
end
|
1056
1444
|
|
@@ -1067,7 +1455,7 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
|
1067
1455
|
----
|
1068
1456
|
EOS
|
1069
1457
|
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1070
|
-
assert_xpath '//pre[@class="
|
1458
|
+
assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@style = "color:#036;font-weight:bold"][text() = "CodeRay"]', output, 1
|
1071
1459
|
assert_no_match(/\.CodeRay \{/, output)
|
1072
1460
|
end
|
1073
1461
|
|
@@ -1097,4 +1485,267 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
|
1097
1485
|
end
|
1098
1486
|
end
|
1099
1487
|
|
1488
|
+
context 'Abstract and Part Intro' do
|
1489
|
+
test 'should make abstract on open block without title a quote block for article' do
|
1490
|
+
input = <<-EOS
|
1491
|
+
= Article
|
1492
|
+
|
1493
|
+
[abstract]
|
1494
|
+
--
|
1495
|
+
This article is about stuff.
|
1496
|
+
|
1497
|
+
And other stuff.
|
1498
|
+
--
|
1499
|
+
EOS
|
1500
|
+
|
1501
|
+
output = render_string input
|
1502
|
+
assert_css '.quoteblock', output, 1
|
1503
|
+
assert_css '.quoteblock.abstract', output, 1
|
1504
|
+
assert_css '#preamble .quoteblock', output, 1
|
1505
|
+
assert_css '.quoteblock > blockquote', output, 1
|
1506
|
+
assert_css '.quoteblock > blockquote > .paragraph', output, 2
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
test 'should make abstract on open block with title a quote block with title for article' do
|
1510
|
+
input = <<-EOS
|
1511
|
+
= Article
|
1512
|
+
|
1513
|
+
.My abstract
|
1514
|
+
[abstract]
|
1515
|
+
--
|
1516
|
+
This article is about stuff.
|
1517
|
+
--
|
1518
|
+
EOS
|
1519
|
+
|
1520
|
+
output = render_string input
|
1521
|
+
assert_css '.quoteblock', output, 1
|
1522
|
+
assert_css '.quoteblock.abstract', output, 1
|
1523
|
+
assert_css '#preamble .quoteblock', output, 1
|
1524
|
+
assert_css '.quoteblock > .title', output, 1
|
1525
|
+
assert_css '.quoteblock > .title + blockquote', output, 1
|
1526
|
+
assert_css '.quoteblock > .title + blockquote > .paragraph', output, 1
|
1527
|
+
end
|
1528
|
+
|
1529
|
+
test 'should allow abstract in document with title if doctype is book' do
|
1530
|
+
input = <<-EOS
|
1531
|
+
= Book
|
1532
|
+
:doctype: book
|
1533
|
+
|
1534
|
+
[abstract]
|
1535
|
+
Abstract for book with title is valid
|
1536
|
+
EOS
|
1537
|
+
|
1538
|
+
output = render_string input
|
1539
|
+
assert_css '.abstract', output, 1
|
1540
|
+
end
|
1541
|
+
|
1542
|
+
test 'should not allow abstract as direct child of document if doctype is book' do
|
1543
|
+
input = <<-EOS
|
1544
|
+
:doctype: book
|
1545
|
+
|
1546
|
+
[abstract]
|
1547
|
+
Abstract for book without title is invalid.
|
1548
|
+
EOS
|
1549
|
+
|
1550
|
+
output = render_string input
|
1551
|
+
assert_css '.abstract', output, 0
|
1552
|
+
end
|
1553
|
+
|
1554
|
+
test 'should make abstract on open block without title rendered to DocBook' do
|
1555
|
+
input = <<-EOS
|
1556
|
+
= Article
|
1557
|
+
|
1558
|
+
[abstract]
|
1559
|
+
--
|
1560
|
+
This article is about stuff.
|
1561
|
+
|
1562
|
+
And other stuff.
|
1563
|
+
--
|
1564
|
+
EOS
|
1565
|
+
|
1566
|
+
output = render_string input, :backend => 'docbook'
|
1567
|
+
assert_css 'abstract', output, 1
|
1568
|
+
assert_css 'abstract > simpara', output, 2
|
1569
|
+
end
|
1570
|
+
|
1571
|
+
test 'should make abstract on open block with title rendered to DocBook' do
|
1572
|
+
input = <<-EOS
|
1573
|
+
= Article
|
1574
|
+
|
1575
|
+
.My abstract
|
1576
|
+
[abstract]
|
1577
|
+
--
|
1578
|
+
This article is about stuff.
|
1579
|
+
--
|
1580
|
+
EOS
|
1581
|
+
|
1582
|
+
output = render_string input, :backend => 'docbook'
|
1583
|
+
assert_css 'abstract', output, 1
|
1584
|
+
assert_css 'abstract > title', output, 1
|
1585
|
+
assert_css 'abstract > title + simpara', output, 1
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
test 'should allow abstract in document with title if doctype is book rendered to DocBook' do
|
1589
|
+
input = <<-EOS
|
1590
|
+
= Book
|
1591
|
+
:doctype: book
|
1592
|
+
|
1593
|
+
[abstract]
|
1594
|
+
Abstract for book with title is valid
|
1595
|
+
EOS
|
1596
|
+
|
1597
|
+
output = render_string input, :backend => 'docbook'
|
1598
|
+
assert_css 'abstract', output, 1
|
1599
|
+
end
|
1600
|
+
|
1601
|
+
test 'should not allow abstract as direct child of document if doctype is book rendered to DocBook' do
|
1602
|
+
input = <<-EOS
|
1603
|
+
:doctype: book
|
1604
|
+
|
1605
|
+
[abstract]
|
1606
|
+
Abstract for book is invalid.
|
1607
|
+
EOS
|
1608
|
+
|
1609
|
+
output = render_string input, :backend => 'docbook'
|
1610
|
+
assert_css 'abstract', output, 0
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
# TODO partintro shouldn't be recognized if doctype is not book, should be in proper place
|
1614
|
+
test 'should accept partintro on open block without title' do
|
1615
|
+
input = <<-EOS
|
1616
|
+
= Book
|
1617
|
+
:doctype: book
|
1618
|
+
|
1619
|
+
= Part 1
|
1620
|
+
|
1621
|
+
[partintro]
|
1622
|
+
--
|
1623
|
+
This is a part intro.
|
1624
|
+
|
1625
|
+
It can have multiple paragraphs.
|
1626
|
+
--
|
1627
|
+
EOS
|
1628
|
+
|
1629
|
+
output = render_string input
|
1630
|
+
assert_css '.openblock', output, 1
|
1631
|
+
assert_css '.openblock.partintro', output, 1
|
1632
|
+
assert_css '.openblock .title', output, 0
|
1633
|
+
assert_css '.openblock .content', output, 1
|
1634
|
+
assert_xpath %(//h1[@id="_part_1"]/following-sibling::*[#{contains_class(:openblock)}]), output, 1
|
1635
|
+
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="content"]/*[@class="paragraph"]), output, 2
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
test 'should accept partintro on open block with title' do
|
1639
|
+
input = <<-EOS
|
1640
|
+
= Book
|
1641
|
+
:doctype: book
|
1642
|
+
|
1643
|
+
= Part 1
|
1644
|
+
|
1645
|
+
.Intro title
|
1646
|
+
[partintro]
|
1647
|
+
--
|
1648
|
+
This is a part intro with a title.
|
1649
|
+
--
|
1650
|
+
EOS
|
1651
|
+
|
1652
|
+
output = render_string input
|
1653
|
+
assert_css '.openblock', output, 1
|
1654
|
+
assert_css '.openblock.partintro', output, 1
|
1655
|
+
assert_css '.openblock .title', output, 1
|
1656
|
+
assert_css '.openblock .content', output, 1
|
1657
|
+
assert_xpath %(//h1[@id="_part_1"]/following-sibling::*[#{contains_class(:openblock)}]), output, 1
|
1658
|
+
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="title"][text() = "Intro title"]), output, 1
|
1659
|
+
assert_xpath %(//*[#{contains_class(:openblock)}]/*[@class="content"]/*[@class="paragraph"]), output, 1
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
test 'should exclude partintro if not a child of part' do
|
1663
|
+
input = <<-EOS
|
1664
|
+
= Book
|
1665
|
+
:doctype: book
|
1666
|
+
|
1667
|
+
[partintro]
|
1668
|
+
part intro paragraph
|
1669
|
+
EOS
|
1670
|
+
|
1671
|
+
output = render_string input
|
1672
|
+
assert_css '.partintro', output, 0
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
test 'should not allow partintro unless doctype is book' do
|
1676
|
+
input = <<-EOS
|
1677
|
+
[partintro]
|
1678
|
+
part intro paragraph
|
1679
|
+
EOS
|
1680
|
+
|
1681
|
+
output = render_string input
|
1682
|
+
assert_css '.partintro', output, 0
|
1683
|
+
end
|
1684
|
+
|
1685
|
+
test 'should accept partintro on open block without title rendered to DocBook' do
|
1686
|
+
input = <<-EOS
|
1687
|
+
= Book
|
1688
|
+
:doctype: book
|
1689
|
+
|
1690
|
+
= Part 1
|
1691
|
+
|
1692
|
+
[partintro]
|
1693
|
+
--
|
1694
|
+
This is a part intro.
|
1695
|
+
|
1696
|
+
It can have multiple paragraphs.
|
1697
|
+
--
|
1698
|
+
EOS
|
1699
|
+
|
1700
|
+
output = render_string input, :backend => 'docbook'
|
1701
|
+
assert_css 'partintro', output, 1
|
1702
|
+
assert_css 'part#_part_1 > partintro', output, 1
|
1703
|
+
assert_css 'partintro > simpara', output, 2
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
test 'should accept partintro on open block with title rendered to DocBook' do
|
1707
|
+
input = <<-EOS
|
1708
|
+
= Book
|
1709
|
+
:doctype: book
|
1710
|
+
|
1711
|
+
= Part 1
|
1712
|
+
|
1713
|
+
.Intro title
|
1714
|
+
[partintro]
|
1715
|
+
--
|
1716
|
+
This is a part intro with a title.
|
1717
|
+
--
|
1718
|
+
EOS
|
1719
|
+
|
1720
|
+
output = render_string input, :backend => 'docbook'
|
1721
|
+
assert_css 'partintro', output, 1
|
1722
|
+
assert_css 'part#_part_1 > partintro', output, 1
|
1723
|
+
assert_css 'partintro > title', output, 1
|
1724
|
+
assert_css 'partintro > title + simpara', output, 1
|
1725
|
+
end
|
1726
|
+
|
1727
|
+
test 'should exclude partintro if not a child of part rendered to DocBook' do
|
1728
|
+
input = <<-EOS
|
1729
|
+
= Book
|
1730
|
+
:doctype: book
|
1731
|
+
|
1732
|
+
[partintro]
|
1733
|
+
part intro paragraph
|
1734
|
+
EOS
|
1735
|
+
|
1736
|
+
output = render_string input, :backend => 'docbook'
|
1737
|
+
assert_css 'partintro', output, 0
|
1738
|
+
end
|
1739
|
+
|
1740
|
+
test 'should not allow partintro unless doctype is book rendered to DocBook' do
|
1741
|
+
input = <<-EOS
|
1742
|
+
[partintro]
|
1743
|
+
part intro paragraph
|
1744
|
+
EOS
|
1745
|
+
|
1746
|
+
output = render_string input, :backend => 'docbook'
|
1747
|
+
assert_css 'partintro', output, 0
|
1748
|
+
end
|
1749
|
+
end
|
1750
|
+
|
1100
1751
|
end
|