summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2019-06-14 03:51:49 -0600
committerGitHub <noreply@github.com>2019-06-14 03:51:49 -0600
commit36e7e1e0d79f5ff7b4ea75e61f01923ca06f1198 (patch)
tree9f35f97df6f2c032856d212483552f3a069796f9
parent0810fd72d811bc954f958e3dec974ed5b6bd8f76 (diff)
resolves #3331 fix parsing of wrapped link and xref text PR (#3334)
-rw-r--r--CHANGELOG.adoc1
-rw-r--r--features/xref.feature57
-rw-r--r--lib/asciidoctor/substitutors.rb26
-rw-r--r--test/links_test.rb16
4 files changed, 94 insertions, 6 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index e07d7fb3..8f6e5334 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -17,6 +17,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[
Bug Fixes::
+ * Fix parsing of wrapped link and xref text, including when an attrlist signature is detected (#3331)
* Restore deprecated writable number property on AbstractBlock
Improvements::
diff --git a/features/xref.feature b/features/xref.feature
index e7f2bfde..5ddcf308 100644
--- a/features/xref.feature
+++ b/features/xref.feature
@@ -950,6 +950,63 @@ Feature: Cross References
a< href='#_section_one' "The Premier Section"
"""
+ Scenario: Does not parse text of xref macro as attribute if no attributes found
+ Given the AsciiDoc source
+ """
+ == Section One
+
+ content
+
+ == Section Two
+
+ refer to xref:_section_one[Section One
+ = First Section]
+ """
+ When it is converted to html
+ Then the result should match the HTML structure
+ """
+ .sect1
+ h2#_section_one
+ |Section One
+ .sectionbody: .paragraph: p content
+ .sect1
+ h2#_section_two Section Two
+ .sectionbody: .paragraph: p
+ |refer to
+ a< href='#_section_one'
+ |Section One
+ |= First Section
+ """
+
+ Scenario: Does not parse formatted text of xref macro as attributes
+ Given the AsciiDoc source
+ """
+ == Section One
+
+ content
+
+ == Section Two
+
+ refer to xref:_section_one[[.role]#Section
+ One#]
+ """
+ When it is converted to html
+ Then the result should match the HTML structure
+ """
+ .sect1
+ h2#_section_one
+ |Section One
+ .sectionbody: .paragraph: p content
+ .sect1
+ h2#_section_two Section Two
+ .sectionbody: .paragraph: p
+ |refer to
+ a< href='#_section_one'
+ span.role
+ |Section
+ |One
+ """
+
Scenario: Can escape double quotes in text of xref macro using backslashes when text is parsed as attributes
Given the AsciiDoc source
"""
diff --git a/lib/asciidoctor/substitutors.rb b/lib/asciidoctor/substitutors.rb
index 5f4d21bb..e47f0292 100644
--- a/lib/asciidoctor/substitutors.rb
+++ b/lib/asciidoctor/substitutors.rb
@@ -591,7 +591,8 @@ module Substitutors
unless text.empty?
text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
if !doc.compat_mode && (text.include? '=')
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
+ # NOTE if an equals sign (=) is present, extract attributes from text
+ text, attrs = extract_attributes_from_text text, ''
link_opts[:id] = attrs['id']
end
@@ -637,7 +638,8 @@ module Substitutors
text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
if mailto
if !doc.compat_mode && (text.include? ',')
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
+ # NOTE if a comma (,) is present, extract attributes from text
+ text, attrs = extract_attributes_from_text text, ''
link_opts[:id] = attrs['id']
if attrs.key? 2
if attrs.key? 3
@@ -648,7 +650,8 @@ module Substitutors
end
end
elsif !doc.compat_mode && (text.include? '=')
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
+ # NOTE if an equals sign (=) is present, extract attributes from text
+ text, attrs = extract_attributes_from_text text, ''
link_opts[:id] = attrs['id']
end
@@ -739,8 +742,8 @@ module Substitutors
refid = $2
if (text = $3)
text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
- # NOTE if an equal sign (=) is present, parse text as attributes
- text = ((AttributeList.new text, self).parse_into attrs)[1] if !doc.compat_mode && (text.include? '=')
+ # NOTE if an equals sign (=) is present, extract attributes from text
+ text, attrs = extract_attributes_from_text text if !doc.compat_mode && (text.include? '=')
end
end
@@ -1321,6 +1324,19 @@ module Substitutors
private
+ # This method is used in cases when the attrlist can be mixed with the text of a macro.
+ # If no attributes are detected aside from the first positional attribute, and the first positional
+ # attribute matches the attrlist, then the original text is returned.
+ def extract_attributes_from_text text, default_text = nil
+ attrlist = (text.include? LF) ? (text.tr LF, ' ') : text
+ if (resolved_text = (attrs = (AttributeList.new attrlist, self).parse)[1])
+ # NOTE if resolved text remains unchanged, clear attributes and return unparsed text
+ resolved_text == attrlist ? [text, attrs.clear] : [resolved_text, attrs]
+ else
+ [default_text, attrs]
+ end
+ end
+
# Internal: Extract the callout numbers from the source to prepare it for syntax highlighting.
def extract_callouts source
callout_marks = {}
diff --git a/test/links_test.rb b/test/links_test.rb
index 56ddd1e5..30ae3774 100644
--- a/test/links_test.rb
+++ b/test/links_test.rb
@@ -212,6 +212,10 @@ context 'Links' do
assert_xpath '//a[@href="http://search.example.com"][text()="Google, Yahoo, Bing = Search Engines"]', convert_string_to_embedded('http://search.example.com["Google, Yahoo, Bing = Search Engines"]'), 1
end
+ test 'should leave link text as is if it contains an equals sign but no attributes are found' do
+ assert_xpath %(//a[@href="https://example.com"][text()="What You Need\n= What You Get"]), convert_string_to_embedded(%(https://example.com[What You Need\n= What You Get])), 1
+ end
+
test 'link with quoted text but no equal sign should carry quotes over to output' do
assert_xpath %(//a[@href="http://search.example.com"][text()='"Google, Yahoo, Bing"']), convert_string_to_embedded('http://search.example.com["Google, Yahoo, Bing"]'), 1
end
@@ -220,10 +224,20 @@ context 'Links' do
assert_xpath '//a[@href="http://search.example.com"][text()="Google, Yahoo, Bing"]', convert_string_to_embedded('http://search.example.com[Google, Yahoo, Bing]'), 1
end
- test 'role and window attributes on link are processed' do
+ test 'link with formatted wrapped text should not be separated into attributes' do
+ result = convert_string_to_embedded %(https://example.com[[.role]#Foo\nBar#])
+ assert_include %(<a href="https://example.com"><span class="role">Foo\nBar</span></a>), result
+ end
+
+ test 'should process role and window attributes on link' do
assert_xpath '//a[@href="http://google.com"][@class="external"][@target="_blank"]', convert_string_to_embedded('http://google.com[Google, role=external, window="_blank"]'), 1
end
+ test 'should parse link with wrapped text that includes attributes' do
+ result = convert_string_to_embedded %(https://example.com[Foo\nBar,role=foobar])
+ assert_include %(<a href="https://example.com" class="foobar">Foo Bar</a>), result
+ end
+
test 'link macro with attributes but no text should use URL as text' do
url = 'https://fonts.googleapis.com/css?family=Roboto:400,400italic,'
assert_xpath %(//a[@href="#{url}"][text()="#{url}"]), convert_string_to_embedded(%(link:#{url}[family=Roboto,weight=400])), 1