diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb index c097bab70c..9256f66deb 100644 --- a/lib/rdoc/generator/darkfish.rb +++ b/lib/rdoc/generator/darkfish.rb @@ -714,6 +714,17 @@ def template_for(file, page = true, klass = ERB) ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.] # use \p/\P{letter} instead of \w/\W in Unicode ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.] + + # Link markup to replace with its text (or remove) before taking an excerpt + ExcerptMarkdownLinks = [ + [/(?]*[^\s>.,;:!?)]>?] # :startdoc: # Returns an excerpt of the comment for usage in meta description tags @@ -725,6 +736,8 @@ def excerpt(comment) comment end + text = strip_links(text, comment.respond_to?(:format) ? comment.format : nil) + # Match from a capital letter to the first period, discarding any links, so # that we don't end up matching badges in the README pattern = ParagraphExcerptRegexpUnicode @@ -745,6 +758,15 @@ def excerpt(comment) extracted_text[0...150].tr_s("\n", " ").squeeze(" ") end + # Replaces links in +text+ written in +format+ markup with their text, and + # removes images and bare URLs, so that link targets don't end up in excerpts + def strip_links(text, format) # :nodoc: + links = format == 'markdown' ? ExcerptMarkdownLinks : ExcerptRDocLinks + + text = links.inject(text) { |t, (regexp, replacement)| t.gsub(regexp, replacement) } + text.gsub(ExcerptURL, '') + end + def generate_ancestor_list(ancestors, klass) return '' if ancestors.empty? diff --git a/test/rdoc/generator/darkfish_test.rb b/test/rdoc/generator/darkfish_test.rb index d853101312..60857c547e 100644 --- a/test/rdoc/generator/darkfish_test.rb +++ b/test/rdoc/generator/darkfish_test.rb @@ -581,6 +581,49 @@ def test_meta_tags_for_markdown_files ) end + def test_meta_tags_for_markdown_links + top_level = @store.add_file("file.rb") + klass = top_level.add_class(RDoc::NormalClass, "Linked") + comment = RDoc::Comment.new(<<~MARKDOWN, top_level) + Foo. + + [Example Link](https://example.com) and ![Badge](https://example.com/badge.svg) + MARKDOWN + comment.format = "markdown" + klass.add_comment(comment, top_level) + + @g.generate + + content = File.binread("Linked.html") + assert_include(content, '') + end + + def test_meta_tags_for_rdoc_links + top_level = @store.add_file("file.rb") + klass = top_level.add_class(RDoc::NormalClass, "Linked") + klass.add_comment(<<~RDOC, top_level) + See {the docs}[https://example.com/docs.html] or RDoc[https://ruby.github.io/rdoc/] for more. + RDOC + + @g.generate + + content = File.binread("Linked.html") + assert_include(content, '') + end + + def test_meta_tags_for_bare_urls + top_level = @store.add_file("file.rb") + klass = top_level.add_class(RDoc::NormalClass, "Linked") + klass.add_comment(<<~RDOC, top_level) + Details are at https://example.com/docs. Use it. + RDOC + + @g.generate + + content = File.binread("Linked.html") + assert_include(content, '') + end + def test_meta_tags_for_raw_pages top_level = @store.add_file("MyPage", parser: RDoc::Parser::Simple) comment = RDoc::Comment.new('this is a comment')