summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dallen@redhat.com>2013-04-17 03:41:42 -0600
committerDan Allen <dallen@redhat.com>2013-04-17 03:58:34 -0600
commitba194b968d891762fc656e3a9ee6c3aaa171e2b6 (patch)
tree9958e76b1310f35450a136e3eb258c090de81443
parent7d6942c7752d2515af00dda267f1ce2a8873cf77 (diff)
resolves #226 add line selection to include macro
- support selecting individual lines, line ranges & remainder
-rwxr-xr-xlib/asciidoctor.rb3
-rw-r--r--lib/asciidoctor/reader.rb49
-rw-r--r--test/fixtures/include-file.asciidoc9
-rw-r--r--test/reader_test.rb14
4 files changed, 69 insertions, 6 deletions
diff --git a/lib/asciidoctor.rb b/lib/asciidoctor.rb
index 57aedf4a..d8282aa5 100755
--- a/lib/asciidoctor.rb
+++ b/lib/asciidoctor.rb
@@ -443,7 +443,8 @@ module Asciidoctor
#:eval_expr => /^(true|false|("|'|)\{\w+(?:\-\w+)*\}\2|("|')[^\3]*\3|\-?\d+(?:\.\d+)*)[[:blank:]]*(==|!=|<=|>=|<|>)[[:blank:]]*(true|false|("|'|)\{\w+(?:\-\w+)*\}\6|("|')[^\7]*\7|\-?\d+(?:\.\d+)*)$/,
# include::chapter1.ad[]
- :include_macro => /^\\?include::([^\[]+)\[\]$/,
+ # include::example.txt[lines=1;2;5..10]
+ :include_macro => /^\\?include::([^\[]+)\[(.*?)\]$/,
# http://domain
# https://domain
diff --git a/lib/asciidoctor/reader.rb b/lib/asciidoctor/reader.rb
index e57917f1..b9ff14d1 100644
--- a/lib/asciidoctor/reader.rb
+++ b/lib/asciidoctor/reader.rb
@@ -268,7 +268,7 @@ class Reader
def preprocess_next_line
# this return could be happening from a recursive call
return nil if @eof || (next_line = @lines.first).nil?
- if next_line.include?('if') && (match = next_line.match(REGEXP[:ifdef_macro]))
+ if next_line.include?('::') && (next_line.include?('if') || next_line.include?('endif')) && (match = next_line.match(REGEXP[:ifdef_macro]))
if next_line.start_with? '\\'
@next_line_preprocessed = true
@unescape_next_line = true
@@ -287,7 +287,7 @@ class Reader
@unescape_next_line = true
false
else
- preprocess_include(match[1])
+ preprocess_include(match[1], match[2].strip)
end
else
@next_line_preprocessed = true
@@ -422,7 +422,7 @@ class Reader
# target slot of the include::[] macro
#
# returns a Boolean indicating whether the line under the cursor has changed.
- def preprocess_include(target)
+ def preprocess_include(target, raw_attributes)
# if running in SafeMode::SECURE or greater, don't process this directive
# however, be friendly and at least make it a link to the source document
if @document.safe >= SafeMode::SECURE
@@ -439,8 +439,49 @@ class Reader
# FIXME currently we're not checking the upper bound of the include depth
elsif @document.attributes.fetch('include-depth', 0).to_i > 0
advance
+ lines = nil
+ if !raw_attributes.empty?
+ attributes = AttributeList.new(raw_attributes).parse
+ if attributes.has_key? 'lines'
+ lines = []
+ attributes['lines'].split(';').each do |linedef|
+ if linedef.include?('..')
+ from, to = linedef.split('..').map(&:to_i)
+ if to == -1
+ lines << from
+ lines << 1.0/0.0
+ else
+ lines.concat Range.new(from, to).to_a
+ end
+ else
+ lines << linedef.to_i
+ end
+ end
+ lines = lines.sort.uniq
+ #lines.push lines.shift if lines.first == -1
+ end
+ end
# FIXME this borks line numbers
- @lines.unshift(*File.readlines(@document.normalize_asset_path(target, 'include file')).map {|l| "#{l.rstrip}\n"})
+ include_file = @document.normalize_asset_path(target, 'include file')
+ if lines.nil?
+ @lines.unshift(*File.readlines(include_file).map {|l| "#{l.rstrip}\n"})
+ elsif !lines.empty?
+ selected = []
+ f = File.new(include_file)
+ f.each_line {|l|
+ take = lines.first
+ if take.is_a?(Float) && take.infinite?
+ selected.push("#{l.rstrip}\n")
+ else
+ if f.lineno == take
+ selected.push("#{l.rstrip}\n")
+ lines.shift
+ end
+ break if lines.empty?
+ end
+ }
+ @lines.unshift(*selected) unless selected.empty?
+ end
true
else
@next_line_preprocessed = true
diff --git a/test/fixtures/include-file.asciidoc b/test/fixtures/include-file.asciidoc
index 21ed5fbd..61db9538 100644
--- a/test/fixtures/include-file.asciidoc
+++ b/test/fixtures/include-file.asciidoc
@@ -1 +1,8 @@
-included content
+first line of included content
+second line of included content
+third line of included content
+fourth line of included content
+fifth line of included content
+sixth line of included content
+seventh line of included content
+eighth line of included content
diff --git a/test/reader_test.rb b/test/reader_test.rb
index b7670553..28ee5955 100644
--- a/test/reader_test.rb
+++ b/test/reader_test.rb
@@ -173,6 +173,20 @@ include::fixtures/include-file.asciidoc[]
assert_match(/included content/, output)
end
+ test 'include macro supports line selection' do
+ input = <<-EOS
+include::fixtures/include-file.asciidoc[lines=1;3..4;6..-1]
+ EOS
+
+ output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :attributes => {'docdir' => File.dirname(__FILE__)}
+ assert_match(/first line/, output)
+ assert_match(/third line/, output)
+ assert_match(/fourth line/, output)
+ assert_match(/sixth line/, output)
+ assert_match(/seventh line/, output)
+ assert_match(/eighth line/, output)
+ end
+
test "block is called to handle an include macro" do
input = <<-EOS
first line