summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2013-08-28 04:23:09 -0600
committerDan Allen <dan.j.allen@gmail.com>2013-08-28 04:23:09 -0600
commit975b94b5100f1e11601ca33f1071233a1a231330 (patch)
tree0dc22a428f3b1369f970ef452c658fbcea5a99b5
parentb2d027a50c4c893e640654f4cfdc89a0ac954e40 (diff)
fix regression for multiple callouts on a single line
-rwxr-xr-xlib/asciidoctor.rb10
-rw-r--r--lib/asciidoctor/lexer.rb4
-rw-r--r--lib/asciidoctor/substituters.rb18
-rw-r--r--test/blocks_test.rb12
-rw-r--r--test/lists_test.rb22
5 files changed, 51 insertions, 15 deletions
diff --git a/lib/asciidoctor.rb b/lib/asciidoctor.rb
index a76ef155..78794a50 100755
--- a/lib/asciidoctor.rb
+++ b/lib/asciidoctor.rb
@@ -340,12 +340,14 @@ module Asciidoctor
:biblio_macro => /\\?\[\[\[([\w:][\w:.-]*?)\]\]\]/,
# callout reference inside literal text
- # <1> (optionally prefixed by //, # or ;; line comment chars) or <!--1--> (for XML-based languages)
+ # <1> (optionally prefixed by //, # or ;; line comment chars)
+ # <1> <2> (multiple callouts on one line)
+ # <!--1--> (for XML-based languages)
# special characters are already be replaced at this point during render
- :callout_render => /(?:(?:\/\/|#|;;) ?)?(\\)?&lt;!?(--|)(\d+)\2&gt;$/,
+ :callout_render => /(?:(?:\/\/|#|;;) ?)?(\\)?&lt;!?(--|)(\d+)\2&gt;(?=$| ?\\?&lt;!?\2\d+\2&gt;$)/,
# ...but not while scanning
- :callout_quick_scan => /(\\)?<!?(--|)(\d+)\2>$/,
- :callout_scan => /(?:(?:\/\/|#|;;) ?)?(\\)?<!?(--|)(\d+)\2>$/,
+ :callout_quick_scan => /\\?<!?(--|)(\d+)\1>(?=$| ?\\?<!?\1\d+\1>$)/,
+ :callout_scan => /(?:(?:\/\/|#|;;) ?)?(\\)?<!?(--|)(\d+)\2>(?=$| ?\\?<!?\2\d+\2>$)/,
# <1> Foo
:colist => /^<?(\d+)>[[:blank:]]+(.*)/,
diff --git a/lib/asciidoctor/lexer.rb b/lib/asciidoctor/lexer.rb
index f27d7182..fc2ea47d 100644
--- a/lib/asciidoctor/lexer.rb
+++ b/lib/asciidoctor/lexer.rb
@@ -1026,8 +1026,8 @@ class Lexer
text.scan(REGEXP[:callout_quick_scan]) {
# alias match for Ruby 1.8.7 compat
m = $~
- next if m[1] == '\\'
- document.callouts.register(m[3])
+ next if m[0][0..0] == '\\'
+ document.callouts.register(m[2])
}
end
diff --git a/lib/asciidoctor/substituters.rb b/lib/asciidoctor/substituters.rb
index 248cd0b9..3abf5e7c 100644
--- a/lib/asciidoctor/substituters.rb
+++ b/lib/asciidoctor/substituters.rb
@@ -795,7 +795,7 @@ module Substituters
m = $~
# honor the escape
if m[1] == '\\'
- next "&lt;#{m[3]}&gt;"
+ next m[0].sub('\\', '')
end
Inline.new(self, :callout, m[3], :id => @document.callouts.read_next_id).render
}
@@ -957,15 +957,14 @@ module Substituters
# extract callout marks, indexed by line number
source = source.split(EOL).map {|line|
lineno = lineno + 1
- line.sub(REGEXP[:callout_scan]) {
+ line.gsub(REGEXP[:callout_scan]) {
# alias match for Ruby 1.8.7 compat
m = $~
# honor the escape
- # FIXME this does not put back the optional leading comment chars
if m[1] == '\\'
- "<#{m[3]}>"
+ m[0].sub('\\', '')
else
- callout_marks[lineno] = m[3]
+ (callout_marks[lineno] ||= []) << m[3]
nil
end
}
@@ -996,8 +995,13 @@ module Substituters
lineno = 0
result.split(EOL).map {|line|
lineno = lineno + 1
- if (conum = callout_marks.delete(lineno))
- %(#{line}#{Inline.new(self, :callout, conum, :id => @document.callouts.read_next_id).render})
+ if (conums = callout_marks.delete(lineno))
+ if conums.size == 1
+ %(#{line}#{Inline.new(self, :callout, conums.first, :id => @document.callouts.read_next_id).render })
+ else
+ conums_markup = conums.map {|conum| Inline.new(self, :callout, conum, :id => @document.callouts.read_next_id).render } * ' '
+ %(#{line}#{conums_markup})
+ end
else
line
end
diff --git a/test/blocks_test.rb b/test/blocks_test.rb
index 69f2e8c3..1dbefaeb 100644
--- a/test/blocks_test.rb
+++ b/test/blocks_test.rb
@@ -1620,7 +1620,7 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
assert_match(/\.CodeRay \{/, output)
end
- test 'wip should replace callout marks if source-highlighter attribute is coderay' do
+ test 'should replace callout marks but not highlight them if source-highlighter attribute is coderay' do
input = <<-EOS
:source-highlighter: coderay
@@ -1629,13 +1629,21 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
require 'coderay' # <1>
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <2>
+puts html # <3> <4>
+exit 0 # <5><6>
----
<1> Load library
<2> Highlight source
+<3> Print to stdout
+<4> Redirect to a file to capture output
+<5> Exit program
+<6> Reports success
EOS
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
assert_match(/ <b>\(1\)<\/b>$/, output)
- assert_match(/ <b>\(2\)<\/b><\/code>/, output)
+ assert_match(/ <b>\(2\)<\/b>$/, output)
+ assert_match(/ <b>\(3\)<\/b> <b>\(4\)<\/b>$/, output)
+ assert_match(/ <b>\(5\)<\/b> <b>\(6\)<\/b><\/code>/, output)
end
test 'should link to CodeRay stylesheet if source-highlighter is coderay and linkcss is set' do
diff --git a/test/lists_test.rb b/test/lists_test.rb
index 16436437..5f9fb8ee 100644
--- a/test/lists_test.rb
+++ b/test/lists_test.rb
@@ -3757,6 +3757,28 @@ puts "The syntax <1> at the end of the line makes a code callout"
assert_xpath '//b', output, 0
end
+ test 'should allow multiple callouts on the same line' do
+ input = <<-EOS
+[source, ruby]
+----
+require 'asciidoctor' <1>
+doc = Asciidoctor.load('Hello, World!') # <2> <3>
+puts doc.render <4><5>
+exit 0
+----
+<1> Require library
+<2> Load document from String
+<3> Uses default backend and doctype
+<4> Renders document to String
+<5> Prints output to stdout
+ EOS
+ output = render_embedded_string input
+ assert_xpath '//code/b', output, 5
+ assert_match(/ <b>\(1\)<\/b>$/, output)
+ assert_match(/ <b>\(2\)<\/b> <b>\(3\)<\/b>$/, output)
+ assert_match(/ <b>\(4\)<\/b><b>\(5\)<\/b>$/, output)
+ end
+
test 'should allow XML comment-style callouts' do
input = <<-EOS
[source, xml]