diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2014-07-17 00:57:49 -0600 |
|---|---|---|
| committer | Dan Allen <dan.j.allen@gmail.com> | 2014-07-17 00:57:49 -0600 |
| commit | 0efdd9be9009676b0729f3bff4863fbe5dab037e (patch) | |
| tree | 8cb9e4da018485dd02bfd2ffe83ff29790df807c | |
| parent | f44e70af9e9a41f22264930d1514a2c5451bc3be (diff) | |
resolves #1022 \ as line continuation character in attribute value
- \ as line continuation character in attribute value
- join lines on endline char if preceding line ends with line break sequence
- optimize line continuation parse logic
| -rw-r--r-- | lib/asciidoctor.rb | 7 | ||||
| -rw-r--r-- | lib/asciidoctor/parser.rb | 23 | ||||
| -rw-r--r-- | test/attributes_test.rb | 22 |
3 files changed, 38 insertions, 14 deletions
diff --git a/lib/asciidoctor.rb b/lib/asciidoctor.rb index 729bc7bf..6dc7bc5c 100644 --- a/lib/asciidoctor.rb +++ b/lib/asciidoctor.rb @@ -311,10 +311,13 @@ module Asciidoctor LIST_CONTINUATION = '+' - # FIXME technically a preceding TAB is allowed too - # alternatively, we can enforce everywhere it must be a space + # NOTE AsciiDoc Python recognizes both a preceding TAB and a space LINE_BREAK = ' +' + LINE_CONTINUATION = ' \\' + + LINE_CONTINUATION_LEGACY = ' +' + BLOCK_MATH_DELIMITERS = { :asciimath => ['\\$', '\\$'], :latexmath => ['\\[', '\\]'], diff --git a/lib/asciidoctor/parser.rb b/lib/asciidoctor/parser.rb index d2669376..a23998e0 100644 --- a/lib/asciidoctor/parser.rb +++ b/lib/asciidoctor/parser.rb @@ -2050,17 +2050,18 @@ class Parser match ||= (reader.has_more_lines? ? AttributeEntryRx.match(reader.peek_line) : nil) if match name = match[1] - value = match[2] || '' - if value.end_with? LINE_BREAK - value = value.chop.rstrip - while reader.advance - next_line = reader.peek_line.strip - break if next_line.empty? - if next_line.end_with? LINE_BREAK - value = %(#{value} #{next_line.chop.rstrip}) - else - value = %(#{value} #{next_line}) - break + unless (value = match[2] || '').empty? + if value.end_with?(line_continuation = LINE_CONTINUATION) || + value.end_with?(line_continuation = LINE_CONTINUATION_LEGACY) + value = value.chop.rstrip + while reader.advance + break if (next_line = reader.peek_line.strip).empty? + if (keep_open = next_line.end_with? line_continuation) + next_line = next_line.chop.rstrip + end + separator = (value.end_with? LINE_BREAK) ? EOL : ' ' + value = %(#{value}#{separator}#{next_line}) + break unless keep_open end end end diff --git a/test/attributes_test.rb b/test/attributes_test.rb index bc2bbf78..52eb0eea 100644 --- a/test/attributes_test.rb +++ b/test/attributes_test.rb @@ -16,7 +16,7 @@ context 'Attributes' do assert_equal nil, doc.attributes['foo'] end - test 'creates an attribute by fusing a multi-line value' do + test 'creates an attribute by fusing a legacy multi-line value' do str = <<-EOS :description: This is the first + Ruby implementation of + @@ -26,6 +26,26 @@ context 'Attributes' do assert_equal 'This is the first Ruby implementation of AsciiDoc.', doc.attributes['description'] end + test 'creates an attribute by fusing a multi-line value' do + str = <<-EOS +:description: This is the first \\ + Ruby implementation of \\ + AsciiDoc. + EOS + doc = document_from_string(str) + assert_equal 'This is the first Ruby implementation of AsciiDoc.', doc.attributes['description'] + end + + test 'honors line break characters in multi-line values' do + str = <<-EOS +:signature: Linus Torvalds + \\ +Linux Hacker + \\ +linus.torvalds@example.com + EOS + doc = document_from_string(str) + assert_equal %(Linus Torvalds +\nLinux Hacker +\nlinus.torvalds@example.com), doc.attributes['signature'] + end + test 'should delete an attribute that ends with !' do doc = document_from_string(":frog: Tanglefoot\n:frog!:") assert_equal nil, doc.attributes['frog'] |
