asciidoctor 1.5.8 → 2.0.0.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +162 -17
- data/LICENSE +1 -1
- data/README-de.adoc +12 -13
- data/README-fr.adoc +11 -12
- data/README-jp.adoc +11 -12
- data/README-zh_CN.adoc +12 -13
- data/README.adoc +6 -7
- data/asciidoctor.gemspec +19 -24
- data/bin/asciidoctor +5 -4
- data/data/reference/syntax.adoc +283 -0
- data/data/stylesheets/asciidoctor-default.css +56 -52
- data/data/stylesheets/coderay-asciidoctor.css +7 -9
- data/lib/asciidoctor.rb +171 -232
- data/lib/asciidoctor/abstract_block.rb +96 -105
- data/lib/asciidoctor/abstract_node.rb +118 -139
- data/lib/asciidoctor/attribute_list.rb +10 -14
- data/lib/asciidoctor/block.rb +20 -19
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/cli/invoker.rb +14 -21
- data/lib/asciidoctor/cli/options.rb +64 -54
- data/lib/asciidoctor/converter.rb +357 -185
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +604 -640
- data/lib/asciidoctor/converter/html5.rb +949 -963
- data/lib/asciidoctor/converter/manpage.rb +569 -548
- data/lib/asciidoctor/converter/template.rb +231 -272
- data/lib/asciidoctor/core_ext.rb +5 -18
- data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
- data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
- data/lib/asciidoctor/document.rb +399 -377
- data/lib/asciidoctor/extensions.rb +72 -140
- data/lib/asciidoctor/helpers.rb +122 -83
- data/lib/asciidoctor/inline.rb +5 -1
- data/lib/asciidoctor/list.rb +13 -11
- data/lib/asciidoctor/logging.rb +17 -16
- data/lib/asciidoctor/parser.rb +390 -423
- data/lib/asciidoctor/path_resolver.rb +10 -5
- data/lib/asciidoctor/reader.rb +286 -263
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/section.rb +9 -8
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +364 -509
- data/lib/asciidoctor/syntax_highlighter.rb +238 -0
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
- data/lib/asciidoctor/table.rb +73 -66
- data/lib/asciidoctor/timings.rb +4 -2
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/man/asciidoctor.1 +19 -15
- data/man/asciidoctor.adoc +14 -12
- metadata +69 -216
- data/CONTRIBUTING.adoc +0 -185
- data/Gemfile +0 -60
- data/Rakefile +0 -129
- data/bin/asciidoctor-safe +0 -15
- data/features/open_block.feature +0 -92
- data/features/pass_block.feature +0 -66
- data/features/step_definitions.rb +0 -49
- data/features/text_formatting.feature +0 -57
- data/features/xref.feature +0 -1039
- data/lib/asciidoctor/converter/base.rb +0 -59
- data/lib/asciidoctor/converter/docbook45.rb +0 -93
- data/lib/asciidoctor/converter/factory.rb +0 -226
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
- data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
- data/test/api_test.rb +0 -1240
- data/test/attribute_list_test.rb +0 -242
- data/test/attributes_test.rb +0 -1623
- data/test/blocks_test.rb +0 -3870
- data/test/converter_test.rb +0 -470
- data/test/document_test.rb +0 -1853
- data/test/extensions_test.rb +0 -1560
- 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 -9
- 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/doctime-localtime.adoc +0 -2
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/file-with-missing-include.adoc +0 -1
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -69
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.jsx +0 -8
- data/test/fixtures/include-file.ml +0 -3
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/lists.adoc +0 -96
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/mismatched-end-tag.adoc +0 -7
- data/test/fixtures/other-chapters.adoc +0 -11
- data/test/fixtures/outer-include.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 -30
- data/test/fixtures/section-a.adoc +0 -4
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subdir/index.adoc +0 -3
- data/test/fixtures/subdir/inner-include.adoc +0 -3
- data/test/fixtures/subdir/middle-include.adoc +0 -5
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -6
- data/test/fixtures/tagged-class-enclosed.rb +0 -25
- data/test/fixtures/tagged-class.rb +0 -23
- data/test/fixtures/tip.gif +0 -0
- data/test/fixtures/unclosed-tag.adoc +0 -3
- data/test/fixtures/unexpected-end-tag.adoc +0 -4
- data/test/invoker_test.rb +0 -745
- data/test/links_test.rb +0 -855
- data/test/lists_test.rb +0 -5151
- data/test/logger_test.rb +0 -211
- data/test/manpage_test.rb +0 -660
- data/test/options_test.rb +0 -262
- data/test/paragraphs_test.rb +0 -562
- data/test/parser_test.rb +0 -742
- data/test/paths_test.rb +0 -395
- data/test/preamble_test.rb +0 -173
- data/test/reader_test.rb +0 -2161
- data/test/sections_test.rb +0 -3575
- data/test/substitutions_test.rb +0 -2066
- data/test/tables_test.rb +0 -2036
- data/test/test_helper.rb +0 -447
- data/test/text_test.rb +0 -309
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: Handles all operations for resolving, cleaning and joining paths.
|
4
4
|
# This class includes operations for handling both web paths (request URIs) and
|
@@ -84,7 +84,7 @@ module Asciidoctor
|
|
84
84
|
# => 'C:/data/docs/css'
|
85
85
|
#
|
86
86
|
# begin
|
87
|
-
# resolver.system_path('../../../css', '../../..', '/path/to/docs', :
|
87
|
+
# resolver.system_path('../../../css', '../../..', '/path/to/docs', recover: false)
|
88
88
|
# rescue SecurityError => e
|
89
89
|
# puts e.message
|
90
90
|
# end
|
@@ -206,8 +206,9 @@ class PathResolver
|
|
206
206
|
|
207
207
|
# Public: Calculate the relative path to this absolute path from the specified base directory
|
208
208
|
#
|
209
|
-
# If neither path or base are absolute paths,
|
210
|
-
# within the base directory,
|
209
|
+
# If neither path or base are absolute paths, the path is not contained
|
210
|
+
# within the base directory, or the relative path cannot be computed, the
|
211
|
+
# original path is returned work is done.
|
211
212
|
#
|
212
213
|
# path - [String] an absolute filename.
|
213
214
|
# base - [String] an absolute base directory.
|
@@ -218,7 +219,11 @@ class PathResolver
|
|
218
219
|
if (offset = descends_from? path, base)
|
219
220
|
path.slice offset, path.length
|
220
221
|
else
|
221
|
-
|
222
|
+
begin
|
223
|
+
(Pathname.new path).relative_path_from(Pathname.new base).to_s
|
224
|
+
rescue
|
225
|
+
path
|
226
|
+
end
|
222
227
|
end
|
223
228
|
else
|
224
229
|
path
|
data/lib/asciidoctor/reader.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: Methods for retrieving lines from AsciiDoc source files
|
4
4
|
class Reader
|
@@ -59,7 +59,7 @@ class Reader
|
|
59
59
|
end
|
60
60
|
@lineno = cursor.lineno || 1 # IMPORTANT lineno assignment must proceed prepare_lines call!
|
61
61
|
end
|
62
|
-
@lines =
|
62
|
+
@lines = prepare_lines data, opts
|
63
63
|
@source_lines = @lines.drop 0
|
64
64
|
@mark = nil
|
65
65
|
@look_ahead = 0
|
@@ -69,47 +69,6 @@ class Reader
|
|
69
69
|
@saved = nil
|
70
70
|
end
|
71
71
|
|
72
|
-
# Internal: Prepare the lines from the provided data
|
73
|
-
#
|
74
|
-
# This method strips whitespace from the end of every line of
|
75
|
-
# the source data and appends a LF (i.e., Unix endline). This
|
76
|
-
# whitespace substitution is very important to how Asciidoctor
|
77
|
-
# works.
|
78
|
-
#
|
79
|
-
# Any leading or trailing blank lines are also removed.
|
80
|
-
#
|
81
|
-
# data - A String Array of input data to be normalized
|
82
|
-
# opts - A Hash of options to control what cleansing is done
|
83
|
-
#
|
84
|
-
# Returns The String lines extracted from the data
|
85
|
-
def prepare_lines data, opts = {}
|
86
|
-
if ::String === data
|
87
|
-
if opts[:normalize]
|
88
|
-
Helpers.normalize_lines_from_string data
|
89
|
-
else
|
90
|
-
data.split LF, -1
|
91
|
-
end
|
92
|
-
elsif opts[:normalize]
|
93
|
-
Helpers.normalize_lines_array data
|
94
|
-
else
|
95
|
-
data.drop 0
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Internal: Processes a previously unvisited line
|
100
|
-
#
|
101
|
-
# By default, this method marks the line as processed
|
102
|
-
# by incrementing the look_ahead counter and returns
|
103
|
-
# the line unmodified.
|
104
|
-
#
|
105
|
-
# Returns The String line the Reader should make available to the next
|
106
|
-
# invocation of Reader#read_line or nil if the Reader should drop the line,
|
107
|
-
# advance to the next line and process it.
|
108
|
-
def process_line line
|
109
|
-
@look_ahead += 1 if @process_lines
|
110
|
-
line
|
111
|
-
end
|
112
|
-
|
113
72
|
# Public: Check whether there are any lines left to read.
|
114
73
|
#
|
115
74
|
# If a previous call to this method resulted in a value of false,
|
@@ -351,7 +310,7 @@ class Reader
|
|
351
310
|
if next_line.start_with? '//'
|
352
311
|
if next_line.start_with? '///'
|
353
312
|
if (ll = next_line.length) > 3 && next_line == '/' * ll
|
354
|
-
read_lines_until :
|
313
|
+
read_lines_until terminator: next_line, skip_first_line: true, read_last_line: true, skip_processing: true, context: :comment
|
355
314
|
else
|
356
315
|
break
|
357
316
|
end
|
@@ -396,7 +355,7 @@ class Reader
|
|
396
355
|
end
|
397
356
|
|
398
357
|
# Public: Return all the lines from `@lines` until we (1) run out them,
|
399
|
-
# (2) find a blank line with :
|
358
|
+
# (2) find a blank line with `break_on_blank_lines: true`, or (3) find
|
400
359
|
# a line for which the given block evals to true.
|
401
360
|
#
|
402
361
|
# options - an optional Hash of processing options:
|
@@ -429,7 +388,7 @@ class Reader
|
|
429
388
|
# "\n",
|
430
389
|
# "Third line\n",
|
431
390
|
# ]
|
432
|
-
# reader = Reader.new data, nil, :
|
391
|
+
# reader = Reader.new data, nil, normalize: true
|
433
392
|
#
|
434
393
|
# reader.read_lines_until
|
435
394
|
# => ["First line", "Second line"]
|
@@ -484,7 +443,7 @@ class Reader
|
|
484
443
|
end
|
485
444
|
if terminator && terminator != line && (context = options.fetch :context, terminator)
|
486
445
|
start_cursor = cursor_at_mark if start_cursor == :at_mark
|
487
|
-
logger.warn message_with_context %(unterminated #{context} block), :
|
446
|
+
logger.warn message_with_context %(unterminated #{context} block), source_location: start_cursor
|
488
447
|
@unterminated = true
|
489
448
|
end
|
490
449
|
result
|
@@ -570,15 +529,19 @@ class Reader
|
|
570
529
|
@source_lines.join LF
|
571
530
|
end
|
572
531
|
|
532
|
+
# Internal: Save the state of the reader at cursor
|
573
533
|
def save
|
574
|
-
|
575
|
-
|
576
|
-
|
534
|
+
@saved = {}.tap do |accum|
|
535
|
+
instance_variables.each do |name|
|
536
|
+
unless name == :@saved || name == :@source_lines
|
537
|
+
accum[name] = ::Array === (val = instance_variable_get name) ? (val.drop 0) : val
|
538
|
+
end
|
539
|
+
end
|
577
540
|
end
|
578
|
-
@saved = accum
|
579
541
|
nil
|
580
542
|
end
|
581
543
|
|
544
|
+
# Internal: Restore the state of the reader at cursor
|
582
545
|
def restore_save
|
583
546
|
if @saved
|
584
547
|
@saved.each do |name, val|
|
@@ -588,15 +551,60 @@ class Reader
|
|
588
551
|
end
|
589
552
|
end
|
590
553
|
|
554
|
+
# Internal: Discard a previous saved state
|
591
555
|
def discard_save
|
592
556
|
@saved = nil
|
593
557
|
end
|
594
558
|
|
595
|
-
|
559
|
+
def to_s
|
560
|
+
%(#<#{self.class}@#{object_id} {path: #{@path.inspect}, line: #{@lineno}}>)
|
561
|
+
end
|
562
|
+
|
563
|
+
private
|
564
|
+
|
565
|
+
# Internal: Prepare the source data for parsing.
|
566
|
+
#
|
567
|
+
# Converts the source data into an Array of lines ready for parsing. If the +:normalize+ option is set, this method
|
568
|
+
# coerces the encoding of each line to UTF-8 and strips trailing whitespace, including the newline. (This whitespace
|
569
|
+
# cleaning is very important to how Asciidoctor works). Subclasses may choose to perform additional preparation.
|
570
|
+
#
|
571
|
+
# data - A String Array or String of source data to be normalized.
|
572
|
+
# opts - A Hash of options to control how lines are prepared.
|
573
|
+
# :normalize - Enables line normalization, which coerces the encoding to UTF-8 and removes trailing whitespace
|
574
|
+
# (optional, default: false).
|
596
575
|
#
|
576
|
+
# Returns A String Array of source lines. If the source data is an Array, this method returns a copy.
|
577
|
+
def prepare_lines data, opts = {}
|
578
|
+
if opts[:normalize]
|
579
|
+
::Array === data ? (Helpers.prepare_source_array data) : (Helpers.prepare_source_string data)
|
580
|
+
elsif ::Array === data
|
581
|
+
data.drop 0
|
582
|
+
elsif data
|
583
|
+
data.split LF, -1
|
584
|
+
else
|
585
|
+
[]
|
586
|
+
end
|
587
|
+
rescue
|
588
|
+
if (::Array === data ? data.join : data.to_s).valid_encoding?
|
589
|
+
raise
|
590
|
+
else
|
591
|
+
raise ::ArgumentError, 'source is either binary or contains invalid Unicode data'
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
# Internal: Processes a previously unvisited line
|
597
596
|
#
|
598
|
-
#
|
599
|
-
|
597
|
+
# By default, this method marks the line as processed
|
598
|
+
# by incrementing the look_ahead counter and returns
|
599
|
+
# the line unmodified.
|
600
|
+
#
|
601
|
+
# Returns The String line the Reader should make available to the next
|
602
|
+
# invocation of Reader#read_line or nil if the Reader should drop the line,
|
603
|
+
# advance to the next line and process it.
|
604
|
+
def process_line line
|
605
|
+
@look_ahead += 1 if @process_lines
|
606
|
+
line
|
607
|
+
end
|
600
608
|
end
|
601
609
|
|
602
610
|
# Public: Methods for retrieving lines from AsciiDoc source files, evaluating preprocessor
|
@@ -608,10 +616,13 @@ class PreprocessorReader < Reader
|
|
608
616
|
def initialize document, data = nil, cursor = nil, opts = {}
|
609
617
|
@document = document
|
610
618
|
super data, cursor, opts
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
619
|
+
if (default_include_depth = (document.attributes['max-include-depth'] || 64).to_i) > 0
|
620
|
+
# track absolute max depth, current max depth for comparing to include stack size, and relative max depth for reporting
|
621
|
+
@maxdepth = { abs: default_include_depth, curr: default_include_depth, rel: default_include_depth }
|
622
|
+
else
|
623
|
+
# if @maxdepth is not set, built-in include functionality is disabled
|
624
|
+
@maxdepth = nil
|
625
|
+
end
|
615
626
|
@include_stack = []
|
616
627
|
@includes = document.catalog[:includes]
|
617
628
|
@skipping = false
|
@@ -619,6 +630,173 @@ class PreprocessorReader < Reader
|
|
619
630
|
@include_processor_extensions = nil
|
620
631
|
end
|
621
632
|
|
633
|
+
# (see Reader#has_more_lines?)
|
634
|
+
def has_more_lines?
|
635
|
+
peek_line ? true : false
|
636
|
+
end
|
637
|
+
|
638
|
+
# (see Reader#empty?)
|
639
|
+
def empty?
|
640
|
+
peek_line ? false : true
|
641
|
+
end
|
642
|
+
alias eof? empty?
|
643
|
+
|
644
|
+
# Public: Override the Reader#peek_line method to pop the include
|
645
|
+
# stack if the last line has been reached and there's at least
|
646
|
+
# one include on the stack.
|
647
|
+
#
|
648
|
+
# Returns the next line of the source data as a String if there are lines remaining
|
649
|
+
# in the current include context or a parent include context.
|
650
|
+
# Returns nothing if there are no more lines remaining and the include stack is empty.
|
651
|
+
def peek_line direct = false
|
652
|
+
if (line = super)
|
653
|
+
line
|
654
|
+
elsif @include_stack.empty?
|
655
|
+
nil
|
656
|
+
else
|
657
|
+
pop_include
|
658
|
+
peek_line direct
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
# Public: Push source onto the front of the reader and switch the context
|
663
|
+
# based on the file, document-relative path and line information given.
|
664
|
+
#
|
665
|
+
# This method is typically used in an IncludeProcessor to add source
|
666
|
+
# read from the target specified.
|
667
|
+
#
|
668
|
+
# Examples
|
669
|
+
#
|
670
|
+
# path = 'partial.adoc'
|
671
|
+
# file = File.expand_path path
|
672
|
+
# data = File.read file
|
673
|
+
# reader.push_include data, file, path
|
674
|
+
#
|
675
|
+
# Returns this Reader object.
|
676
|
+
def push_include data, file = nil, path = nil, lineno = 1, attributes = {}
|
677
|
+
@include_stack << [@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines]
|
678
|
+
if (@file = file)
|
679
|
+
# NOTE if file is not a string, assume it's a URI
|
680
|
+
if ::String === file
|
681
|
+
@dir = ::File.dirname file
|
682
|
+
elsif RUBY_ENGINE_OPAL
|
683
|
+
@dir = ::URI.parse ::File.dirname(file = file.to_s)
|
684
|
+
else
|
685
|
+
# NOTE this intentionally throws an error if URI has no path
|
686
|
+
(@dir = file.dup).path = (dir = ::File.dirname file.path) == '/' ? '' : dir
|
687
|
+
file = file.to_s
|
688
|
+
end
|
689
|
+
path ||= ::File.basename file
|
690
|
+
# only process lines in AsciiDoc files
|
691
|
+
@process_lines = ASCIIDOC_EXTENSIONS[::File.extname file]
|
692
|
+
else
|
693
|
+
@dir = '.'
|
694
|
+
# we don't know what file type we have, so assume AsciiDoc
|
695
|
+
@process_lines = true
|
696
|
+
end
|
697
|
+
|
698
|
+
if path
|
699
|
+
@path = path
|
700
|
+
@includes[Helpers.rootname path] = attributes['partial-option'] ? nil : true if @process_lines
|
701
|
+
else
|
702
|
+
@path = '<stdin>'
|
703
|
+
end
|
704
|
+
|
705
|
+
@lineno = lineno
|
706
|
+
|
707
|
+
if @maxdepth && (attributes.key? 'depth')
|
708
|
+
if (rel_maxdepth = attributes['depth'].to_i) > 0
|
709
|
+
if (curr_maxdepth = @include_stack.size + rel_maxdepth) > (abs_maxdepth = @maxdepth[:abs])
|
710
|
+
# if relative depth exceeds absolute max depth, effectively ignore relative depth request
|
711
|
+
curr_maxdepth = rel_maxdepth = abs_maxdepth
|
712
|
+
end
|
713
|
+
@maxdepth = { abs: abs_maxdepth, curr: curr_maxdepth, rel: rel_maxdepth }
|
714
|
+
else
|
715
|
+
@maxdepth = { abs: @maxdepth[:abs], curr: @include_stack.size, rel: 0 }
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
# effectively fill the buffer
|
720
|
+
if (@lines = prepare_lines data, normalize: true, condense: false, indent: attributes['indent']).empty?
|
721
|
+
pop_include
|
722
|
+
else
|
723
|
+
# FIXME we eventually want to handle leveloffset without affecting the lines
|
724
|
+
if attributes.key? 'leveloffset'
|
725
|
+
@lines.unshift ''
|
726
|
+
@lines.unshift %(:leveloffset: #{attributes['leveloffset']})
|
727
|
+
@lines << ''
|
728
|
+
if (old_leveloffset = @document.attr 'leveloffset')
|
729
|
+
@lines << %(:leveloffset: #{old_leveloffset})
|
730
|
+
else
|
731
|
+
@lines << ':leveloffset!:'
|
732
|
+
end
|
733
|
+
# compensate for these extra lines
|
734
|
+
@lineno -= 2
|
735
|
+
end
|
736
|
+
|
737
|
+
# FIXME kind of a hack
|
738
|
+
#Document::AttributeEntry.new('infile', @file).save_to_next_block @document
|
739
|
+
#Document::AttributeEntry.new('indir', @dir).save_to_next_block @document
|
740
|
+
@look_ahead = 0
|
741
|
+
end
|
742
|
+
self
|
743
|
+
end
|
744
|
+
|
745
|
+
def include_depth
|
746
|
+
@include_stack.size
|
747
|
+
end
|
748
|
+
|
749
|
+
# Public: Reports whether pushing an include on the include stack exceeds the max include depth.
|
750
|
+
#
|
751
|
+
# Returns nil if no max depth is set and includes are disabled (max-include-depth=0), false if the current max depth
|
752
|
+
# will not be exceeded, and the relative max include depth if the current max depth will be exceed.
|
753
|
+
def exceeds_max_depth?
|
754
|
+
@maxdepth && @include_stack.size >= @maxdepth[:curr] && @maxdepth[:rel]
|
755
|
+
end
|
756
|
+
alias exceeded_max_depth? exceeds_max_depth?
|
757
|
+
|
758
|
+
# TODO Document this override
|
759
|
+
# also, we now have the field in the super class, so perhaps
|
760
|
+
# just implement the logic there?
|
761
|
+
def shift
|
762
|
+
if @unescape_next_line
|
763
|
+
@unescape_next_line = false
|
764
|
+
(line = super).slice 1, line.length
|
765
|
+
else
|
766
|
+
super
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
def include_processors?
|
771
|
+
if @include_processor_extensions.nil?
|
772
|
+
if @document.extensions? && @document.extensions.include_processors?
|
773
|
+
!!(@include_processor_extensions = @document.extensions.include_processors)
|
774
|
+
else
|
775
|
+
@include_processor_extensions = false
|
776
|
+
end
|
777
|
+
else
|
778
|
+
@include_processor_extensions != false
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
def create_include_cursor file, path, lineno
|
783
|
+
if ::String === file
|
784
|
+
dir = ::File.dirname file
|
785
|
+
elsif RUBY_ENGINE_OPAL
|
786
|
+
dir = ::File.dirname(file = file.to_s)
|
787
|
+
else
|
788
|
+
dir = (dir = ::File.dirname file.path) == '' ? '/' : dir
|
789
|
+
file = file.to_s
|
790
|
+
end
|
791
|
+
Cursor.new file, dir, path, lineno
|
792
|
+
end
|
793
|
+
|
794
|
+
def to_s
|
795
|
+
%(#<#{self.class}@#{object_id} {path: #{@path.inspect}, line: #{@lineno}, include depth: #{@include_stack.size}, include stack: [#{@include_stack.map {|inc| inc.to_s }.join ', '}]}>)
|
796
|
+
end
|
797
|
+
|
798
|
+
private
|
799
|
+
|
622
800
|
def prepare_lines data, opts = {}
|
623
801
|
result = super
|
624
802
|
|
@@ -634,9 +812,7 @@ class PreprocessorReader < Reader
|
|
634
812
|
result.pop while (last = result[-1]) && last.empty?
|
635
813
|
end
|
636
814
|
|
637
|
-
if opts[:indent]
|
638
|
-
Parser.adjust_indentation! result, opts[:indent], (@document.attr 'tabsize')
|
639
|
-
end
|
815
|
+
Parser.adjust_indentation! result, opts[:indent].to_i, (@document.attr 'tabsize').to_i if opts[:indent]
|
640
816
|
|
641
817
|
result
|
642
818
|
end
|
@@ -702,35 +878,6 @@ class PreprocessorReader < Reader
|
|
702
878
|
end
|
703
879
|
end
|
704
880
|
|
705
|
-
# (see Reader#has_more_lines?)
|
706
|
-
def has_more_lines?
|
707
|
-
peek_line ? true : false
|
708
|
-
end
|
709
|
-
|
710
|
-
# (see Reader#empty?)
|
711
|
-
def empty?
|
712
|
-
peek_line ? false : true
|
713
|
-
end
|
714
|
-
alias eof? empty?
|
715
|
-
|
716
|
-
# Public: Override the Reader#peek_line method to pop the include
|
717
|
-
# stack if the last line has been reached and there's at least
|
718
|
-
# one include on the stack.
|
719
|
-
#
|
720
|
-
# Returns the next line of the source data as a String if there are lines remaining
|
721
|
-
# in the current include context or a parent include context.
|
722
|
-
# Returns nothing if there are no more lines remaining and the include stack is empty.
|
723
|
-
def peek_line direct = false
|
724
|
-
if (line = super)
|
725
|
-
line
|
726
|
-
elsif @include_stack.empty?
|
727
|
-
nil
|
728
|
-
else
|
729
|
-
pop_include
|
730
|
-
peek_line direct
|
731
|
-
end
|
732
|
-
end
|
733
|
-
|
734
881
|
# Internal: Preprocess the directive to conditionally include or exclude content.
|
735
882
|
#
|
736
883
|
# Preprocess the conditional directive (ifdef, ifndef, ifeval, endif) under
|
@@ -763,12 +910,12 @@ class PreprocessorReader < Reader
|
|
763
910
|
|
764
911
|
if keyword == 'endif'
|
765
912
|
if @conditional_stack.empty?
|
766
|
-
logger.error message_with_context %(unmatched macro: endif::#{target}[]), :
|
913
|
+
logger.error message_with_context %(unmatched macro: endif::#{target}[]), source_location: cursor
|
767
914
|
elsif no_target || target == (pair = @conditional_stack[-1])[:target]
|
768
915
|
@conditional_stack.pop
|
769
916
|
@skipping = @conditional_stack.empty? ? false : @conditional_stack[-1][:skipping]
|
770
917
|
else
|
771
|
-
logger.error message_with_context %(mismatched macro: endif::#{target}[], expected endif::#{pair[:target]}[]), :
|
918
|
+
logger.error message_with_context %(mismatched macro: endif::#{target}[], expected endif::#{pair[:target]}[]), source_location: cursor
|
772
919
|
end
|
773
920
|
return true
|
774
921
|
end
|
@@ -807,16 +954,14 @@ class PreprocessorReader < Reader
|
|
807
954
|
# don't honor match if it doesn't meet this criteria
|
808
955
|
return false unless no_target && EvalExpressionRx =~ text.strip
|
809
956
|
|
810
|
-
|
811
|
-
|
812
|
-
lhs = resolve_expr_val lhs
|
813
|
-
rhs = resolve_expr_val rhs
|
957
|
+
lhs = resolve_expr_val $1
|
958
|
+
rhs = resolve_expr_val $3
|
814
959
|
|
815
960
|
# regex enforces a restricted set of math-related operations
|
816
|
-
if
|
961
|
+
if $2 == '!='
|
817
962
|
skip = lhs.send :==, rhs
|
818
963
|
else
|
819
|
-
skip = !(lhs.send
|
964
|
+
skip = !(lhs.send $2.to_sym, rhs)
|
820
965
|
end
|
821
966
|
end
|
822
967
|
end
|
@@ -824,7 +969,7 @@ class PreprocessorReader < Reader
|
|
824
969
|
# conditional inclusion block
|
825
970
|
if keyword == 'ifeval' || !text
|
826
971
|
@skipping = true if skip
|
827
|
-
@conditional_stack << {:
|
972
|
+
@conditional_stack << { target: target, skip: skip, skipping: @skipping }
|
828
973
|
# single line conditional inclusion
|
829
974
|
else
|
830
975
|
unless @skipping || skip
|
@@ -867,7 +1012,7 @@ class PreprocessorReader < Reader
|
|
867
1012
|
def preprocess_include_directive target, attrlist
|
868
1013
|
doc = @document
|
869
1014
|
if ((expanded_target = target).include? ATTR_REF_HEAD) &&
|
870
|
-
(expanded_target = doc.sub_attributes target, :
|
1015
|
+
(expanded_target = doc.sub_attributes target, attribute_missing: 'drop-line').empty?
|
871
1016
|
shift
|
872
1017
|
if (doc.attributes['attribute-missing'] || Compliance.attribute_missing) == 'skip'
|
873
1018
|
unshift %(Unresolved directive in #{@path} - include::#{target}[#{attrlist}])
|
@@ -876,22 +1021,31 @@ class PreprocessorReader < Reader
|
|
876
1021
|
elsif include_processors? && (ext = @include_processor_extensions.find {|candidate| candidate.instance.handles? expanded_target })
|
877
1022
|
shift
|
878
1023
|
# FIXME parse attributes only if requested by extension
|
879
|
-
ext.process_method[doc, self, expanded_target, (doc.parse_attributes attrlist, [], :
|
1024
|
+
ext.process_method[doc, self, expanded_target, (doc.parse_attributes attrlist, [], sub_input: true)]
|
880
1025
|
true
|
881
1026
|
# if running in SafeMode::SECURE or greater, don't process this directive
|
882
1027
|
# however, be friendly and at least make it a link to the source document
|
883
1028
|
elsif doc.safe >= SafeMode::SECURE
|
884
1029
|
# FIXME we don't want to use a link macro if we are in a verbatim context
|
885
1030
|
replace_next_line %(link:#{expanded_target}[])
|
886
|
-
elsif
|
887
|
-
if @include_stack.size >=
|
888
|
-
logger.error message_with_context %(maximum include depth of #{@maxdepth[:rel]} exceeded), :
|
1031
|
+
elsif @maxdepth
|
1032
|
+
if @include_stack.size >= @maxdepth[:curr]
|
1033
|
+
logger.error message_with_context %(maximum include depth of #{@maxdepth[:rel]} exceeded), source_location: cursor
|
889
1034
|
return
|
890
1035
|
end
|
891
1036
|
|
892
|
-
parsed_attrs = doc.parse_attributes attrlist, [], :
|
1037
|
+
parsed_attrs = doc.parse_attributes attrlist, [], sub_input: true
|
893
1038
|
inc_path, target_type, relpath = resolve_include_path expanded_target, attrlist, parsed_attrs
|
894
|
-
|
1039
|
+
if target_type == :file
|
1040
|
+
reader = ::File.method :open
|
1041
|
+
read_mode = FILE_READ_MODE
|
1042
|
+
elsif target_type == :uri
|
1043
|
+
reader = ::OpenURI.method :open_uri
|
1044
|
+
read_mode = URI_READ_MODE
|
1045
|
+
else
|
1046
|
+
# NOTE if target_type is not set, inc_path is a boolean to skip over (false) or reevaluate (true) the current line
|
1047
|
+
return inc_path
|
1048
|
+
end
|
895
1049
|
|
896
1050
|
inc_linenos = inc_tags = nil
|
897
1051
|
if attrlist
|
@@ -899,8 +1053,8 @@ class PreprocessorReader < Reader
|
|
899
1053
|
inc_linenos = []
|
900
1054
|
(split_delimited_value parsed_attrs['lines']).each do |linedef|
|
901
1055
|
if linedef.include? '..'
|
902
|
-
from, to = linedef.
|
903
|
-
inc_linenos += (to.empty? || (to = to.to_i) < 0) ? [from.to_i, 1.0/0.0] :
|
1056
|
+
from, _, to = linedef.partition '..'
|
1057
|
+
inc_linenos += (to.empty? || (to = to.to_i) < 0) ? [from.to_i, 1.0/0.0] : (from.to_i..to).to_a
|
904
1058
|
else
|
905
1059
|
inc_linenos << linedef.to_i
|
906
1060
|
end
|
@@ -926,7 +1080,7 @@ class PreprocessorReader < Reader
|
|
926
1080
|
if inc_linenos
|
927
1081
|
inc_lines, inc_offset, inc_lineno = [], nil, 0
|
928
1082
|
begin
|
929
|
-
|
1083
|
+
reader.call inc_path, read_mode do |f|
|
930
1084
|
select_remaining = nil
|
931
1085
|
f.each_line do |l|
|
932
1086
|
inc_lineno += 1
|
@@ -946,51 +1100,49 @@ class PreprocessorReader < Reader
|
|
946
1100
|
end
|
947
1101
|
end
|
948
1102
|
rescue
|
949
|
-
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), :
|
1103
|
+
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), source_location: cursor
|
950
1104
|
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
951
1105
|
end
|
952
1106
|
shift
|
953
1107
|
# FIXME not accounting for skipped lines in reader line numbering
|
954
1108
|
if inc_offset
|
955
|
-
parsed_attrs['partial-option'] =
|
1109
|
+
parsed_attrs['partial-option'] = ''
|
956
1110
|
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attrs
|
957
1111
|
end
|
958
1112
|
elsif inc_tags
|
959
1113
|
inc_lines, inc_offset, inc_lineno, tag_stack, tags_used, active_tag = [], nil, 0, [], ::Set.new, nil
|
960
1114
|
if inc_tags.key? '**'
|
961
1115
|
if inc_tags.key? '*'
|
962
|
-
select = base_select =
|
1116
|
+
select = base_select = inc_tags.delete '**'
|
963
1117
|
wildcard = inc_tags.delete '*'
|
964
1118
|
else
|
965
|
-
select = base_select = wildcard =
|
1119
|
+
select = base_select = wildcard = inc_tags.delete '**'
|
966
1120
|
end
|
967
1121
|
else
|
968
1122
|
select = base_select = !(inc_tags.value? true)
|
969
1123
|
wildcard = inc_tags.delete '*'
|
970
1124
|
end
|
971
1125
|
begin
|
972
|
-
|
1126
|
+
reader.call inc_path, read_mode do |f|
|
973
1127
|
dbl_co, dbl_sb = '::', '[]'
|
974
|
-
encoding = ::Encoding::UTF_8 if COERCE_ENCODING
|
975
1128
|
f.each_line do |l|
|
976
1129
|
inc_lineno += 1
|
977
|
-
# must force encoding since we're performing String operations on line
|
978
|
-
l.force_encoding encoding if encoding
|
979
1130
|
if (l.include? dbl_co) && (l.include? dbl_sb) && TagDirectiveRx =~ l
|
1131
|
+
this_tag = $2
|
980
1132
|
if $1 # end tag
|
981
|
-
if
|
1133
|
+
if this_tag == active_tag
|
982
1134
|
tag_stack.pop
|
983
1135
|
active_tag, select = tag_stack.empty? ? [nil, base_select] : tag_stack[-1]
|
984
1136
|
elsif inc_tags.key? this_tag
|
985
1137
|
include_cursor = create_include_cursor inc_path, expanded_target, inc_lineno
|
986
1138
|
if (idx = tag_stack.rindex {|key, _| key == this_tag })
|
987
1139
|
idx == 0 ? tag_stack.shift : (tag_stack.delete_at idx)
|
988
|
-
logger.warn message_with_context %(mismatched end tag (expected '#{active_tag}' but found '#{this_tag}') at line #{inc_lineno} of include #{target_type}: #{inc_path}), :
|
1140
|
+
logger.warn message_with_context %(mismatched end tag (expected '#{active_tag}' but found '#{this_tag}') at line #{inc_lineno} of include #{target_type}: #{inc_path}), source_location: cursor, include_location: include_cursor
|
989
1141
|
else
|
990
|
-
logger.warn message_with_context %(unexpected end tag '#{this_tag}' at line #{inc_lineno} of include #{target_type}: #{inc_path}), :
|
1142
|
+
logger.warn message_with_context %(unexpected end tag '#{this_tag}' at line #{inc_lineno} of include #{target_type}: #{inc_path}), source_location: cursor, include_location: include_cursor
|
991
1143
|
end
|
992
1144
|
end
|
993
|
-
elsif inc_tags.key?
|
1145
|
+
elsif inc_tags.key? this_tag
|
994
1146
|
tags_used << this_tag
|
995
1147
|
# QUESTION should we prevent tag from being selected when enclosing tag is excluded?
|
996
1148
|
tag_stack << [(active_tag = this_tag), (select = inc_tags[this_tag]), inc_lineno]
|
@@ -1006,31 +1158,31 @@ class PreprocessorReader < Reader
|
|
1006
1158
|
end
|
1007
1159
|
end
|
1008
1160
|
rescue
|
1009
|
-
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), :
|
1161
|
+
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), source_location: cursor
|
1010
1162
|
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
1011
1163
|
end
|
1012
1164
|
unless tag_stack.empty?
|
1013
1165
|
tag_stack.each do |tag_name, _, tag_lineno|
|
1014
|
-
logger.warn message_with_context %(detected unclosed tag '#{tag_name}' starting at line #{tag_lineno} of include #{target_type}: #{inc_path}), :
|
1166
|
+
logger.warn message_with_context %(detected unclosed tag '#{tag_name}' starting at line #{tag_lineno} of include #{target_type}: #{inc_path}), source_location: cursor, include_location: (create_include_cursor inc_path, expanded_target, tag_lineno)
|
1015
1167
|
end
|
1016
1168
|
end
|
1017
|
-
unless (missing_tags = inc_tags.keys
|
1018
|
-
logger.warn message_with_context %(tag#{missing_tags.size > 1 ? 's' : ''} '#{missing_tags.join ', '}' not found in include #{target_type}: #{inc_path}), :
|
1169
|
+
unless (missing_tags = inc_tags.keys - tags_used.to_a).empty?
|
1170
|
+
logger.warn message_with_context %(tag#{missing_tags.size > 1 ? 's' : ''} '#{missing_tags.join ', '}' not found in include #{target_type}: #{inc_path}), source_location: cursor
|
1019
1171
|
end
|
1020
1172
|
shift
|
1021
1173
|
if inc_offset
|
1022
|
-
parsed_attrs['partial-option'] =
|
1174
|
+
parsed_attrs['partial-option'] = '' unless base_select && wildcard && inc_tags.empty?
|
1023
1175
|
# FIXME not accounting for skipped lines in reader line numbering
|
1024
1176
|
push_include inc_lines, inc_path, relpath, inc_offset, parsed_attrs
|
1025
1177
|
end
|
1026
1178
|
else
|
1027
1179
|
begin
|
1028
|
-
# NOTE read content
|
1029
|
-
inc_content =
|
1180
|
+
# NOTE read content before shift so cursor is only advanced if IO operation succeeds
|
1181
|
+
inc_content = reader.call(inc_path, read_mode) {|f| f.read }
|
1030
1182
|
shift
|
1031
1183
|
push_include inc_content, inc_path, relpath, 1, parsed_attrs
|
1032
1184
|
rescue
|
1033
|
-
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), :
|
1185
|
+
logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), source_location: cursor
|
1034
1186
|
return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
|
1035
1187
|
end
|
1036
1188
|
end
|
@@ -1064,20 +1216,20 @@ class PreprocessorReader < Reader
|
|
1064
1216
|
# caching requires the open-uri-cached gem to be installed
|
1065
1217
|
# processing will be automatically aborted if these libraries can't be opened
|
1066
1218
|
Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
|
1067
|
-
elsif
|
1219
|
+
elsif !RUBY_ENGINE_OPAL
|
1068
1220
|
# autoload open-uri
|
1069
1221
|
::OpenURI
|
1070
1222
|
end
|
1071
1223
|
[(::URI.parse target), :uri, target]
|
1072
1224
|
else
|
1073
1225
|
# include file is resolved relative to dir of current include, or base_dir if within original docfile
|
1074
|
-
inc_path = doc.normalize_system_path target, @dir, nil, :
|
1226
|
+
inc_path = doc.normalize_system_path target, @dir, nil, target_name: 'include file'
|
1075
1227
|
unless ::File.file? inc_path
|
1076
|
-
if attributes
|
1228
|
+
if attributes['optional-option']
|
1077
1229
|
shift
|
1078
1230
|
return true
|
1079
1231
|
else
|
1080
|
-
logger.error message_with_context %(include file not found: #{inc_path}), :
|
1232
|
+
logger.error message_with_context %(include file not found: #{inc_path}), source_location: cursor
|
1081
1233
|
return replace_next_line %(Unresolved directive in #{@path} - include::#{target}[#{attrlist}])
|
1082
1234
|
end
|
1083
1235
|
end
|
@@ -1088,95 +1240,6 @@ class PreprocessorReader < Reader
|
|
1088
1240
|
end
|
1089
1241
|
end
|
1090
1242
|
|
1091
|
-
# Public: Push source onto the front of the reader and switch the context
|
1092
|
-
# based on the file, document-relative path and line information given.
|
1093
|
-
#
|
1094
|
-
# This method is typically used in an IncludeProcessor to add source
|
1095
|
-
# read from the target specified.
|
1096
|
-
#
|
1097
|
-
# Examples
|
1098
|
-
#
|
1099
|
-
# path = 'partial.adoc'
|
1100
|
-
# file = File.expand_path path
|
1101
|
-
# data = IO.read file
|
1102
|
-
# reader.push_include data, file, path
|
1103
|
-
#
|
1104
|
-
# Returns this Reader object.
|
1105
|
-
def push_include data, file = nil, path = nil, lineno = 1, attributes = {}
|
1106
|
-
@include_stack << [@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines]
|
1107
|
-
if (@file = file)
|
1108
|
-
# NOTE if file is not a string, assume it's a URI
|
1109
|
-
if ::String === file
|
1110
|
-
@dir = ::File.dirname file
|
1111
|
-
elsif ::RUBY_ENGINE_OPAL
|
1112
|
-
@dir = ::URI.parse ::File.dirname(file = file.to_s)
|
1113
|
-
else
|
1114
|
-
# NOTE this intentionally throws an error if URI has no path
|
1115
|
-
(@dir = file.dup).path = (dir = ::File.dirname file.path) == '/' ? '' : dir
|
1116
|
-
file = file.to_s
|
1117
|
-
end
|
1118
|
-
path ||= ::File.basename file
|
1119
|
-
# only process lines in AsciiDoc files
|
1120
|
-
@process_lines = ASCIIDOC_EXTENSIONS[::File.extname file]
|
1121
|
-
else
|
1122
|
-
@dir = '.'
|
1123
|
-
# we don't know what file type we have, so assume AsciiDoc
|
1124
|
-
@process_lines = true
|
1125
|
-
end
|
1126
|
-
|
1127
|
-
if path
|
1128
|
-
@path = path
|
1129
|
-
@includes[Helpers.rootname path] = attributes['partial-option'] ? nil : true if @process_lines
|
1130
|
-
else
|
1131
|
-
@path = '<stdin>'
|
1132
|
-
end
|
1133
|
-
|
1134
|
-
@lineno = lineno
|
1135
|
-
|
1136
|
-
if attributes.key? 'depth'
|
1137
|
-
depth = attributes['depth'].to_i
|
1138
|
-
depth = 1 if depth <= 0
|
1139
|
-
@maxdepth = {:abs => (@include_stack.size - 1) + depth, :rel => depth}
|
1140
|
-
end
|
1141
|
-
|
1142
|
-
# effectively fill the buffer
|
1143
|
-
if (@lines = prepare_lines data, :normalize => true, :condense => false, :indent => attributes['indent']).empty?
|
1144
|
-
pop_include
|
1145
|
-
else
|
1146
|
-
# FIXME we eventually want to handle leveloffset without affecting the lines
|
1147
|
-
if attributes.key? 'leveloffset'
|
1148
|
-
@lines.unshift ''
|
1149
|
-
@lines.unshift %(:leveloffset: #{attributes['leveloffset']})
|
1150
|
-
@lines << ''
|
1151
|
-
if (old_leveloffset = @document.attr 'leveloffset')
|
1152
|
-
@lines << %(:leveloffset: #{old_leveloffset})
|
1153
|
-
else
|
1154
|
-
@lines << ':leveloffset!:'
|
1155
|
-
end
|
1156
|
-
# compensate for these extra lines
|
1157
|
-
@lineno -= 2
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
# FIXME kind of a hack
|
1161
|
-
#Document::AttributeEntry.new('infile', @file).save_to_next_block @document
|
1162
|
-
#Document::AttributeEntry.new('indir', @dir).save_to_next_block @document
|
1163
|
-
@look_ahead = 0
|
1164
|
-
end
|
1165
|
-
self
|
1166
|
-
end
|
1167
|
-
|
1168
|
-
def create_include_cursor file, path, lineno
|
1169
|
-
if ::String === file
|
1170
|
-
dir = ::File.dirname file
|
1171
|
-
elsif ::RUBY_ENGINE_OPAL
|
1172
|
-
dir = ::File.dirname(file = file.to_s)
|
1173
|
-
else
|
1174
|
-
dir = (dir = ::File.dirname file.path) == '' ? '/' : dir
|
1175
|
-
file = file.to_s
|
1176
|
-
end
|
1177
|
-
Cursor.new file, dir, path, lineno
|
1178
|
-
end
|
1179
|
-
|
1180
1243
|
def pop_include
|
1181
1244
|
if @include_stack.size > 0
|
1182
1245
|
@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines = @include_stack.pop
|
@@ -1188,30 +1251,6 @@ class PreprocessorReader < Reader
|
|
1188
1251
|
end
|
1189
1252
|
end
|
1190
1253
|
|
1191
|
-
def include_depth
|
1192
|
-
@include_stack.size
|
1193
|
-
end
|
1194
|
-
|
1195
|
-
def exceeded_max_depth?
|
1196
|
-
if (abs_maxdepth = @maxdepth[:abs]) > 0 && @include_stack.size >= abs_maxdepth
|
1197
|
-
@maxdepth[:rel]
|
1198
|
-
else
|
1199
|
-
false
|
1200
|
-
end
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
# TODO Document this override
|
1204
|
-
# also, we now have the field in the super class, so perhaps
|
1205
|
-
# just implement the logic there?
|
1206
|
-
def shift
|
1207
|
-
if @unescape_next_line
|
1208
|
-
@unescape_next_line = false
|
1209
|
-
(line = super).slice 1, line.length
|
1210
|
-
else
|
1211
|
-
super
|
1212
|
-
end
|
1213
|
-
end
|
1214
|
-
|
1215
1254
|
# Private: Split delimited value on comma (if found), otherwise semi-colon
|
1216
1255
|
def split_delimited_value val
|
1217
1256
|
(val.include? ',') ? (val.split ',') : (val.split ';')
|
@@ -1284,7 +1323,7 @@ class PreprocessorReader < Reader
|
|
1284
1323
|
|
1285
1324
|
# QUESTION should we substitute first?
|
1286
1325
|
# QUESTION should we also require string to be single quoted (like block attribute values?)
|
1287
|
-
val = @document.sub_attributes val, :
|
1326
|
+
val = @document.sub_attributes val, attribute_missing: 'drop' if val.include? ATTR_REF_HEAD
|
1288
1327
|
|
1289
1328
|
if quoted
|
1290
1329
|
val
|
@@ -1304,21 +1343,5 @@ class PreprocessorReader < Reader
|
|
1304
1343
|
val.to_i
|
1305
1344
|
end
|
1306
1345
|
end
|
1307
|
-
|
1308
|
-
def include_processors?
|
1309
|
-
if @include_processor_extensions.nil?
|
1310
|
-
if @document.extensions? && @document.extensions.include_processors?
|
1311
|
-
!!(@include_processor_extensions = @document.extensions.include_processors)
|
1312
|
-
else
|
1313
|
-
@include_processor_extensions = false
|
1314
|
-
end
|
1315
|
-
else
|
1316
|
-
@include_processor_extensions != false
|
1317
|
-
end
|
1318
|
-
end
|
1319
|
-
|
1320
|
-
def to_s
|
1321
|
-
%(#<#{self.class}@#{object_id} {path: #{@path.inspect}, line #: #{@lineno}, include depth: #{@include_stack.size}, include stack: [#{@include_stack.map {|inc| inc.to_s }.join ', '}]}>)
|
1322
|
-
end
|
1323
1346
|
end
|
1324
1347
|
end
|