diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2019-06-14 03:51:49 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-06-14 03:51:49 -0600 |
| commit | 36e7e1e0d79f5ff7b4ea75e61f01923ca06f1198 (patch) | |
| tree | 9f35f97df6f2c032856d212483552f3a069796f9 | |
| parent | 0810fd72d811bc954f958e3dec974ed5b6bd8f76 (diff) | |
resolves #3331 fix parsing of wrapped link and xref text PR (#3334)
| -rw-r--r-- | CHANGELOG.adoc | 1 | ||||
| -rw-r--r-- | features/xref.feature | 57 | ||||
| -rw-r--r-- | lib/asciidoctor/substitutors.rb | 26 | ||||
| -rw-r--r-- | test/links_test.rb | 16 |
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 |
