asciidoctor 1.5.5 → 1.5.6
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/CHANGELOG.adoc +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
data/lib/asciidoctor/table.rb
CHANGED
@@ -14,50 +14,20 @@ class Table < AbstractBlock
|
|
14
14
|
@body = body
|
15
15
|
end
|
16
16
|
|
17
|
-
alias
|
17
|
+
alias [] send
|
18
|
+
|
19
|
+
# Public: Returns the rows grouped by section.
|
20
|
+
#
|
21
|
+
# Creates a 2-dimensional array of two element entries. The first element
|
22
|
+
# is the section name as a symbol. The second element is the Array of rows
|
23
|
+
# in that section. The entries are in document order (head, foot, body).
|
24
|
+
#
|
25
|
+
# Returns a 2-dimentional Array of rows grouped by section.
|
26
|
+
def by_section
|
27
|
+
[[:head, @head], [:foot, @foot], [:body, @body]]
|
28
|
+
end
|
18
29
|
end
|
19
30
|
|
20
|
-
# Public: A String key that specifies the default table format in AsciiDoc (psv)
|
21
|
-
DEFAULT_DATA_FORMAT = 'psv'
|
22
|
-
|
23
|
-
# Public: An Array of String keys that represent the table formats in AsciiDoc
|
24
|
-
DATA_FORMATS = ['psv', 'dsv', 'csv']
|
25
|
-
|
26
|
-
# Public: A Hash mapping the AsciiDoc table formats to their default delimiters
|
27
|
-
DEFAULT_DELIMITERS = {
|
28
|
-
'psv' => '|',
|
29
|
-
'dsv' => ':',
|
30
|
-
'csv' => ','
|
31
|
-
}
|
32
|
-
|
33
|
-
# Public: A Hash mapping styles abbreviations to styles that can be applied
|
34
|
-
# to a table column or cell
|
35
|
-
TEXT_STYLES = {
|
36
|
-
'd' => :none,
|
37
|
-
's' => :strong,
|
38
|
-
'e' => :emphasis,
|
39
|
-
'm' => :monospaced,
|
40
|
-
'h' => :header,
|
41
|
-
'l' => :literal,
|
42
|
-
'v' => :verse,
|
43
|
-
'a' => :asciidoc
|
44
|
-
}
|
45
|
-
|
46
|
-
# Public: A Hash mapping alignment abbreviations to alignments (horizontal
|
47
|
-
# and vertial) that can be applies to a table column or cell
|
48
|
-
ALIGNMENTS = {
|
49
|
-
:h => {
|
50
|
-
'<' => 'left',
|
51
|
-
'>' => 'right',
|
52
|
-
'^' => 'center'
|
53
|
-
},
|
54
|
-
:v => {
|
55
|
-
'<' => 'top',
|
56
|
-
'>' => 'bottom',
|
57
|
-
'^' => 'middle'
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
31
|
# Public: Get/Set the columns for this table
|
62
32
|
attr_accessor :columns
|
63
33
|
|
@@ -68,6 +38,9 @@ class Table < AbstractBlock
|
|
68
38
|
# Public: Boolean specifies whether this table has a header row
|
69
39
|
attr_accessor :has_header_option
|
70
40
|
|
41
|
+
# Public: Get the caption for this table
|
42
|
+
attr_reader :caption
|
43
|
+
|
71
44
|
def initialize parent, attributes
|
72
45
|
super parent, :table
|
73
46
|
@rows = Rows.new
|
@@ -87,6 +60,7 @@ class Table < AbstractBlock
|
|
87
60
|
@attributes['tablepcwidth'] = pcwidth_intval
|
88
61
|
|
89
62
|
if @document.attributes.key? 'pagewidth'
|
63
|
+
# FIXME calculate more accurately (only used in DocBook output)
|
90
64
|
@attributes['tableabswidth'] ||=
|
91
65
|
((@attributes['tablepcwidth'].to_f / 100) * @document.attributes['pagewidth']).round
|
92
66
|
end
|
@@ -135,12 +109,22 @@ class Table < AbstractBlock
|
|
135
109
|
@columns.each {|col| total_width += (col_pcwidth = col.assign_width nil, width_base, pf) }
|
136
110
|
else
|
137
111
|
col_pcwidth = ((100 * pf / @columns.size).to_i) / pf
|
112
|
+
# or...
|
113
|
+
#col_pcwidth = (100.0 / @columns.size).truncate 4
|
138
114
|
col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
|
139
115
|
@columns.each {|col| total_width += col.assign_width col_pcwidth }
|
140
116
|
end
|
141
117
|
|
142
|
-
# donate balance, if any, to final column
|
143
|
-
|
118
|
+
# donate balance, if any, to final column (using half up rounding)
|
119
|
+
unless total_width == 100
|
120
|
+
@columns[-1].assign_width(((100 - total_width + col_pcwidth) * pf).round / pf)
|
121
|
+
# or (manual half up rounding)...
|
122
|
+
#numerator = (raw_numerator = (100 - total_width + col_pcwidth) * pf).to_i
|
123
|
+
#numerator += 1 if raw_numerator >= numerator + 0.5
|
124
|
+
#@columns[-1].assign_width numerator / pf
|
125
|
+
# or...
|
126
|
+
#@columns[-1].assign_width((100 - total_width + col_pcwidth).round 4)
|
127
|
+
end
|
144
128
|
|
145
129
|
nil
|
146
130
|
end
|
@@ -149,7 +133,7 @@ class Table < AbstractBlock
|
|
149
133
|
# by the options on the table
|
150
134
|
#
|
151
135
|
# returns nothing
|
152
|
-
def partition_header_footer(
|
136
|
+
def partition_header_footer(attrs)
|
153
137
|
# set rowcount before splitting up body rows
|
154
138
|
@attributes['rowcount'] = @rows.body.size
|
155
139
|
|
@@ -164,7 +148,7 @@ class Table < AbstractBlock
|
|
164
148
|
@rows.head = [head]
|
165
149
|
end
|
166
150
|
|
167
|
-
if num_body_rows > 0 &&
|
151
|
+
if num_body_rows > 0 && attrs.key?('footer-option')
|
168
152
|
@rows.foot = [@rows.body.pop]
|
169
153
|
end
|
170
154
|
|
@@ -189,7 +173,7 @@ class Table::Column < AbstractNode
|
|
189
173
|
end
|
190
174
|
|
191
175
|
# Public: An alias to the parent block (which is always a Table)
|
192
|
-
alias
|
176
|
+
alias table parent
|
193
177
|
|
194
178
|
# Internal: Calculate and assign the widths (percentage and absolute) for this column
|
195
179
|
#
|
@@ -199,6 +183,8 @@ class Table::Column < AbstractNode
|
|
199
183
|
def assign_width col_pcwidth, width_base = nil, pf = 10000.0
|
200
184
|
if width_base
|
201
185
|
col_pcwidth = ((@attributes['width'].to_f / width_base) * 100 * pf).to_i / pf
|
186
|
+
# or...
|
187
|
+
#col_pcwidth = (@attributes['width'].to_f * 100.0 / width_base).truncate 4
|
202
188
|
col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
|
203
189
|
end
|
204
190
|
@attributes['colpcwidth'] = col_pcwidth
|
@@ -222,58 +208,90 @@ class Table::Cell < AbstractNode
|
|
222
208
|
attr_accessor :rowspan
|
223
209
|
|
224
210
|
# Public: An alias to the parent block (which is always a Column)
|
225
|
-
alias
|
211
|
+
alias column parent
|
226
212
|
|
227
213
|
# Public: The internal Asciidoctor::Document for a cell that has the asciidoc style
|
228
214
|
attr_reader :inner_document
|
229
215
|
|
230
|
-
def initialize column,
|
216
|
+
def initialize column, cell_text, attributes = {}, opts = {}
|
231
217
|
super column, :cell
|
232
|
-
@text = text
|
233
|
-
@style = nil
|
234
|
-
@colspan = nil
|
235
|
-
@rowspan = nil
|
236
|
-
# TODO feels hacky
|
237
218
|
if column
|
238
|
-
|
239
|
-
|
219
|
+
cell_style = (in_header_row = column.table.header_row?) ? nil : column.attributes['style']
|
220
|
+
# REVIEW feels hacky to inherit all attributes from column
|
221
|
+
update_attributes column.attributes
|
222
|
+
else
|
223
|
+
in_header_row = cell_style = nil
|
240
224
|
end
|
241
225
|
if attributes
|
242
|
-
@colspan = attributes.delete
|
243
|
-
@rowspan = attributes.delete
|
244
|
-
# TODO
|
245
|
-
|
246
|
-
|
247
|
-
|
226
|
+
@colspan = attributes.delete 'colspan'
|
227
|
+
@rowspan = attributes.delete 'rowspan'
|
228
|
+
# TODO eventually remove the style attribute from the attributes hash
|
229
|
+
#cell_style = attributes.delete 'style' unless in_header_row || !(attributes.key? 'style')
|
230
|
+
cell_style = attributes['style'] unless in_header_row || !(attributes.key? 'style')
|
231
|
+
if opts[:strip_text]
|
232
|
+
if cell_style == :literal || cell_style == :verse
|
233
|
+
cell_text = cell_text.rstrip
|
234
|
+
cell_text = cell_text.slice 1, cell_text.length - 1 while cell_text.start_with? LF
|
235
|
+
else
|
236
|
+
cell_text = cell_text.strip
|
237
|
+
end
|
238
|
+
end
|
239
|
+
update_attributes attributes
|
240
|
+
else
|
241
|
+
@colspan = nil
|
242
|
+
@rowspan = nil
|
248
243
|
end
|
249
|
-
# only
|
250
|
-
if
|
244
|
+
# NOTE only true for non-header rows
|
245
|
+
if cell_style == :asciidoc
|
251
246
|
# FIXME hide doctitle from nested document; temporary workaround to fix
|
252
247
|
# nested document seeing doctitle and assuming it has its own document title
|
253
248
|
parent_doctitle = @document.attributes.delete('doctitle')
|
254
249
|
# NOTE we need to process the first line of content as it may not have been processed
|
255
250
|
# the included content cannot expect to match conditional terminators in the remaining
|
256
251
|
# lines of table cell content, it must be self-contained logic
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
252
|
+
# QUESTION should we reset cell_text to nil?
|
253
|
+
# QUESTION is is faster to check for :: before splitting?
|
254
|
+
inner_document_lines = cell_text.split LF, -1
|
255
|
+
if (unprocessed_line1 = inner_document_lines[0]).include? '::'
|
256
|
+
preprocessed_lines = (PreprocessorReader.new @document, [unprocessed_line1]).readlines
|
257
|
+
unless unprocessed_line1 == preprocessed_lines[0] && preprocessed_lines.size < 2
|
262
258
|
inner_document_lines.shift
|
263
|
-
inner_document_lines.unshift(*
|
259
|
+
inner_document_lines.unshift(*preprocessed_lines) unless preprocessed_lines.empty?
|
264
260
|
end
|
265
|
-
end
|
266
|
-
@inner_document = Document.new(inner_document_lines, :header_footer => false, :parent => @document, :cursor => cursor)
|
261
|
+
end unless inner_document_lines.empty?
|
262
|
+
@inner_document = Document.new(inner_document_lines, :header_footer => false, :parent => @document, :cursor => opts[:cursor])
|
267
263
|
@document.attributes['doctitle'] = parent_doctitle unless parent_doctitle.nil?
|
268
264
|
end
|
265
|
+
@text = cell_text
|
266
|
+
@style = cell_style
|
269
267
|
end
|
270
268
|
|
271
|
-
# Public: Get the text
|
269
|
+
# Public: Get the String text of this cell with substitutions applied.
|
270
|
+
#
|
271
|
+
# Used for cells in the head row as well as text-only (non-AsciiDoc) cells in
|
272
|
+
# the foot row and body.
|
273
|
+
#
|
274
|
+
# This method shouldn't be used for cells that have the AsciiDoc style.
|
275
|
+
#
|
276
|
+
# Returns the converted String text for this Cell
|
272
277
|
def text
|
273
|
-
|
278
|
+
apply_subs @text, (@style == :literal ? BASIC_SUBS : NORMAL_SUBS)
|
279
|
+
end
|
280
|
+
|
281
|
+
# Public: Set the String text.
|
282
|
+
#
|
283
|
+
# This method shouldn't be used for cells that have the AsciiDoc style.
|
284
|
+
#
|
285
|
+
# Returns the new String text assigned to this Cell
|
286
|
+
def text= val
|
287
|
+
@text = val
|
274
288
|
end
|
275
289
|
|
276
290
|
# Public: Handles the body data (tbody, tfoot), applying styles and partitioning into paragraphs
|
291
|
+
#
|
292
|
+
# This method should not be used for cells in the head row or that have the literal or verse style.
|
293
|
+
#
|
294
|
+
# Returns the converted String for this Cell
|
277
295
|
def content
|
278
296
|
if @style == :asciidoc
|
279
297
|
@inner_document.convert
|
@@ -296,11 +314,24 @@ end
|
|
296
314
|
# instantiated, the row is closed if the cell satisifies the column count and,
|
297
315
|
# finally, a new buffer is allocated to track the next cell.
|
298
316
|
class Table::ParserContext
|
317
|
+
# Public: An Array of String keys that represent the table formats in AsciiDoc
|
318
|
+
#--
|
319
|
+
# QUESTION should we recognize !sv as a valid format value?
|
320
|
+
FORMATS = ['psv', 'csv', 'dsv', 'tsv'].to_set
|
321
|
+
|
322
|
+
# Public: A Hash mapping the AsciiDoc table formats to default delimiters
|
323
|
+
DELIMITERS = {
|
324
|
+
'psv' => ['|', /\|/],
|
325
|
+
'csv' => [',', /,/],
|
326
|
+
'dsv' => [':', /:/],
|
327
|
+
'tsv' => [%(\t), /\t/],
|
328
|
+
'!sv' => ['!', /!/]
|
329
|
+
}
|
299
330
|
|
300
331
|
# Public: The Table currently being parsed
|
301
332
|
attr_accessor :table
|
302
333
|
|
303
|
-
# Public: The AsciiDoc table format (psv, dsv or csv)
|
334
|
+
# Public: The AsciiDoc table format (psv, dsv, or csv)
|
304
335
|
attr_accessor :format
|
305
336
|
|
306
337
|
# Public: Get the expected column count for a row
|
@@ -319,25 +350,41 @@ class Table::ParserContext
|
|
319
350
|
# Public: The cell delimiter compiled Regexp for this table.
|
320
351
|
attr_reader :delimiter_re
|
321
352
|
|
322
|
-
def initialize
|
353
|
+
def initialize reader, table, attributes = {}
|
323
354
|
@reader = reader
|
324
355
|
@table = table
|
325
|
-
#
|
356
|
+
# IMPORTANT if reader.cursor becomes a reference, this assignment would require .dup
|
326
357
|
@last_cursor = reader.cursor
|
327
|
-
|
328
|
-
|
329
|
-
|
358
|
+
|
359
|
+
if attributes.key? 'format'
|
360
|
+
if FORMATS.include?(xsv = attributes['format'])
|
361
|
+
if xsv == 'tsv'
|
362
|
+
# NOTE tsv is just an alias for csv with a tab separator
|
363
|
+
@format = 'csv'
|
364
|
+
elsif (@format = xsv) == 'psv' && table.document.nested?
|
365
|
+
xsv = '!sv'
|
366
|
+
end
|
367
|
+
else
|
368
|
+
warn %(asciidoctor: ERROR: #{reader.prev_line_info}: illegal table format: #{xsv})
|
369
|
+
@format, xsv = 'psv', (table.document.nested? ? '!sv' : 'psv')
|
330
370
|
end
|
331
371
|
else
|
332
|
-
@format =
|
372
|
+
@format, xsv = 'psv', (table.document.nested? ? '!sv' : 'psv')
|
333
373
|
end
|
334
374
|
|
335
|
-
|
336
|
-
'
|
375
|
+
if attributes.key? 'separator'
|
376
|
+
if (sep = attributes['separator']).nil_or_empty?
|
377
|
+
@delimiter, @delimiter_re = DELIMITERS[xsv]
|
378
|
+
# QUESTION should we support any other escape codes or multiple tabs?
|
379
|
+
elsif sep == '\t'
|
380
|
+
@delimiter, @delimiter_re = DELIMITERS['tsv']
|
381
|
+
else
|
382
|
+
@delimiter, @delimiter_re = sep, /#{::Regexp.escape sep}/
|
383
|
+
end
|
337
384
|
else
|
338
|
-
|
385
|
+
@delimiter, @delimiter_re = DELIMITERS[xsv]
|
339
386
|
end
|
340
|
-
|
387
|
+
|
341
388
|
@colcount = table.columns.empty? ? -1 : table.columns.size
|
342
389
|
@buffer = ''
|
343
390
|
@cellspecs = []
|
@@ -364,31 +411,36 @@ class Table::ParserContext
|
|
364
411
|
@delimiter_re.match(line)
|
365
412
|
end
|
366
413
|
|
367
|
-
# Public: Skip
|
368
|
-
# (either because it was escaped or in a quoted context)
|
414
|
+
# Public: Skip past the matched delimiter because it's inside quoted text.
|
369
415
|
#
|
370
416
|
# returns the String after the match
|
371
|
-
def
|
372
|
-
@buffer = %(#{@buffer}#{
|
417
|
+
def skip_past_delimiter(match)
|
418
|
+
@buffer = %(#{@buffer}#{match.pre_match}#{@delimiter})
|
373
419
|
match.post_match
|
374
420
|
end
|
375
421
|
|
376
|
-
# Public:
|
422
|
+
# Public: Skip past the matched delimiter because it's escaped.
|
377
423
|
#
|
378
|
-
# returns
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
record.start_with?('"') && !record.start_with?('""') && !record.end_with?('"')
|
424
|
+
# returns the String after the match
|
425
|
+
def skip_past_escaped_delimiter(match)
|
426
|
+
@buffer = %(#{@buffer}#{match.pre_match.chop}#{@delimiter})
|
427
|
+
match.post_match
|
383
428
|
end
|
384
429
|
|
385
|
-
# Public: Determines whether the buffer
|
430
|
+
# Public: Determines whether the buffer has unclosed quotes. Used for CSV data.
|
386
431
|
#
|
387
|
-
# returns true if the buffer
|
388
|
-
#
|
389
|
-
def
|
390
|
-
|
391
|
-
|
432
|
+
# returns true if the buffer has unclosed quotes, false if it doesn't or it
|
433
|
+
# isn't quoted data
|
434
|
+
def buffer_has_unclosed_quotes? append = nil
|
435
|
+
if (record = append ? (buffer + append).strip : buffer.strip).start_with? '"'
|
436
|
+
if ((trailing_quote = record.end_with? '"') && (record.end_with? '""')) || (record.start_with? '""')
|
437
|
+
((record = record.gsub '""', '').start_with? '"') && !(record.end_with? '"')
|
438
|
+
else
|
439
|
+
!trailing_quote
|
440
|
+
end
|
441
|
+
else
|
442
|
+
false
|
443
|
+
end
|
392
444
|
end
|
393
445
|
|
394
446
|
# Public: Takes a cell spec from the stack. Cell specs precede the delimiter, so a
|
@@ -460,11 +512,11 @@ class Table::ParserContext
|
|
460
512
|
#
|
461
513
|
# returns nothing
|
462
514
|
def close_cell(eol = false)
|
463
|
-
cell_text = @buffer.strip
|
464
|
-
@buffer = ''
|
465
515
|
if @format == 'psv'
|
466
|
-
|
467
|
-
|
516
|
+
strip_text = true
|
517
|
+
cell_text = @buffer
|
518
|
+
@buffer = ''
|
519
|
+
if (cellspec = take_cellspec)
|
468
520
|
repeat = cellspec.delete('repeatcol') || 1
|
469
521
|
else
|
470
522
|
warn %(asciidoctor: ERROR: #{@last_cursor.line_info}: table missing leading separator, recovering automatically)
|
@@ -472,6 +524,9 @@ class Table::ParserContext
|
|
472
524
|
repeat = 1
|
473
525
|
end
|
474
526
|
else
|
527
|
+
strip_text = false
|
528
|
+
cell_text = @buffer.strip
|
529
|
+
@buffer = ''
|
475
530
|
cellspec = nil
|
476
531
|
repeat = 1
|
477
532
|
if @format == 'csv'
|
@@ -482,8 +537,8 @@ class Table::ParserContext
|
|
482
537
|
cell_text = cell_text[1...-1].strip
|
483
538
|
end
|
484
539
|
|
485
|
-
#
|
486
|
-
cell_text = cell_text.
|
540
|
+
# collapse escaped quotes
|
541
|
+
cell_text = cell_text.squeeze('"')
|
487
542
|
end
|
488
543
|
end
|
489
544
|
end
|
@@ -506,7 +561,7 @@ class Table::ParserContext
|
|
506
561
|
end
|
507
562
|
end
|
508
563
|
|
509
|
-
cell = Table::Cell.new(column, cell_text, cellspec, @last_cursor)
|
564
|
+
cell = Table::Cell.new(column, cell_text, cellspec, :cursor => @last_cursor, :strip_text => strip_text)
|
510
565
|
@last_cursor = @reader.cursor
|
511
566
|
unless !cell.rowspan || cell.rowspan == 1
|
512
567
|
activate_rowspan(cell.rowspan, (cell.colspan || 1))
|
data/lib/asciidoctor/version.rb
CHANGED
data/man/asciidoctor.1
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
'\" t
|
2
2
|
.\" Title: asciidoctor
|
3
3
|
.\" Author: Dan Allen, Sarah White, Ryan Waldron
|
4
|
-
.\" Generator: Asciidoctor 1.5.
|
5
|
-
.\" Date:
|
4
|
+
.\" Generator: Asciidoctor 1.5.6
|
5
|
+
.\" Date: 2017-07-12
|
6
6
|
.\" Manual: Asciidoctor Manual
|
7
|
-
.\" Source: Asciidoctor 1.5.
|
7
|
+
.\" Source: Asciidoctor 1.5.6
|
8
8
|
.\" Language: English
|
9
9
|
.\"
|
10
|
-
.TH "ASCIIDOCTOR" "1" "
|
10
|
+
.TH "ASCIIDOCTOR" "1" "2017-07-12" "Asciidoctor 1.5.6" "Asciidoctor Manual"
|
11
11
|
.ie \n(.g .ds Aq \(aq
|
12
12
|
.el .ds Aq '
|
13
13
|
.ss \n[.ss] 0
|
@@ -35,7 +35,7 @@ If \fIFILE\fP is \fI\-\fP then the AsciiDoc source is read from standard input.
|
|
35
35
|
.RS 4
|
36
36
|
Base directory containing the document and resources.
|
37
37
|
Defaults to the directory containing the source file, or the working directory if the source is read from a stream.
|
38
|
-
|
38
|
+
When combined with the safe mode setting, can be used to chroot the execution of the program.
|
39
39
|
.RE
|
40
40
|
.sp
|
41
41
|
\fB\-S, \-\-safe\-mode\fP=\fISAFE_MODE\fP
|
@@ -48,7 +48,7 @@ If not set, the safe mode level defaults to \fIunsafe\fP when Asciidoctor is inv
|
|
48
48
|
\fB\-\-safe\fP
|
49
49
|
.RS 4
|
50
50
|
Set safe mode level to \fIsafe\fP.
|
51
|
-
Enables include
|
51
|
+
Enables include directives, but prevents access to ancestor paths of source file.
|
52
52
|
Provided for compatibility with the asciidoc command.
|
53
53
|
If not set, the safe mode level defaults to \fIunsafe\fP when Asciidoctor is invoked using this script.
|
54
54
|
.RE
|
@@ -57,7 +57,7 @@ If not set, the safe mode level defaults to \fIunsafe\fP when Asciidoctor is inv
|
|
57
57
|
\fB\-a, \-\-attribute\fP=\fIATTRIBUTE\fP
|
58
58
|
.RS 4
|
59
59
|
Define, override or delete a document attribute.
|
60
|
-
Command\-line attributes take precedence over attributes defined in the source file.
|
60
|
+
Command\-line attributes take precedence over attributes defined in the source file unless the value ends with \fI@\fP.
|
61
61
|
.sp
|
62
62
|
\fIATTRIBUTE\fP is normally formatted as a key\-value pair, in the form \fINAME=VALUE\fP.
|
63
63
|
Alternate acceptable forms are \fINAME\fP (where the \fIVALUE\fP defaults to an empty string), \fINAME!\fP (unassigns the \fINAME\fP attribute) and \fINAME=VALUE@\fP (where \fIVALUE\fP does not override value of \fINAME\fP attribute if it\(cqs already defined in the source document).
|
@@ -70,8 +70,8 @@ This option may be specified more than once.
|
|
70
70
|
.RS 4
|
71
71
|
Backend output file format: \fIhtml5\fP, \fIdocbook5\fP, \fIdocbook45\fP and \fImanpage\fP are supported out of the box.
|
72
72
|
You can also use the backend alias names \fIhtml\fP (aliased to \fIhtml5\fP) or \fIdocbook\fP (aliased to \fIdocbook5\fP).
|
73
|
+
Other values can be passed, but if Asciidoctor cannot resolve the backend to a converter, it will fail.
|
73
74
|
Defaults to \fIhtml5\fP.
|
74
|
-
Other options can be passed, but if Asciidoctor cannot find the backend, it will fail during conversion.
|
75
75
|
.RE
|
76
76
|
.sp
|
77
77
|
\fB\-d, \-\-doctype\fP=\fIDOCTYPE\fP
|
@@ -79,7 +79,7 @@ Other options can be passed, but if Asciidoctor cannot find the backend, it will
|
|
79
79
|
Document type: \fIarticle\fP, \fIbook\fP, \fImanpage\fP or \fIinline\fP.
|
80
80
|
Sets the root element when using the \fIdocbook\fP backend and the style class on the HTML body element when using the \fIhtml\fP backend.
|
81
81
|
The \fIbook\fP document type allows multiple level\-0 section titles in a single document.
|
82
|
-
The \fImanpage\fP document type enables parsing of metadata necessary to produce a
|
82
|
+
The \fImanpage\fP document type enables parsing of metadata necessary to produce a man page.
|
83
83
|
The \fIinline\fP document type allows the content of a single paragraph to be formatted and returned without wrapping it in a containing element.
|
84
84
|
Defaults to \fIarticle\fP.
|
85
85
|
.RE
|
@@ -129,9 +129,9 @@ Synonym for \fB\-\-attribute numbered\fP.
|
|
129
129
|
.RS 4
|
130
130
|
Write output to file \fIOUT_FILE\fP.
|
131
131
|
Defaults to the base name of the input file suffixed with \fIbackend\fP extension.
|
132
|
-
|
133
|
-
If
|
134
|
-
If
|
132
|
+
The file is resolved relative to the working directory.
|
133
|
+
If the input is read from standard input or a named pipe (fifo), then the output file defaults to stdout.
|
134
|
+
If \fIOUT_FILE\fP is \fI\-\fP, then the output file is written to standard output.
|
135
135
|
.RE
|
136
136
|
.sp
|
137
137
|
\fB\-r, \-\-require\fP=\fILIBRARY\fP
|
@@ -180,9 +180,11 @@ Display timings information (time to read, parse and convert).
|
|
180
180
|
.RE
|
181
181
|
.SS "Program Information"
|
182
182
|
.sp
|
183
|
-
\fB\-h, \-\-help\fP
|
183
|
+
\fB\-h, \-\-help\fP [\fITOPIC\fP]
|
184
184
|
.RS 4
|
185
|
-
|
185
|
+
Print the help message.
|
186
|
+
Show the command usage if \fITOPIC\fP is not specified (or not recognized).
|
187
|
+
Dump the Asciidoctor man page (in troff/groff format) if \fITOPIC\fP is \fImanpage\fP.
|
186
188
|
.RE
|
187
189
|
.sp
|
188
190
|
\fB\-V, \-\-version\fP
|
@@ -193,7 +195,7 @@ Print program version number.
|
|
193
195
|
.RE
|
194
196
|
.SH "ENVIRONMENT"
|
195
197
|
.sp
|
196
|
-
\fBAsciidoctor\fP honors the
|
198
|
+
\fBAsciidoctor\fP honors the \fBSOURCE_DATE_EPOCH\fP environment variable.
|
197
199
|
If this variable is assigned an integer value, that value is used as the epoch of all input documents and as the local date and time.
|
198
200
|
See \c
|
199
201
|
.URL "https://reproducible\-builds.org/specs/source\-date\-epoch/" "" " "
|
@@ -233,7 +235,7 @@ Refer to the \fBAsciidoctor\fP issue tracker at \c
|
|
233
235
|
.URL "http://discuss.asciidoctor.org" "" ""
|
234
236
|
.SH "COPYING"
|
235
237
|
.sp
|
236
|
-
Copyright (C) 2012\-
|
238
|
+
Copyright (C) 2012\-2017 Dan Allen, Ryan Waldron and the Asciidoctor Project.
|
237
239
|
Free use of this software is granted under the terms of the MIT License.
|
238
240
|
.SH "AUTHOR(S)"
|
239
241
|
.sp
|