Skip to content

Commit

Permalink
Expand rdoc-ref targets at the end of ri output (#1141)
Browse files Browse the repository at this point in the history
There have been several document refactors in ruby/ruby that extract
individual methods/classes' documentation into separate files, like
ruby/ruby#6567

Because RI is not capable of rendering those references, RI users
are left with dramatically fewer documentation on those methods/classes.

This commit adds a new option `--expand-ref` (default: true) to expand
all the rdoc-ref targets at the end of the output.
  • Loading branch information
st0012 authored Dec 9, 2024
1 parent 4004dff commit 9e2b28c
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 11 deletions.
56 changes: 48 additions & 8 deletions lib/rdoc/ri/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def self.default_options
options[:interactive] = false
options[:profile] = false
options[:show_all] = false
options[:expand_refs] = true
options[:use_stdout] = !$stdout.tty?
options[:width] = 72

Expand Down Expand Up @@ -245,6 +246,12 @@ def self.process_args argv

opt.separator nil

opt.on("--[no-]expand-refs", "Expand rdoc-refs at the end of output") do |value|
options[:expand_refs] = value
end

opt.separator nil

opt.on("--help", "-h",
"Show help and exit.") do
puts opts
Expand Down Expand Up @@ -425,6 +432,7 @@ def initialize initial_options = {}
@use_stdout = options[:use_stdout]
@show_all = options[:show_all]
@width = options[:width]
@expand_refs = options[:expand_refs]
end

##
Expand Down Expand Up @@ -549,11 +557,8 @@ def add_includes out, includes
# Looks up the method +name+ and adds it to +out+

def add_method out, name
filtered = lookup_method name

method_out = method_document name, filtered

out.concat method_out.parts
filtered = lookup_method name
method_document out, name, filtered
end

##
Expand Down Expand Up @@ -645,6 +650,7 @@ def class_document name, found, klasses, includes, extends

add_also_in out, also_in

expand_rdoc_refs_at_the_bottom(out)
out
end

Expand Down Expand Up @@ -824,6 +830,8 @@ def display_method name

add_method out, name

expand_rdoc_refs_at_the_bottom(out)

display out
end

Expand Down Expand Up @@ -1255,9 +1263,7 @@ def lookup_method name
##
# Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+

def method_document name, filtered
out = RDoc::Markup::Document.new

def method_document out, name, filtered
out << RDoc::Markup::Heading.new(1, name)
out << RDoc::Markup::BlankLine.new

Expand Down Expand Up @@ -1514,4 +1520,38 @@ def start_server
server.start
end

RDOC_REFS_REGEXP = /\[rdoc-ref:([\w.]+)(@.*)?\]/

def expand_rdoc_refs_at_the_bottom(out)
return unless @expand_refs

extracted_rdoc_refs = []

out.each do |part|
content = if part.respond_to?(:text)
part.text
else
next
end

rdoc_refs = content.scan(RDOC_REFS_REGEXP).uniq.map do |file_name, _anchor|
file_name
end

extracted_rdoc_refs.concat(rdoc_refs)
end

found_pages = extracted_rdoc_refs.map do |ref|
begin
@stores.first.load_page(ref)
rescue RDoc::Store::MissingFileError
end
end.compact

found_pages.each do |page|
out << RDoc::Markup::Heading.new(4, "Expanded from #{page.full_name}")
out << RDoc::Markup::BlankLine.new
out << page.comment
end
end
end
57 changes: 54 additions & 3 deletions test/rdoc/test_rdoc_ri_driver.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative 'helper'

class TestRDocRIDriver < RDoc::TestCase
class RDocRIDriverTest < RDoc::TestCase

def setup
super
Expand Down Expand Up @@ -243,6 +243,29 @@ def test_add_method
assert_equal expected, out
end

def test_add_method_with_rdoc_ref_link
util_store

out = doc

@driver.add_method out, 'Foo::Bar#blah_with_rdoc_ref'

expected =
doc(
head(1, 'Foo::Bar#blah_with_rdoc_ref'),
blank_line,
para("(from #{@rdoc_home})"),
head(3, 'Implementation from Bar'),
rule(1),
verb("blah(5) => 5\n", "See also {Doc}[rdoc-ref:README.rdoc]\n"),
rule(1),
blank_line,
blank_line
)

assert_equal expected, out
end

def test_add_method_that_is_alias_for_original
util_store

Expand Down Expand Up @@ -598,7 +621,7 @@ def test_display_class
assert_match %r%^= Attributes:%, out
assert_match %r%^ attr_accessor attr%, out

assert_equal 1, out.scan(/^-{50,}$/).length, out
assert_equal 2, out.scan(/^-{50,}$/).length, out

refute_match %r%Foo::Bar#blah%, out
end
Expand All @@ -622,9 +645,29 @@ def test_display_class_all
assert_match %r%^= Attributes:%, out
assert_match %r%^ attr_accessor attr%, out

assert_equal 6, out.scan(/^-{50,}$/).length, out
assert_equal 9, out.scan(/^-{50,}$/).length, out

assert_match %r%Foo::Bar#blah%, out
assert_match %r%Foo::Bar#blah_with_rdoc_ref%, out
# From Foo::Bar and Foo::Bar#blah_with_rdoc_ref
assert_equal 2, out.scan(/rdoc-ref:README.rdoc/).length
# But README.rdoc should only be displayed once
assert_equal 1, out.scan(/Expanded from README.rdoc/).length
end

def test_rdoc_refs_expansion_can_be_disabled
util_store

@driver.instance_variable_set :@expand_rdoc_refs, false

out, = capture_output do
@driver.display_class 'Foo::Bar'
end

# From Foo::Bar
assert_equal 1, out.scan(/rdoc-ref:README.rdoc/).length
# But README.rdoc should not be expanded
assert_empty out.scan(/Expanded from README.rdoc/)
end

def test_display_class_ambiguous
Expand Down Expand Up @@ -766,6 +809,7 @@ def test_display_name_not_found_method
Foo::Bar#b not found, maybe you meant:
Foo::Bar#blah
Foo::Bar#blah_with_rdoc_ref
Foo::Bar#bother
EXPECTED

Expand Down Expand Up @@ -1141,6 +1185,7 @@ def test_list_methods_matching
assert_equal %w[
Foo::Bar#attr
Foo::Bar#blah
Foo::Bar#blah_with_rdoc_ref
Foo::Bar#bother
Foo::Bar::new
],
Expand Down Expand Up @@ -1516,11 +1561,17 @@ def util_store
@cFooInc.record_location @top_level

@cFoo_Bar = @cFoo.add_class RDoc::NormalClass, 'Bar'
@cFoo_Bar.add_comment "See also {Doc}[rdoc-ref:README.rdoc]", @top_level
@cFoo_Bar.record_location @top_level

@blah = @cFoo_Bar.add_method RDoc::AnyMethod.new(nil, 'blah')
@blah.call_seq = "blah(5) => 5\nblah(6) => 6\n"
@blah.record_location @top_level

@blah_with_rdoc_ref = @cFoo_Bar.add_method RDoc::AnyMethod.new(nil, 'blah_with_rdoc_ref')
@blah_with_rdoc_ref.call_seq = "blah(5) => 5\nSee also {Doc}[rdoc-ref:README.rdoc]"
@blah_with_rdoc_ref.record_location @top_level

@bother = @cFoo_Bar.add_method RDoc::AnyMethod.new(nil, 'bother')
@bother.block_params = "stuff"
@bother.params = "(things)"
Expand Down

0 comments on commit 9e2b28c

Please sign in to comment.