diff options
| author | Dan Allen <dallen@redhat.com> | 2013-04-17 03:41:42 -0600 |
|---|---|---|
| committer | Dan Allen <dallen@redhat.com> | 2013-04-17 03:58:34 -0600 |
| commit | ba194b968d891762fc656e3a9ee6c3aaa171e2b6 (patch) | |
| tree | 9958e76b1310f35450a136e3eb258c090de81443 | |
| parent | 7d6942c7752d2515af00dda267f1ce2a8873cf77 (diff) | |
resolves #226 add line selection to include macro
- support selecting individual lines, line ranges & remainder
| -rwxr-xr-x | lib/asciidoctor.rb | 3 | ||||
| -rw-r--r-- | lib/asciidoctor/reader.rb | 49 | ||||
| -rw-r--r-- | test/fixtures/include-file.asciidoc | 9 | ||||
| -rw-r--r-- | test/reader_test.rb | 14 |
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 |
