asciidoctor 1.5.4 → 1.5.5
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 +72 -5
- data/CONTRIBUTING.adoc +3 -3
- data/Gemfile +23 -0
- data/README-fr.adoc +416 -0
- data/README-jp.adoc +395 -0
- data/README-zh_CN.adoc +414 -0
- data/README.adoc +134 -72
- data/asciidoctor.gemspec +49 -0
- data/data/locale/attributes.adoc +470 -0
- data/data/stylesheets/asciidoctor-default.css +6 -5
- data/lib/asciidoctor.rb +22 -19
- data/lib/asciidoctor/abstract_block.rb +20 -10
- data/lib/asciidoctor/abstract_node.rb +3 -14
- data/lib/asciidoctor/cli/invoker.rb +5 -4
- data/lib/asciidoctor/cli/options.rb +1 -1
- data/lib/asciidoctor/converter/docbook5.rb +1 -1
- data/lib/asciidoctor/converter/factory.rb +1 -5
- data/lib/asciidoctor/converter/html5.rb +36 -31
- data/lib/asciidoctor/converter/manpage.rb +14 -9
- data/lib/asciidoctor/converter/template.rb +8 -4
- data/lib/asciidoctor/core_ext.rb +7 -6
- data/lib/asciidoctor/core_ext/{string → 1.8.7/string}/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/limit.rb +28 -0
- data/lib/asciidoctor/core_ext/{symbol → 1.8.7/symbol}/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +23 -0
- data/lib/asciidoctor/core_ext/string/limit.rb +10 -0
- data/lib/asciidoctor/document.rb +33 -26
- data/lib/asciidoctor/extensions.rb +16 -16
- data/lib/asciidoctor/helpers.rb +1 -1
- data/lib/asciidoctor/list.rb +3 -0
- data/lib/asciidoctor/parser.rb +47 -43
- data/lib/asciidoctor/path_resolver.rb +3 -1
- data/lib/asciidoctor/reader.rb +15 -14
- data/lib/asciidoctor/section.rb +2 -2
- data/lib/asciidoctor/stylesheets.rb +2 -1
- data/lib/asciidoctor/substitutors.rb +44 -46
- data/lib/asciidoctor/table.rb +41 -38
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +11 -4
- data/man/asciidoctor.adoc +7 -1
- data/test/attributes_test.rb +52 -0
- data/test/blocks_test.rb +8 -8
- data/test/document_test.rb +13 -1
- data/test/extensions_test.rb +38 -0
- data/test/invoker_test.rb +15 -0
- data/test/lists_test.rb +78 -53
- data/test/manpage_test.rb +15 -0
- data/test/paths_test.rb +3 -0
- data/test/reader_test.rb +2 -2
- data/test/sections_test.rb +10 -0
- data/test/substitutions_test.rb +12 -6
- data/test/tables_test.rb +76 -2
- metadata +16 -45
- data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +0 -23
- data/test/fixtures/asciidoc_index.txt +0 -521
- data/test/fixtures/basic-docinfo-footer.html +0 -6
- data/test/fixtures/basic-docinfo-footer.xml +0 -8
- data/test/fixtures/basic-docinfo.html +0 -1
- data/test/fixtures/basic-docinfo.xml +0 -4
- data/test/fixtures/basic.asciidoc +0 -5
- data/test/fixtures/chapter-a.adoc +0 -3
- data/test/fixtures/child-include.adoc +0 -5
- data/test/fixtures/circle.svg +0 -8
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
- data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
- data/test/fixtures/docinfo-footer.html +0 -1
- data/test/fixtures/docinfo-footer.xml +0 -9
- data/test/fixtures/docinfo.html +0 -1
- data/test/fixtures/docinfo.xml +0 -3
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -0
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/parent-include-restricted.adoc +0 -5
- data/test/fixtures/parent-include.adoc +0 -5
- data/test/fixtures/sample.asciidoc +0 -26
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -7
- data/test/fixtures/tip.gif +0 -0
- data/test/test_helper.rb +0 -399
data/lib/asciidoctor/helpers.rb
CHANGED
@@ -189,7 +189,7 @@ module Helpers
|
|
189
189
|
# Returns the String filename with leading directories removed and, if specified, the extension removed
|
190
190
|
def self.basename(file_name, drop_extname = false)
|
191
191
|
if drop_extname
|
192
|
-
::File.basename file_name, (
|
192
|
+
::File.basename file_name, (::File.extname file_name)
|
193
193
|
else
|
194
194
|
::File.basename file_name
|
195
195
|
end
|
data/lib/asciidoctor/list.rb
CHANGED
@@ -43,6 +43,9 @@ end
|
|
43
43
|
# Public: Methods for managing items for AsciiDoc olists, ulist, and dlists.
|
44
44
|
class ListItem < AbstractBlock
|
45
45
|
|
46
|
+
# A contextual alias for the list parent node; counterpart to the items alias on List
|
47
|
+
alias :list :parent
|
48
|
+
|
46
49
|
# Public: Get/Set the String used to mark this list item
|
47
50
|
attr_accessor :marker
|
48
51
|
|
data/lib/asciidoctor/parser.rb
CHANGED
@@ -437,7 +437,7 @@ class Parser
|
|
437
437
|
else
|
438
438
|
block_extensions = block_macro_extensions = false
|
439
439
|
end
|
440
|
-
#parent_context =
|
440
|
+
#parent_context = Block === parent ? parent.context : nil
|
441
441
|
in_list = ListItem === parent
|
442
442
|
block = nil
|
443
443
|
style = nil
|
@@ -523,9 +523,11 @@ class Parser
|
|
523
523
|
posattrs = []
|
524
524
|
end
|
525
525
|
|
526
|
-
|
526
|
+
# QUESTION why did we make exception for explicit style?
|
527
|
+
#if style && !explicit_style
|
528
|
+
if style
|
527
529
|
attributes['alt'] = style if blk_ctx == :image
|
528
|
-
attributes.delete
|
530
|
+
attributes.delete 'style'
|
529
531
|
style = nil
|
530
532
|
end
|
531
533
|
|
@@ -633,7 +635,7 @@ class Parser
|
|
633
635
|
elsif (match = OrderedListRx.match(this_line))
|
634
636
|
reader.unshift_line this_line
|
635
637
|
block = next_outline_list(reader, :olist, parent)
|
636
|
-
#
|
638
|
+
# TODO move this logic into next_outline_list
|
637
639
|
if !attributes['style'] && !block.attributes['style']
|
638
640
|
marker = block.items[0].marker
|
639
641
|
if marker.start_with? '.'
|
@@ -641,13 +643,13 @@ class Parser
|
|
641
643
|
#attributes['style'] = (ORDERED_LIST_STYLES[block.level - 1] || ORDERED_LIST_STYLES[0]).to_s
|
642
644
|
attributes['style'] = (ORDERED_LIST_STYLES[marker.length - 1] || ORDERED_LIST_STYLES[0]).to_s
|
643
645
|
else
|
644
|
-
style = ORDERED_LIST_STYLES.
|
646
|
+
style = ORDERED_LIST_STYLES.find {|s| OrderedListMarkerRxMap[s] =~ marker }
|
645
647
|
attributes['style'] = (style || ORDERED_LIST_STYLES[0]).to_s
|
646
648
|
end
|
647
649
|
end
|
648
650
|
break
|
649
651
|
|
650
|
-
elsif (match =
|
652
|
+
elsif (match = DescriptionListRx.match(this_line))
|
651
653
|
reader.unshift_line this_line
|
652
654
|
block = next_labeled_list(reader, match, parent)
|
653
655
|
break
|
@@ -710,7 +712,7 @@ class Parser
|
|
710
712
|
adjust_indentation! lines
|
711
713
|
|
712
714
|
block = Block.new(parent, :literal, :content_model => :verbatim, :source => lines, :attributes => attributes)
|
713
|
-
# a literal gets special meaning inside of a
|
715
|
+
# a literal gets special meaning inside of a description list
|
714
716
|
# TODO this feels hacky, better way to distinguish from explicit literal block?
|
715
717
|
block.set_option('listparagraph') if in_list
|
716
718
|
|
@@ -901,7 +903,7 @@ class Parser
|
|
901
903
|
if block
|
902
904
|
block.source_location = source_location if source_location
|
903
905
|
# REVIEW seems like there is a better way to organize this wrap-up
|
904
|
-
block.title
|
906
|
+
block.title = attributes['title'] unless block.title?
|
905
907
|
# FIXME HACK don't hardcode logic for alt, caption and scaledwidth on images down here
|
906
908
|
if block.context == :image
|
907
909
|
resolved_target = attributes['target']
|
@@ -1034,7 +1036,7 @@ class Parser
|
|
1034
1036
|
end
|
1035
1037
|
end
|
1036
1038
|
|
1037
|
-
# whether a block supports
|
1039
|
+
# whether a block supports compound content should be a config setting
|
1038
1040
|
# if terminator is false, that means the all the lines in the reader should be parsed
|
1039
1041
|
# NOTE could invoke filter in here, before and after parsing
|
1040
1042
|
def self.build_block(block_context, content_model, terminator, parent, reader, attributes, options = {})
|
@@ -1237,7 +1239,7 @@ class Parser
|
|
1237
1239
|
nil
|
1238
1240
|
end
|
1239
1241
|
|
1240
|
-
# Internal: Parse and construct a
|
1242
|
+
# Internal: Parse and construct a description list Block from the current position of the Reader
|
1241
1243
|
#
|
1242
1244
|
# reader - The Reader from which to retrieve the labeled list
|
1243
1245
|
# match - The Regexp match for the head of the list
|
@@ -1249,7 +1251,7 @@ class Parser
|
|
1249
1251
|
previous_pair = nil
|
1250
1252
|
# allows us to capture until we find a labeled item
|
1251
1253
|
# that uses the same delimiter (::, :::, :::: or ;;)
|
1252
|
-
sibling_pattern =
|
1254
|
+
sibling_pattern = DescriptionListSiblingRx[match[2]]
|
1253
1255
|
|
1254
1256
|
# NOTE skip the match on the first time through as we've already done it (emulates begin...while)
|
1255
1257
|
while match || (reader.has_more_lines? && (match = sibling_pattern.match(reader.peek_line)))
|
@@ -1270,12 +1272,12 @@ class Parser
|
|
1270
1272
|
|
1271
1273
|
# Internal: Parse and construct the next ListItem for the current bulleted
|
1272
1274
|
# (unordered or ordered) list Block, callout lists included, or the next
|
1273
|
-
# term ListItem and
|
1275
|
+
# term ListItem and description ListItem pair for the labeled list Block.
|
1274
1276
|
#
|
1275
1277
|
# First collect and process all the lines that constitute the next list
|
1276
1278
|
# item for the parent list (according to its type). Next, parse those lines
|
1277
1279
|
# into blocks and associate them with the ListItem (in the case of a
|
1278
|
-
# labeled list, the
|
1280
|
+
# labeled list, the description ListItem). Finally, fold the first block
|
1279
1281
|
# into the item's text attribute according to rules described in ListItem.
|
1280
1282
|
#
|
1281
1283
|
# reader - The Reader from which to retrieve the next list item
|
@@ -1370,7 +1372,7 @@ class Parser
|
|
1370
1372
|
# through all the rules that determine what comprises a list item.
|
1371
1373
|
#
|
1372
1374
|
# Grab lines until a sibling list item is found, or the block is broken by a
|
1373
|
-
# terminator (such as a line comment).
|
1375
|
+
# terminator (such as a line comment). Description lists are more greedy if
|
1374
1376
|
# they don't have optional inline item text...they want that text
|
1375
1377
|
#
|
1376
1378
|
# reader - The Reader from which to retrieve the lines.
|
@@ -1464,7 +1466,7 @@ class Parser
|
|
1464
1466
|
elsif BlockTitleRx =~ this_line || BlockAttributeLineRx =~ this_line || AttributeEntryRx =~ this_line
|
1465
1467
|
buffer << this_line
|
1466
1468
|
else
|
1467
|
-
if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).
|
1469
|
+
if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }
|
1468
1470
|
within_nested_list = true
|
1469
1471
|
if nested_list_type == :dlist && $~[3].nil_or_empty?
|
1470
1472
|
# get greedy again
|
@@ -1494,7 +1496,7 @@ class Parser
|
|
1494
1496
|
# TODO any way to combine this with the check after skipping blank lines?
|
1495
1497
|
if is_sibling_list_item?(this_line, list_type, sibling_trait)
|
1496
1498
|
break
|
1497
|
-
elsif nested_list_type = NESTABLE_LIST_CONTEXTS.
|
1499
|
+
elsif nested_list_type = NESTABLE_LIST_CONTEXTS.find {|ctx| ListRxMap[ctx] =~ this_line }
|
1498
1500
|
buffer << this_line
|
1499
1501
|
within_nested_list = true
|
1500
1502
|
if nested_list_type == :dlist && $~[3].nil_or_empty?
|
@@ -1525,7 +1527,7 @@ class Parser
|
|
1525
1527
|
end
|
1526
1528
|
else
|
1527
1529
|
has_text = true if !this_line.empty?
|
1528
|
-
if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).
|
1530
|
+
if nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }
|
1529
1531
|
within_nested_list = true
|
1530
1532
|
if nested_list_type == :dlist && $~[3].nil_or_empty?
|
1531
1533
|
# get greedy again
|
@@ -1818,7 +1820,7 @@ class Parser
|
|
1818
1820
|
# apply header subs and assign to document
|
1819
1821
|
author_metadata.each do |key, val|
|
1820
1822
|
unless document.attributes.has_key? key
|
1821
|
-
document.attributes[key] =
|
1823
|
+
document.attributes[key] = ::String === val ? (document.apply_header_subs val) : val
|
1822
1824
|
end
|
1823
1825
|
end
|
1824
1826
|
|
@@ -1838,7 +1840,7 @@ class Parser
|
|
1838
1840
|
rev_line = reader.read_line
|
1839
1841
|
if (match = RevisionInfoLineRx.match(rev_line))
|
1840
1842
|
rev_metadata['revnumber'] = match[1].rstrip if match[1]
|
1841
|
-
unless (component = match[2].strip)
|
1843
|
+
unless (component = match[2].strip).empty?
|
1842
1844
|
# version must begin with 'v' if date is absent
|
1843
1845
|
if !match[1] && (component.start_with? 'v')
|
1844
1846
|
rev_metadata['revnumber'] = component[1..-1]
|
@@ -1928,7 +1930,7 @@ class Parser
|
|
1928
1930
|
author_entries.each_with_index do |author_entry, idx|
|
1929
1931
|
next if author_entry.empty?
|
1930
1932
|
key_map = {}
|
1931
|
-
if idx
|
1933
|
+
if idx == 0
|
1932
1934
|
keys.each do |key|
|
1933
1935
|
key_map[key.to_sym] = key
|
1934
1936
|
end
|
@@ -1977,7 +1979,7 @@ class Parser
|
|
1977
1979
|
author_metadata[%(#{key}_1)] = author_metadata[key] if author_metadata.has_key? key
|
1978
1980
|
end
|
1979
1981
|
end
|
1980
|
-
if idx
|
1982
|
+
if idx == 0
|
1981
1983
|
author_metadata['authors'] = author_metadata[key_map[:author]]
|
1982
1984
|
else
|
1983
1985
|
author_metadata['authors'] = %(#{author_metadata['authors']}, #{author_metadata[key_map[:author]]})
|
@@ -2193,7 +2195,7 @@ class Parser
|
|
2193
2195
|
#
|
2194
2196
|
# Returns the String of the first marker in this number series
|
2195
2197
|
def self.resolve_ordered_list_marker(marker, ordinal = 0, validate = false, reader = nil)
|
2196
|
-
number_style = ORDERED_LIST_STYLES.
|
2198
|
+
number_style = ORDERED_LIST_STYLES.find {|s| OrderedListMarkerRxMap[s] =~ marker }
|
2197
2199
|
expected = actual = nil
|
2198
2200
|
case number_style
|
2199
2201
|
when :arabic
|
@@ -2247,7 +2249,7 @@ class Parser
|
|
2247
2249
|
# Returns a Boolean indicating whether this line is a sibling list item given
|
2248
2250
|
# the criteria provided
|
2249
2251
|
def self.is_sibling_list_item?(line, list_type, sibling_trait)
|
2250
|
-
if
|
2252
|
+
if ::Regexp === sibling_trait
|
2251
2253
|
matcher = sibling_trait
|
2252
2254
|
expected_marker = false
|
2253
2255
|
else
|
@@ -2280,25 +2282,27 @@ class Parser
|
|
2280
2282
|
table.assign_caption attributes.delete('caption')
|
2281
2283
|
end
|
2282
2284
|
|
2283
|
-
if (attributes.key? 'cols') && !(
|
2284
|
-
table.create_columns
|
2285
|
-
|
2285
|
+
if (attributes.key? 'cols') && !(colspecs = parse_colspecs attributes['cols']).empty?
|
2286
|
+
table.create_columns colspecs
|
2287
|
+
explicit_colspecs = true
|
2286
2288
|
else
|
2287
|
-
|
2289
|
+
explicit_colspecs = false
|
2288
2290
|
end
|
2289
2291
|
|
2290
2292
|
skipped = table_reader.skip_blank_lines
|
2291
2293
|
|
2292
2294
|
parser_ctx = Table::ParserContext.new(table_reader, table, attributes)
|
2295
|
+
skip_implicit_header = (attributes.key? 'header-option') || (attributes.key? 'noheader-option')
|
2293
2296
|
loop_idx = -1
|
2294
2297
|
while table_reader.has_more_lines?
|
2295
2298
|
loop_idx += 1
|
2296
2299
|
line = table_reader.read_line
|
2297
2300
|
|
2298
|
-
if skipped == 0 && loop_idx
|
2301
|
+
if !skip_implicit_header && skipped == 0 && loop_idx == 0 &&
|
2299
2302
|
!(next_line = table_reader.peek_line).nil? && next_line.empty?
|
2300
2303
|
table.has_header_option = true
|
2301
|
-
|
2304
|
+
attributes['header-option'] = ''
|
2305
|
+
attributes['options'] = (attributes.key? 'options') ? %(#{attributes['options']},header) : 'header'
|
2302
2306
|
end
|
2303
2307
|
|
2304
2308
|
if parser_ctx.format == 'psv'
|
@@ -2307,10 +2311,10 @@ class Parser
|
|
2307
2311
|
# push an empty cell spec if boundary at start of line
|
2308
2312
|
parser_ctx.close_open_cell
|
2309
2313
|
else
|
2310
|
-
|
2314
|
+
next_cellspec, line = parse_cellspec(line, :start, parser_ctx.delimiter)
|
2311
2315
|
# if the cell spec is not null, then we're at a cell boundary
|
2312
|
-
if !
|
2313
|
-
parser_ctx.close_open_cell
|
2316
|
+
if !next_cellspec.nil?
|
2317
|
+
parser_ctx.close_open_cell next_cellspec
|
2314
2318
|
else
|
2315
2319
|
# QUESTION do we not advance to next line? if so, when will we if we came into this block?
|
2316
2320
|
end
|
@@ -2341,14 +2345,14 @@ class Parser
|
|
2341
2345
|
end
|
2342
2346
|
|
2343
2347
|
if parser_ctx.format == 'psv'
|
2344
|
-
|
2345
|
-
parser_ctx.
|
2348
|
+
next_cellspec, cell_text = parse_cellspec(m.pre_match, :end)
|
2349
|
+
parser_ctx.push_cellspec next_cellspec
|
2346
2350
|
parser_ctx.buffer = %(#{parser_ctx.buffer}#{cell_text})
|
2347
2351
|
else
|
2348
2352
|
parser_ctx.buffer = %(#{parser_ctx.buffer}#{m.pre_match})
|
2349
2353
|
end
|
2350
2354
|
|
2351
|
-
if (line = m.post_match)
|
2355
|
+
if (line = m.post_match).empty?
|
2352
2356
|
# hack to prevent dropping empty cell found at end of line (see issue #1106)
|
2353
2357
|
seen = false
|
2354
2358
|
end
|
@@ -2380,8 +2384,8 @@ class Parser
|
|
2380
2384
|
end
|
2381
2385
|
end
|
2382
2386
|
|
2383
|
-
unless (table.attributes['colcount'] ||= table.columns.size) == 0 ||
|
2384
|
-
table.
|
2387
|
+
unless (table.attributes['colcount'] ||= table.columns.size) == 0 || explicit_colspecs
|
2388
|
+
table.assign_column_widths
|
2385
2389
|
end
|
2386
2390
|
|
2387
2391
|
table.partition_header_footer attributes
|
@@ -2400,7 +2404,7 @@ class Parser
|
|
2400
2404
|
#
|
2401
2405
|
# returns a Hash of attributes that specify how to format
|
2402
2406
|
# and layout the cells in the table.
|
2403
|
-
def self.
|
2407
|
+
def self.parse_colspecs records
|
2404
2408
|
records = records.tr ' ', '' if records.include? ' '
|
2405
2409
|
# check for deprecated syntax: single number, equal column spread
|
2406
2410
|
if records == records.to_i.to_s
|
@@ -2410,7 +2414,7 @@ class Parser
|
|
2410
2414
|
specs = []
|
2411
2415
|
# NOTE -1 argument ensures we don't drop empty records
|
2412
2416
|
records.split(',', -1).each {|record|
|
2413
|
-
if record
|
2417
|
+
if record.empty?
|
2414
2418
|
specs << { 'width' => 1 }
|
2415
2419
|
# TODO might want to use scan rather than this mega-regexp
|
2416
2420
|
elsif (m = ColumnSpecRx.match(record))
|
@@ -2458,7 +2462,7 @@ class Parser
|
|
2458
2462
|
#
|
2459
2463
|
# returns the Hash of attributes that indicate how to layout
|
2460
2464
|
# and style this cell in the table.
|
2461
|
-
def self.
|
2465
|
+
def self.parse_cellspec(line, pos = :start, delimiter = nil)
|
2462
2466
|
m = nil
|
2463
2467
|
rest = ''
|
2464
2468
|
|
@@ -2665,13 +2669,13 @@ class Parser
|
|
2665
2669
|
lines.map! do |line|
|
2666
2670
|
next line if line.empty?
|
2667
2671
|
|
2668
|
-
|
2669
|
-
|
2670
|
-
end
|
2672
|
+
# NOTE Opal has to patch this use of sub!
|
2673
|
+
line.sub!(TabIndentRx) {|tabs| full_tab_space * tabs.length } if line.start_with? TAB
|
2671
2674
|
|
2672
2675
|
if line.include? TAB
|
2673
2676
|
# keeps track of how many spaces were added to adjust offset in match data
|
2674
2677
|
spaces_added = 0
|
2678
|
+
# NOTE Opal has to patch this use of gsub!
|
2675
2679
|
line.gsub!(TabRx) {
|
2676
2680
|
# calculate how many spaces this tab represents, then replace tab with spaces
|
2677
2681
|
if (offset = ($~.begin 0) + spaces_added) % tab_size == 0
|
@@ -417,7 +417,7 @@ class PathResolver
|
|
417
417
|
uri_prefix = nil
|
418
418
|
|
419
419
|
unless start.nil_or_empty? || (is_web_root? target)
|
420
|
-
target = %(#{start}#{SLASH}#{target})
|
420
|
+
target = %(#{start.chomp '/'}#{SLASH}#{target})
|
421
421
|
if (uri_prefix = Helpers.uri_prefix target)
|
422
422
|
target = target[uri_prefix.length..-1]
|
423
423
|
end
|
@@ -448,6 +448,8 @@ class PathResolver
|
|
448
448
|
end
|
449
449
|
else
|
450
450
|
resolved_segments << segment
|
451
|
+
# checking for empty would eliminate repeating forward slashes
|
452
|
+
#resolved_segments << segment unless segment.empty?
|
451
453
|
end
|
452
454
|
end
|
453
455
|
|
data/lib/asciidoctor/reader.rb
CHANGED
@@ -41,7 +41,7 @@ class Reader
|
|
41
41
|
@file = @dir = nil
|
42
42
|
@path = '<stdin>'
|
43
43
|
@lineno = 1 # IMPORTANT lineno assignment must proceed prepare_lines call!
|
44
|
-
elsif
|
44
|
+
elsif ::String === cursor
|
45
45
|
@file = cursor
|
46
46
|
@dir, @path = ::File.split @file
|
47
47
|
@lineno = 1 # IMPORTANT lineno assignment must proceed prepare_lines call!
|
@@ -84,7 +84,7 @@ class Reader
|
|
84
84
|
#
|
85
85
|
# Returns The String lines extracted from the data
|
86
86
|
def prepare_lines data, opts = {}
|
87
|
-
if
|
87
|
+
if ::String === data
|
88
88
|
if opts[:normalize]
|
89
89
|
Helpers.normalize_lines_from_string data
|
90
90
|
else
|
@@ -732,10 +732,10 @@ class PreprocessorReader < Reader
|
|
732
732
|
skip = !@document.attributes.has_key?(target)
|
733
733
|
when ','
|
734
734
|
# if any attribute is defined, then don't skip
|
735
|
-
skip =
|
735
|
+
skip = target.split(',').none? {|name| @document.attributes.has_key? name }
|
736
736
|
when '+'
|
737
737
|
# if any attribute is undefined, then skip
|
738
|
-
skip = target.split('+').
|
738
|
+
skip = target.split('+').any? {|name| !@document.attributes.has_key? name }
|
739
739
|
end
|
740
740
|
when 'ifndef'
|
741
741
|
case delimiter
|
@@ -744,10 +744,10 @@ class PreprocessorReader < Reader
|
|
744
744
|
skip = @document.attributes.has_key?(target)
|
745
745
|
when ','
|
746
746
|
# if any attribute is undefined, then don't skip
|
747
|
-
skip =
|
747
|
+
skip = target.split(',').none? {|name| !@document.attributes.has_key? name }
|
748
748
|
when '+'
|
749
749
|
# if any attribute is defined, then skip
|
750
|
-
skip = target.split('+').
|
750
|
+
skip = target.split('+').any? {|name| @document.attributes.has_key? name }
|
751
751
|
end
|
752
752
|
when 'ifeval'
|
753
753
|
# the text in brackets must match an expression
|
@@ -830,10 +830,11 @@ class PreprocessorReader < Reader
|
|
830
830
|
# FIXME we don't want to use a link macro if we are in a verbatim context
|
831
831
|
replace_next_line %(link:#{target}[])
|
832
832
|
true
|
833
|
-
elsif (abs_maxdepth = @maxdepth[:abs]) > 0
|
834
|
-
|
835
|
-
|
836
|
-
|
833
|
+
elsif (abs_maxdepth = @maxdepth[:abs]) > 0
|
834
|
+
if @include_stack.size >= abs_maxdepth
|
835
|
+
warn %(asciidoctor: ERROR: #{line_info}: maximum include depth of #{@maxdepth[:rel]} exceeded)
|
836
|
+
return false
|
837
|
+
end
|
837
838
|
if ::RUBY_ENGINE_OPAL
|
838
839
|
# NOTE resolves uri relative to currently loaded document
|
839
840
|
# NOTE we defer checking if file exists and catch the 404 error if it does not
|
@@ -883,7 +884,7 @@ class PreprocessorReader < Reader
|
|
883
884
|
inc_lines = []
|
884
885
|
attributes['lines'].split(DataDelimiterRx).each do |linedef|
|
885
886
|
if linedef.include?('..')
|
886
|
-
from, to = linedef.split('..').map(&:to_i)
|
887
|
+
from, to = linedef.split('..', 2).map(&:to_i)
|
887
888
|
if to == -1
|
888
889
|
inc_lines << from
|
889
890
|
inc_lines << 1.0/0.0
|
@@ -911,7 +912,7 @@ class PreprocessorReader < Reader
|
|
911
912
|
f.each_line do |l|
|
912
913
|
inc_lineno += 1
|
913
914
|
take = inc_lines[0]
|
914
|
-
if
|
915
|
+
if ::Float === take && take.infinite?
|
915
916
|
selected.push l
|
916
917
|
inc_line_offset = inc_lineno if inc_line_offset == 0
|
917
918
|
else
|
@@ -1010,7 +1011,7 @@ class PreprocessorReader < Reader
|
|
1010
1011
|
# data = IO.read file
|
1011
1012
|
# reader.push_include data, file, path
|
1012
1013
|
#
|
1013
|
-
# Returns
|
1014
|
+
# Returns this Reader object.
|
1014
1015
|
def push_include data, file = nil, path = nil, lineno = 1, attributes = {}
|
1015
1016
|
@include_stack << [@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines]
|
1016
1017
|
if file
|
@@ -1064,7 +1065,7 @@ class PreprocessorReader < Reader
|
|
1064
1065
|
@eof = false
|
1065
1066
|
@look_ahead = 0
|
1066
1067
|
end
|
1067
|
-
|
1068
|
+
self
|
1068
1069
|
end
|
1069
1070
|
|
1070
1071
|
def pop_include
|
data/lib/asciidoctor/section.rb
CHANGED
@@ -87,8 +87,8 @@ class Section < AbstractBlock
|
|
87
87
|
sep = @document.attributes['idseparator'] || '_'
|
88
88
|
pre = @document.attributes['idprefix'] || '_'
|
89
89
|
base_id = %(#{pre}#{title.downcase.gsub(InvalidSectionIdCharsRx, sep).tr_s(sep, sep).chomp(sep)})
|
90
|
-
# ensure id doesn't begin with
|
91
|
-
if pre.empty? && base_id.start_with?(sep)
|
90
|
+
# ensure id doesn't begin with idseparator if idprefix is empty and idseparator is not empty
|
91
|
+
if pre.empty? && !sep.empty? && base_id.start_with?(sep)
|
92
92
|
base_id = base_id[1..-1]
|
93
93
|
base_id = base_id[1..-1] while base_id.start_with?(sep)
|
94
94
|
end
|
@@ -71,7 +71,8 @@ class Stylesheets
|
|
71
71
|
def pygments_stylesheet_data style = nil
|
72
72
|
if load_pygments
|
73
73
|
(@pygments_stylesheet_data ||= {})[style || DEFAULT_PYGMENTS_STYLE] ||=
|
74
|
-
::Pygments.css '.listingblock .pygments', :classprefix => 'tok-', :style => (style || DEFAULT_PYGMENTS_STYLE)
|
74
|
+
(::Pygments.css '.listingblock .pygments', :classprefix => 'tok-', :style => (style || DEFAULT_PYGMENTS_STYLE)).
|
75
|
+
sub('.listingblock .pygments {', '.listingblock .pygments, .listingblock .pygments code {')
|
75
76
|
else
|
76
77
|
'/* Pygments styles disabled. Pygments is not available. */'
|
77
78
|
end
|