rdoc 8.0.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -3
- data/RI.md +75 -75
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +71 -69
- data/lib/rdoc/code_object/any_method.rb +305 -303
- data/lib/rdoc/code_object/attr.rb +150 -148
- data/lib/rdoc/code_object/class_module.rb +798 -792
- data/lib/rdoc/code_object/constant.rb +175 -173
- data/lib/rdoc/code_object/context/section.rb +142 -138
- data/lib/rdoc/code_object/context.rb +926 -958
- data/lib/rdoc/code_object/extend.rb +7 -5
- data/lib/rdoc/code_object/include.rb +7 -5
- data/lib/rdoc/code_object/method_attr.rb +326 -319
- data/lib/rdoc/code_object/mixin.rb +97 -95
- data/lib/rdoc/code_object/normal_class.rb +77 -78
- data/lib/rdoc/code_object/normal_module.rb +61 -59
- data/lib/rdoc/code_object/require.rb +23 -39
- data/lib/rdoc/code_object/single_class.rb +21 -19
- data/lib/rdoc/code_object/top_level.rb +212 -219
- data/lib/rdoc/code_object.rb +305 -303
- data/lib/rdoc/comment.rb +275 -273
- data/lib/rdoc/cross_reference.rb +192 -190
- data/lib/rdoc/encoding.rb +105 -103
- data/lib/rdoc/erb_partial.rb +13 -11
- data/lib/rdoc/erbio.rb +29 -27
- data/lib/rdoc/generator/aliki.rb +161 -153
- data/lib/rdoc/generator/darkfish.rb +645 -635
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +164 -146
- data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
- data/lib/rdoc/generator/pot/po.rb +52 -51
- data/lib/rdoc/generator/pot/po_entry.rb +138 -132
- data/lib/rdoc/generator/pot.rb +85 -81
- data/lib/rdoc/generator/ri.rb +23 -19
- data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
- data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- data/lib/rdoc/generator.rb +48 -46
- data/lib/rdoc/i18n/locale.rb +99 -95
- data/lib/rdoc/i18n/text.rb +109 -105
- data/lib/rdoc/i18n.rb +7 -5
- data/lib/rdoc/markdown/byte_runtime.rb +80 -0
- data/lib/rdoc/markdown.kpeg +15 -11
- data/lib/rdoc/markdown.rb +40 -47
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +219 -215
- data/lib/rdoc/markup/include.rb +33 -29
- data/lib/rdoc/markup/indented_paragraph.rb +37 -33
- data/lib/rdoc/markup/inline_parser.rb +281 -277
- data/lib/rdoc/markup/list.rb +80 -88
- data/lib/rdoc/markup/list_item.rb +73 -85
- data/lib/rdoc/markup/paragraph.rb +23 -19
- data/lib/rdoc/markup/parser.rb +501 -497
- data/lib/rdoc/markup/pre_process.rb +283 -279
- data/lib/rdoc/markup/raw.rb +2 -2
- data/lib/rdoc/markup/rule.rb +16 -12
- data/lib/rdoc/markup/to_ansi.rb +143 -139
- data/lib/rdoc/markup/to_bs.rb +72 -68
- data/lib/rdoc/markup/to_html.rb +594 -565
- data/lib/rdoc/markup/to_html_crossref.rb +234 -230
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
- data/lib/rdoc/markup/to_label.rb +63 -59
- data/lib/rdoc/markup/to_markdown.rb +212 -208
- data/lib/rdoc/markup/to_rdoc.rb +336 -332
- data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
- data/lib/rdoc/markup/to_test.rb +60 -56
- data/lib/rdoc/markup/to_tt_only.rb +84 -80
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1061
- data/lib/rdoc/parser/c.rb +1039 -1037
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +239 -235
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1245 -1124
- data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +228 -220
- data/lib/rdoc/rbs_helper.rb +1 -1
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +500 -491
- data/lib/rdoc/ri/driver.rb +1140 -1135
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +354 -350
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -12
- data/lib/rdoc/rubygems_hook.rb +183 -181
- data/lib/rdoc/server.rb +349 -347
- data/lib/rdoc/stats/normal.rb +46 -42
- data/lib/rdoc/stats/quiet.rb +39 -35
- data/lib/rdoc/stats/verbose.rb +35 -31
- data/lib/rdoc/stats.rb +365 -363
- data/lib/rdoc/store.rb +888 -902
- data/lib/rdoc/task.rb +260 -256
- data/lib/rdoc/text.rb +135 -133
- data/lib/rdoc/token_stream.rb +101 -93
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- metadata +4 -5
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
|
@@ -1,261 +1,265 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
2
|
+
module RDoc
|
|
3
|
+
class Markup
|
|
4
|
+
##
|
|
5
|
+
# Subclass of the RDoc::Markup::ToHtml class that supports looking up method
|
|
6
|
+
# names, classes, etc to create links. RDoc::CrossReference is used to
|
|
7
|
+
# generate those links based on the current context.
|
|
6
8
|
|
|
7
|
-
class
|
|
9
|
+
class ToHtmlCrossref < Markup::ToHtml
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
# :stopdoc:
|
|
12
|
+
ALL_CROSSREF_REGEXP = CrossReference::ALL_CROSSREF_REGEXP
|
|
13
|
+
CROSSREF_REGEXP = CrossReference::CROSSREF_REGEXP
|
|
14
|
+
# :startdoc:
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
##
|
|
17
|
+
# RDoc::CodeObject for generating references
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
attr_accessor :context
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
##
|
|
22
|
+
# Should we show '#' characters on method references?
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
attr_accessor :show_hash
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
##
|
|
27
|
+
# Creates a new crossref resolver that generates links relative to +context+
|
|
28
|
+
# which lives at +from_path+ in the generated files. '#' characters on
|
|
29
|
+
# references are removed unless +show_hash+ is true. Only method names
|
|
30
|
+
# preceded by '#' or '::' are linked, unless +hyperlink_all+ is true.
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
def initialize(from_path, context, pipe: false, output_decoration: true,
|
|
33
|
+
hyperlink_all: false, show_hash: false,
|
|
34
|
+
autolink_excluded_words: [], warn_missing_rdoc_ref: true)
|
|
35
|
+
raise ArgumentError, 'from_path cannot be nil' if from_path.nil?
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
super(pipe: pipe, output_decoration: output_decoration)
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
@context = context
|
|
40
|
+
@from_path = from_path
|
|
41
|
+
@hyperlink_all = hyperlink_all
|
|
42
|
+
@show_hash = show_hash
|
|
43
|
+
@autolink_excluded_words = autolink_excluded_words
|
|
44
|
+
@warn_missing_rdoc_ref = warn_missing_rdoc_ref
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# :nodoc:
|
|
48
|
-
def init_link_notation_regexp_handlings
|
|
49
|
-
add_regexp_handling_RDOCLINK
|
|
50
|
-
|
|
51
|
-
# The crossref must be linked before tidylink because Klass.method[:sym]
|
|
52
|
-
# will be processed as a tidylink first and will be broken.
|
|
53
|
-
crossref_re = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
54
|
-
@markup.add_regexp_handling crossref_re, :CROSSREF
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
##
|
|
58
|
-
# Creates a link to the reference +name+ if the name exists. If +text+ is
|
|
59
|
-
# given it is used as the link text, otherwise +name+ is used.
|
|
60
|
-
# Returns +nil+ if the link target could not be resolved.
|
|
61
|
-
|
|
62
|
-
def cross_reference(name, text = nil, code = true, rdoc_ref: false)
|
|
63
|
-
# Strip '#' for link display text (e.g. #method shows as "method" in links)
|
|
64
|
-
display = !@show_hash && name.start_with?('#') ? name[1..] : name
|
|
65
|
-
|
|
66
|
-
if !display.end_with?('+@', '-@') && match = display.match(/(.*[^#:])?@(.*)/)
|
|
67
|
-
context_name = match[1]
|
|
68
|
-
label = convert_string(RDoc::Text.decode_legacy_label(match[2]))
|
|
69
|
-
text ||= "#{label} at <code>#{convert_string(context_name)}</code>" if context_name
|
|
70
|
-
text ||= label
|
|
71
|
-
code = false
|
|
72
|
-
else
|
|
73
|
-
text ||= convert_string(display)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
link(name, text, code, rdoc_ref: rdoc_ref)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
##
|
|
80
|
-
# We're invoked when any text matches the CROSSREF pattern. If we find the
|
|
81
|
-
# corresponding reference, generate a link. If the name we're looking for
|
|
82
|
-
# contains no punctuation, we look for it up the module/class chain. For
|
|
83
|
-
# example, ToHtml is found, even without the <tt>RDoc::Markup::</tt> prefix,
|
|
84
|
-
# because we look for it in module Markup first.
|
|
85
|
-
|
|
86
|
-
def handle_regexp_CROSSREF(name)
|
|
87
|
-
return convert_string(name) if in_tidylink_label?
|
|
88
|
-
return name if @autolink_excluded_words&.include?(name)
|
|
89
|
-
|
|
90
|
-
return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails
|
|
91
|
-
|
|
92
|
-
unless @hyperlink_all then
|
|
93
|
-
# This ensures that words entirely consisting of lowercase letters will
|
|
94
|
-
# not have cross-references generated (to suppress lots of erroneous
|
|
95
|
-
# cross-references to "new" in text, for instance)
|
|
96
|
-
return name if name =~ /\A[a-z]*\z/
|
|
97
|
-
end
|
|
98
|
-
cross_reference(name, rdoc_ref: false) || convert_string(name)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
##
|
|
102
|
-
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
|
|
103
|
-
# handle other schemes.
|
|
104
|
-
|
|
105
|
-
def handle_regexp_HYPERLINK(url)
|
|
106
|
-
return convert_string(url) if in_tidylink_label?
|
|
107
|
-
|
|
108
|
-
case url
|
|
109
|
-
when /\Ardoc-ref:/
|
|
110
|
-
ref = $'
|
|
111
|
-
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
112
|
-
else
|
|
113
|
-
super
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
##
|
|
118
|
-
# +target+ is an rdoc-schemed link that will be converted into a hyperlink.
|
|
119
|
-
# For the rdoc-ref scheme the cross-reference will be looked up and the
|
|
120
|
-
# given name will be used.
|
|
121
|
-
#
|
|
122
|
-
# All other contents are handled by
|
|
123
|
-
# {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]
|
|
124
|
-
|
|
125
|
-
def handle_regexp_RDOCLINK(url)
|
|
126
|
-
case url
|
|
127
|
-
when /\Ardoc-ref:/
|
|
128
|
-
if in_tidylink_label?
|
|
129
|
-
convert_string(url)
|
|
130
|
-
else
|
|
131
|
-
ref = $'
|
|
132
|
-
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
46
|
+
@cross_reference = CrossReference.new @context
|
|
133
47
|
end
|
|
134
|
-
else
|
|
135
|
-
super
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
48
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
49
|
+
# :nodoc:
|
|
50
|
+
def init_link_notation_regexp_handlings
|
|
51
|
+
add_regexp_handling_RDOCLINK
|
|
142
52
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
super
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
##
|
|
153
|
-
# Creates an HTML link to +name+ with the given +html_string+.
|
|
154
|
-
# +html_string+ should be already escaped and may contain HTML tags.
|
|
155
|
-
# Returns the link HTML string, or +nil+ if the reference could not be resolved.
|
|
53
|
+
# The crossref must be linked before tidylink because Klass.method[:sym]
|
|
54
|
+
# will be processed as a tidylink first and will be broken.
|
|
55
|
+
crossref_re = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
56
|
+
@markup.add_regexp_handling crossref_re, :CROSSREF
|
|
57
|
+
end
|
|
156
58
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
name
|
|
160
|
-
|
|
161
|
-
|
|
59
|
+
##
|
|
60
|
+
# Creates a link to the reference +name+ if the name exists. If +text+ is
|
|
61
|
+
# given it is used as the link text, otherwise +name+ is used.
|
|
62
|
+
# Returns +nil+ if the link target could not be resolved.
|
|
63
|
+
|
|
64
|
+
def cross_reference(name, text = nil, code = true, rdoc_ref: false)
|
|
65
|
+
# Strip '#' for link display text (e.g. #method shows as "method" in links)
|
|
66
|
+
display = !@show_hash && name.start_with?('#') ? name[1..] : name
|
|
67
|
+
|
|
68
|
+
if !display.end_with?('+@', '-@') && match = display.match(/(.*[^#:])?@(.*)/)
|
|
69
|
+
context_name = match[1]
|
|
70
|
+
label = convert_string(Text.decode_legacy_label(match[2]))
|
|
71
|
+
text ||= "#{label} at <code>#{convert_string(context_name)}</code>" if context_name
|
|
72
|
+
text ||= label
|
|
73
|
+
code = false
|
|
74
|
+
else
|
|
75
|
+
text ||= convert_string(display)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
link(name, text, code, rdoc_ref: rdoc_ref)
|
|
79
|
+
end
|
|
162
80
|
|
|
163
|
-
|
|
81
|
+
##
|
|
82
|
+
# We're invoked when any text matches the CROSSREF pattern. If we find the
|
|
83
|
+
# corresponding reference, generate a link. If the name we're looking for
|
|
84
|
+
# contains no punctuation, we look for it up the module/class chain. For
|
|
85
|
+
# example, ToHtml is found, even without the <tt>RDoc::Markup::</tt> prefix,
|
|
86
|
+
# because we look for it in module Markup first.
|
|
87
|
+
|
|
88
|
+
def handle_regexp_CROSSREF(name)
|
|
89
|
+
return convert_string(name) if in_tidylink_label?
|
|
90
|
+
return convert_string(name) if @autolink_excluded_words&.include?(name)
|
|
91
|
+
|
|
92
|
+
return convert_string(name) if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails
|
|
93
|
+
|
|
94
|
+
unless @hyperlink_all
|
|
95
|
+
# This ensures that words entirely consisting of lowercase letters will
|
|
96
|
+
# not have cross-references generated (to suppress lots of erroneous
|
|
97
|
+
# cross-references to "new" in text, for instance)
|
|
98
|
+
return name if name =~ /\A[a-z]*\z/
|
|
99
|
+
end
|
|
100
|
+
cross_reference(name, rdoc_ref: false) || convert_string(name)
|
|
101
|
+
end
|
|
164
102
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return
|
|
169
|
-
end
|
|
103
|
+
##
|
|
104
|
+
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
|
|
105
|
+
# handle other schemes.
|
|
170
106
|
|
|
171
|
-
|
|
172
|
-
|
|
107
|
+
def handle_regexp_HYPERLINK(url)
|
|
108
|
+
return convert_string(url) if in_tidylink_label?
|
|
173
109
|
|
|
174
|
-
|
|
175
|
-
|
|
110
|
+
case url
|
|
111
|
+
when /\Ardoc-ref:/
|
|
112
|
+
ref = $'
|
|
113
|
+
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
114
|
+
else
|
|
115
|
+
super
|
|
116
|
+
end
|
|
176
117
|
end
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
# +target+ is an rdoc-schemed link that will be converted into a hyperlink.
|
|
121
|
+
# For the rdoc-ref scheme the cross-reference will be looked up and the
|
|
122
|
+
# given name will be used.
|
|
123
|
+
#
|
|
124
|
+
# All other contents are handled by
|
|
125
|
+
# {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]
|
|
126
|
+
|
|
127
|
+
def handle_regexp_RDOCLINK(url)
|
|
128
|
+
case url
|
|
129
|
+
when /\Ardoc-ref:/
|
|
130
|
+
if in_tidylink_label?
|
|
131
|
+
convert_string(url)
|
|
132
|
+
else
|
|
133
|
+
ref = $'
|
|
134
|
+
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
135
|
+
end
|
|
136
|
+
else
|
|
137
|
+
super
|
|
138
|
+
end
|
|
180
139
|
end
|
|
181
|
-
return
|
|
182
|
-
else
|
|
183
|
-
# A bare label reference like @foo still produces a valid anchor link
|
|
184
|
-
return unless label
|
|
185
|
-
path = +""
|
|
186
|
-
end
|
|
187
140
|
|
|
188
|
-
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
# Case 2: Label matches a section title
|
|
201
|
-
# Input: C1@Section -> path="C1.html", section "Section" exists
|
|
202
|
-
# Output: C1.html#section (uses section.aref for GitHub-style)
|
|
203
|
-
elsif (section = ref&.sections&.find { |s| decoded_label == s.title })
|
|
204
|
-
path << "##{section.aref}"
|
|
205
|
-
|
|
206
|
-
# Case 3: Ref has an aref (class/module context)
|
|
207
|
-
# Input: C1@heading -> path="C1.html", ref=C1 class
|
|
208
|
-
# Output: C1.html#class-c1-heading
|
|
209
|
-
elsif ref.respond_to?(:aref)
|
|
210
|
-
path << "##{ref.aref}-#{formatted_label}"
|
|
211
|
-
|
|
212
|
-
# Case 4: No context, just the label (e.g., TopLevel/file)
|
|
213
|
-
# Input: README@section -> path="README_md.html"
|
|
214
|
-
# Output: README_md.html#section
|
|
215
|
-
else
|
|
216
|
-
path << "##{formatted_label}"
|
|
141
|
+
##
|
|
142
|
+
# Generates links for <tt>rdoc-ref:</tt> scheme URLs and allows
|
|
143
|
+
# RDoc::Markup::ToHtml to handle other schemes.
|
|
144
|
+
|
|
145
|
+
def gen_url(url, text)
|
|
146
|
+
if url =~ /\Ardoc-ref:/
|
|
147
|
+
name = $'
|
|
148
|
+
cross_reference(name, text, name == text, rdoc_ref: true) || text
|
|
149
|
+
else
|
|
150
|
+
super
|
|
151
|
+
end
|
|
217
152
|
end
|
|
218
|
-
end
|
|
219
153
|
|
|
220
|
-
|
|
221
|
-
|
|
154
|
+
##
|
|
155
|
+
# Creates an HTML link to +name+ with the given +html_string+.
|
|
156
|
+
# +html_string+ should be already escaped and may contain HTML tags.
|
|
157
|
+
# Returns the link HTML string, or +nil+ if the reference could not be resolved.
|
|
158
|
+
|
|
159
|
+
def link(name, html_string, code = true, rdoc_ref: false)
|
|
160
|
+
if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/
|
|
161
|
+
name = $1
|
|
162
|
+
label = $'
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
ref = @cross_reference.resolve name if name
|
|
166
|
+
|
|
167
|
+
# Non-text source files (C, Ruby, etc.) don't get HTML pages generated,
|
|
168
|
+
# so don't auto-link to them. Explicit rdoc-ref: links are still allowed.
|
|
169
|
+
if !rdoc_ref && TopLevel === ref && !ref.text?
|
|
170
|
+
return
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if ref
|
|
174
|
+
path = ref.as_href(@from_path)
|
|
175
|
+
|
|
176
|
+
if code and CodeObject === ref and !(TopLevel === ref)
|
|
177
|
+
html_string = "<code>#{html_string}</code>"
|
|
178
|
+
end
|
|
179
|
+
elsif name
|
|
180
|
+
if rdoc_ref && @warn_missing_rdoc_ref
|
|
181
|
+
puts "#{@from_path}: `rdoc-ref:#{name}` can't be resolved for `#{html_string}`"
|
|
182
|
+
end
|
|
183
|
+
return
|
|
184
|
+
else
|
|
185
|
+
# A bare label reference like @foo still produces a valid anchor link
|
|
186
|
+
return unless label
|
|
187
|
+
path = +""
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if label
|
|
191
|
+
# Decode legacy labels (e.g., "What-27s+Here" -> "What's Here")
|
|
192
|
+
# then convert to GitHub-style anchor format
|
|
193
|
+
decoded_label = Text.decode_legacy_label(label)
|
|
194
|
+
formatted_label = Text.to_anchor(decoded_label)
|
|
195
|
+
|
|
196
|
+
# Case 1: Path already has an anchor (e.g., method link)
|
|
197
|
+
# Input: C1#method@label -> path="C1.html#method-i-m"
|
|
198
|
+
# Output: C1.html#method-i-m-label
|
|
199
|
+
if path =~ /#/
|
|
200
|
+
path << "-#{formatted_label}"
|
|
201
|
+
|
|
202
|
+
# Case 2: Label matches a section title
|
|
203
|
+
# Input: C1@Section -> path="C1.html", section "Section" exists
|
|
204
|
+
# Output: C1.html#section (uses section.aref for GitHub-style)
|
|
205
|
+
elsif (section = ref&.sections&.find { |s| decoded_label == s.title })
|
|
206
|
+
path << "##{section.aref}"
|
|
207
|
+
|
|
208
|
+
# Case 3: Ref has an aref (class/module context)
|
|
209
|
+
# Input: C1@heading -> path="C1.html", ref=C1 class
|
|
210
|
+
# Output: C1.html#class-c1-heading
|
|
211
|
+
elsif ref.respond_to?(:aref)
|
|
212
|
+
path << "##{ref.aref}-#{formatted_label}"
|
|
213
|
+
|
|
214
|
+
# Case 4: No context, just the label (e.g., TopLevel/file)
|
|
215
|
+
# Input: README@section -> path="README_md.html"
|
|
216
|
+
# Output: README_md.html#section
|
|
217
|
+
else
|
|
218
|
+
path << "##{formatted_label}"
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
"<a href=\"#{path}\">#{html_string}</a>"
|
|
223
|
+
end
|
|
222
224
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
def handle_TT(code)
|
|
226
|
+
emit_inline(tt_cross_reference(code) || "<code>#{convert_string(code)}</code>")
|
|
227
|
+
end
|
|
226
228
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
229
|
+
# Applies additional special handling on top of the one defined in ToHtml.
|
|
230
|
+
# When a tidy link is <tt>{Foo}[rdoc-ref:Foo]</tt>, the label part is surrounded by <tt><code></code></tt>.
|
|
231
|
+
# TODO: reconsider this workaround.
|
|
232
|
+
def apply_tidylink_label_special_handling(label, url)
|
|
233
|
+
if url == "rdoc-ref:#{label}" && cross_reference(label)&.include?('<code>')
|
|
234
|
+
"<code>#{convert_string(label)}</code>"
|
|
235
|
+
else
|
|
236
|
+
super
|
|
237
|
+
end
|
|
238
|
+
end
|
|
237
239
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
240
|
+
# Handles cross-reference and suppressed-crossref inside tt tag.
|
|
241
|
+
# Returns nil if code is not an existing cross-reference nor a suppressed-crossref.
|
|
242
|
+
def tt_cross_reference(code)
|
|
243
|
+
return if in_tidylink_label?
|
|
244
|
+
|
|
245
|
+
crossref_regexp = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
246
|
+
# REGEXP sometimes matches a string that starts with a backslash but is not a
|
|
247
|
+
# suppressed cross-reference (for example, `\+`), so the backslash-removed
|
|
248
|
+
# part needs to be checked against crossref_regexp.
|
|
249
|
+
match = crossref_regexp.match(code.delete_prefix('\\'))
|
|
250
|
+
return unless match && match.begin(1).zero?
|
|
251
|
+
return unless match.post_match.match?(/\A[[:punct:]\s]*\z/)
|
|
252
|
+
|
|
253
|
+
# cross_reference(file_page) may return a link without code tag.
|
|
254
|
+
# We need to check it because this method shouldn't return an html text without code tag.
|
|
255
|
+
if code.start_with?('\\')
|
|
256
|
+
# Remove leading backslash if crossref exists
|
|
257
|
+
"<code>#{convert_string(code[1..])}</code>" if cross_reference(code[1..])&.include?('<code>')
|
|
258
|
+
else
|
|
259
|
+
html = cross_reference(code)
|
|
260
|
+
html if html&.include?('<code>')
|
|
261
|
+
end
|
|
262
|
+
end
|
|
259
263
|
end
|
|
260
264
|
end
|
|
261
265
|
end
|