rdoc 7.1.0 → 8.0.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 +3 -4
- data/LICENSE.rdoc +4 -0
- data/README.md +43 -2
- data/doc/markup_reference/markdown.md +104 -3
- data/lib/rdoc/code_object/alias.rb +2 -8
- data/lib/rdoc/code_object/any_method.rb +11 -6
- data/lib/rdoc/code_object/attr.rb +12 -6
- data/lib/rdoc/code_object/class_module.rb +62 -32
- data/lib/rdoc/code_object/constant.rb +29 -3
- data/lib/rdoc/code_object/context/section.rb +30 -43
- data/lib/rdoc/code_object/context.rb +53 -37
- data/lib/rdoc/code_object/method_attr.rb +9 -15
- data/lib/rdoc/code_object/mixin.rb +3 -0
- data/lib/rdoc/code_object/top_level.rb +11 -3
- data/lib/rdoc/code_object.rb +2 -4
- data/lib/rdoc/comment.rb +1 -66
- data/lib/rdoc/cross_reference.rb +8 -30
- data/lib/rdoc/encoding.rb +3 -3
- data/lib/rdoc/generator/aliki.rb +17 -0
- data/lib/rdoc/generator/darkfish.rb +12 -6
- data/lib/rdoc/generator/json_index.rb +2 -2
- data/lib/rdoc/generator/markup.rb +56 -31
- data/lib/rdoc/generator/template/aliki/DESIGN.md +536 -0
- data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +6 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
- data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/class.rhtml +61 -51
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +365 -147
- data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/js/aliki.js +28 -20
- data/lib/rdoc/generator/template/aliki/js/bash_highlighter.js +167 -0
- data/lib/rdoc/generator/template/aliki/js/search_controller.js +1 -1
- data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
- data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
- data/lib/rdoc/i18n/text.rb +3 -3
- data/lib/rdoc/markdown.kpeg +36 -17
- data/lib/rdoc/markdown.rb +324 -125
- data/lib/rdoc/markup/document.rb +2 -2
- data/lib/rdoc/markup/formatter.rb +128 -115
- data/lib/rdoc/markup/heading.rb +3 -6
- data/lib/rdoc/markup/indented_paragraph.rb +1 -1
- data/lib/rdoc/markup/inline_parser.rb +312 -0
- data/lib/rdoc/markup/list.rb +2 -2
- data/lib/rdoc/markup/list_item.rb +2 -2
- data/lib/rdoc/markup/parser.rb +1 -1
- data/lib/rdoc/markup/pre_process.rb +0 -25
- data/lib/rdoc/markup/to_ansi.rb +52 -5
- data/lib/rdoc/markup/to_bs.rb +23 -43
- data/lib/rdoc/markup/to_html.rb +279 -226
- data/lib/rdoc/markup/to_html_crossref.rb +122 -136
- data/lib/rdoc/markup/to_html_snippet.rb +65 -65
- data/lib/rdoc/markup/to_joined_paragraph.rb +0 -5
- data/lib/rdoc/markup/to_label.rb +22 -23
- data/lib/rdoc/markup/to_markdown.rb +62 -38
- data/lib/rdoc/markup/to_rdoc.rb +88 -28
- data/lib/rdoc/markup/to_table_of_contents.rb +1 -1
- data/lib/rdoc/markup/to_test.rb +9 -1
- data/lib/rdoc/markup/to_tt_only.rb +10 -23
- data/lib/rdoc/markup/verbatim.rb +1 -1
- data/lib/rdoc/markup.rb +8 -30
- data/lib/rdoc/options.rb +36 -51
- data/lib/rdoc/parser/c.rb +7 -6
- data/lib/rdoc/parser/changelog.rb +21 -0
- data/lib/rdoc/parser/rbs.rb +275 -0
- data/lib/rdoc/parser/ruby.rb +955 -2067
- data/lib/rdoc/parser/ruby_colorizer.rb +253 -0
- data/lib/rdoc/parser.rb +3 -2
- data/lib/rdoc/rbs_helper.rb +186 -0
- data/lib/rdoc/rdoc.rb +196 -24
- data/lib/rdoc/ri/driver.rb +8 -2
- data/lib/rdoc/ri/paths.rb +1 -1
- data/lib/rdoc/{servlet.rb → ri/servlet.rb} +5 -5
- data/lib/rdoc/ri.rb +4 -3
- data/lib/rdoc/rubygems_hook.rb +11 -11
- data/lib/rdoc/server.rb +460 -0
- data/lib/rdoc/stats.rb +147 -124
- data/lib/rdoc/store.rb +212 -4
- data/lib/rdoc/task.rb +16 -15
- data/lib/rdoc/text.rb +24 -117
- data/lib/rdoc/token_stream.rb +11 -33
- data/lib/rdoc/version.rb +1 -1
- data/lib/rdoc.rb +35 -7
- data/lib/rubygems_plugin.rb +2 -11
- data/rdoc-logo.svg +43 -0
- data/rdoc.gemspec +6 -4
- metadata +37 -23
- data/lib/rdoc/code_object/anon_class.rb +0 -10
- data/lib/rdoc/code_object/ghost_method.rb +0 -6
- data/lib/rdoc/code_object/meta_method.rb +0 -6
- data/lib/rdoc/markup/attr_changer.rb +0 -22
- data/lib/rdoc/markup/attr_span.rb +0 -35
- data/lib/rdoc/markup/attribute_manager.rb +0 -432
- data/lib/rdoc/markup/attributes.rb +0 -70
- data/lib/rdoc/markup/regexp_handling.rb +0 -40
- data/lib/rdoc/parser/prism_ruby.rb +0 -1100
- data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
- data/lib/rdoc/parser/ruby_tools.rb +0 -163
|
@@ -8,9 +8,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
8
8
|
|
|
9
9
|
# :stopdoc:
|
|
10
10
|
ALL_CROSSREF_REGEXP = RDoc::CrossReference::ALL_CROSSREF_REGEXP
|
|
11
|
-
CLASS_REGEXP_STR = RDoc::CrossReference::CLASS_REGEXP_STR
|
|
12
11
|
CROSSREF_REGEXP = RDoc::CrossReference::CROSSREF_REGEXP
|
|
13
|
-
METHOD_REGEXP_STR = RDoc::CrossReference::METHOD_REGEXP_STR
|
|
14
12
|
# :startdoc:
|
|
15
13
|
|
|
16
14
|
##
|
|
@@ -29,15 +27,19 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
29
27
|
# references are removed unless +show_hash+ is true. Only method names
|
|
30
28
|
# preceded by '#' or '::' are linked, unless +hyperlink_all+ is true.
|
|
31
29
|
|
|
32
|
-
def initialize(
|
|
30
|
+
def initialize(from_path, context, pipe: false, output_decoration: true,
|
|
31
|
+
hyperlink_all: false, show_hash: false,
|
|
32
|
+
autolink_excluded_words: [], warn_missing_rdoc_ref: true)
|
|
33
33
|
raise ArgumentError, 'from_path cannot be nil' if from_path.nil?
|
|
34
34
|
|
|
35
|
-
super
|
|
35
|
+
super(pipe: pipe, output_decoration: output_decoration)
|
|
36
36
|
|
|
37
37
|
@context = context
|
|
38
38
|
@from_path = from_path
|
|
39
|
-
@hyperlink_all =
|
|
40
|
-
@show_hash =
|
|
39
|
+
@hyperlink_all = hyperlink_all
|
|
40
|
+
@show_hash = show_hash
|
|
41
|
+
@autolink_excluded_words = autolink_excluded_words
|
|
42
|
+
@warn_missing_rdoc_ref = warn_missing_rdoc_ref
|
|
41
43
|
|
|
42
44
|
@cross_reference = RDoc::CrossReference.new @context
|
|
43
45
|
end
|
|
@@ -48,29 +50,30 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
48
50
|
|
|
49
51
|
# The crossref must be linked before tidylink because Klass.method[:sym]
|
|
50
52
|
# will be processed as a tidylink first and will be broken.
|
|
51
|
-
crossref_re = @
|
|
53
|
+
crossref_re = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
52
54
|
@markup.add_regexp_handling crossref_re, :CROSSREF
|
|
53
|
-
|
|
54
|
-
add_regexp_handling_TIDYLINK
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
##
|
|
58
58
|
# Creates a link to the reference +name+ if the name exists. If +text+ is
|
|
59
59
|
# given it is used as the link text, otherwise +name+ is used.
|
|
60
|
+
# Returns +nil+ if the link target could not be resolved.
|
|
60
61
|
|
|
61
62
|
def cross_reference(name, text = nil, code = true, rdoc_ref: false)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
|
68
71
|
code = false
|
|
69
72
|
else
|
|
70
|
-
text ||=
|
|
73
|
+
text ||= convert_string(display)
|
|
71
74
|
end
|
|
72
75
|
|
|
73
|
-
link
|
|
76
|
+
link(name, text, code, rdoc_ref: rdoc_ref)
|
|
74
77
|
end
|
|
75
78
|
|
|
76
79
|
##
|
|
@@ -80,10 +83,9 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
80
83
|
# example, ToHtml is found, even without the <tt>RDoc::Markup::</tt> prefix,
|
|
81
84
|
# because we look for it in module Markup first.
|
|
82
85
|
|
|
83
|
-
def handle_regexp_CROSSREF(
|
|
84
|
-
name
|
|
85
|
-
|
|
86
|
-
return name if @options.autolink_excluded_words&.include?(name)
|
|
86
|
+
def handle_regexp_CROSSREF(name)
|
|
87
|
+
return convert_string(name) if in_tidylink_label?
|
|
88
|
+
return name if @autolink_excluded_words&.include?(name)
|
|
87
89
|
|
|
88
90
|
return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails
|
|
89
91
|
|
|
@@ -93,20 +95,20 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
93
95
|
# cross-references to "new" in text, for instance)
|
|
94
96
|
return name if name =~ /\A[a-z]*\z/
|
|
95
97
|
end
|
|
96
|
-
|
|
97
|
-
cross_reference name, rdoc_ref: false
|
|
98
|
+
cross_reference(name, rdoc_ref: false) || convert_string(name)
|
|
98
99
|
end
|
|
99
100
|
|
|
100
101
|
##
|
|
101
102
|
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
|
|
102
103
|
# handle other schemes.
|
|
103
104
|
|
|
104
|
-
def handle_regexp_HYPERLINK(
|
|
105
|
-
url
|
|
105
|
+
def handle_regexp_HYPERLINK(url)
|
|
106
|
+
return convert_string(url) if in_tidylink_label?
|
|
106
107
|
|
|
107
108
|
case url
|
|
108
109
|
when /\Ardoc-ref:/
|
|
109
|
-
|
|
110
|
+
ref = $'
|
|
111
|
+
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
110
112
|
else
|
|
111
113
|
super
|
|
112
114
|
end
|
|
@@ -120,12 +122,15 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
120
122
|
# All other contents are handled by
|
|
121
123
|
# {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK]
|
|
122
124
|
|
|
123
|
-
def handle_regexp_RDOCLINK(
|
|
124
|
-
url = target.text
|
|
125
|
-
|
|
125
|
+
def handle_regexp_RDOCLINK(url)
|
|
126
126
|
case url
|
|
127
127
|
when /\Ardoc-ref:/
|
|
128
|
-
|
|
128
|
+
if in_tidylink_label?
|
|
129
|
+
convert_string(url)
|
|
130
|
+
else
|
|
131
|
+
ref = $'
|
|
132
|
+
cross_reference(ref, rdoc_ref: true) || convert_string(ref)
|
|
133
|
+
end
|
|
129
134
|
else
|
|
130
135
|
super
|
|
131
136
|
end
|
|
@@ -138,138 +143,119 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
138
143
|
def gen_url(url, text)
|
|
139
144
|
if url =~ /\Ardoc-ref:/
|
|
140
145
|
name = $'
|
|
141
|
-
cross_reference
|
|
146
|
+
cross_reference(name, text, name == text, rdoc_ref: true) || text
|
|
142
147
|
else
|
|
143
148
|
super
|
|
144
149
|
end
|
|
145
150
|
end
|
|
146
151
|
|
|
147
152
|
##
|
|
148
|
-
# Creates an HTML link to +name+ with the given +
|
|
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.
|
|
149
156
|
|
|
150
|
-
def link(name,
|
|
157
|
+
def link(name, html_string, code = true, rdoc_ref: false)
|
|
151
158
|
if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/
|
|
152
159
|
name = $1
|
|
153
160
|
label = $'
|
|
154
161
|
end
|
|
155
162
|
|
|
156
|
-
ref = @cross_reference.resolve name
|
|
163
|
+
ref = @cross_reference.resolve name if name
|
|
157
164
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
path = ref
|
|
165
|
+
# Non-text source files (C, Ruby, etc.) don't get HTML pages generated,
|
|
166
|
+
# so don't auto-link to them. Explicit rdoc-ref: links are still allowed.
|
|
167
|
+
if !rdoc_ref && RDoc::TopLevel === ref && !ref.text?
|
|
168
|
+
return
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
if ref
|
|
172
|
+
path = ref.as_href(@from_path)
|
|
166
173
|
|
|
167
174
|
if code and RDoc::CodeObject === ref and !(RDoc::TopLevel === ref)
|
|
168
|
-
|
|
175
|
+
html_string = "<code>#{html_string}</code>"
|
|
169
176
|
end
|
|
170
|
-
|
|
171
|
-
if
|
|
172
|
-
#
|
|
173
|
-
# First convert + to space (URL encoding), then apply GitHub-style rules
|
|
174
|
-
formatted_label = RDoc::Text.to_anchor(label.tr('+', ' '))
|
|
175
|
-
|
|
176
|
-
# Case 1: Path already has an anchor (e.g., method link)
|
|
177
|
-
# Input: C1#method@label -> path="C1.html#method-i-m"
|
|
178
|
-
# Output: C1.html#method-i-m-label
|
|
179
|
-
if path =~ /#/
|
|
180
|
-
path << "-#{formatted_label}"
|
|
181
|
-
|
|
182
|
-
# Case 2: Label matches a section title
|
|
183
|
-
# Input: C1@Section -> path="C1.html", section "Section" exists
|
|
184
|
-
# Output: C1.html#section (uses section.aref for GitHub-style)
|
|
185
|
-
elsif (section = ref&.sections&.find { |s| label.tr('+', ' ') == s.title })
|
|
186
|
-
path << "##{section.aref}"
|
|
187
|
-
|
|
188
|
-
# Case 3: Ref has an aref (class/module context)
|
|
189
|
-
# Input: C1@heading -> path="C1.html", ref=C1 class
|
|
190
|
-
# Output: C1.html#class-c1-heading
|
|
191
|
-
elsif ref.respond_to?(:aref)
|
|
192
|
-
path << "##{ref.aref}-#{formatted_label}"
|
|
193
|
-
|
|
194
|
-
# Case 4: No context, just the label (e.g., TopLevel/file)
|
|
195
|
-
# Input: README@section -> path="README_md.html"
|
|
196
|
-
# Output: README_md.html#section
|
|
197
|
-
else
|
|
198
|
-
path << "##{formatted_label}"
|
|
199
|
-
end
|
|
177
|
+
elsif name
|
|
178
|
+
if rdoc_ref && @warn_missing_rdoc_ref
|
|
179
|
+
puts "#{@from_path}: `rdoc-ref:#{name}` can't be resolved for `#{html_string}`"
|
|
200
180
|
end
|
|
201
|
-
|
|
202
|
-
|
|
181
|
+
return
|
|
182
|
+
else
|
|
183
|
+
# A bare label reference like @foo still produces a valid anchor link
|
|
184
|
+
return unless label
|
|
185
|
+
path = +""
|
|
203
186
|
end
|
|
204
|
-
end
|
|
205
187
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
append_flow_fragment res, text
|
|
234
|
-
i += 1
|
|
188
|
+
if label
|
|
189
|
+
# Decode legacy labels (e.g., "What-27s+Here" -> "What's Here")
|
|
190
|
+
# then convert to GitHub-style anchor format
|
|
191
|
+
decoded_label = RDoc::Text.decode_legacy_label(label)
|
|
192
|
+
formatted_label = RDoc::Text.to_anchor(decoded_label)
|
|
193
|
+
|
|
194
|
+
# Case 1: Path already has an anchor (e.g., method link)
|
|
195
|
+
# Input: C1#method@label -> path="C1.html#method-i-m"
|
|
196
|
+
# Output: C1.html#method-i-m-label
|
|
197
|
+
if path =~ /#/
|
|
198
|
+
path << "-#{formatted_label}"
|
|
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
|
|
235
215
|
else
|
|
236
|
-
|
|
216
|
+
path << "##{formatted_label}"
|
|
237
217
|
end
|
|
238
218
|
end
|
|
239
219
|
|
|
240
|
-
|
|
220
|
+
"<a href=\"#{path}\">#{html_string}</a>"
|
|
241
221
|
end
|
|
242
222
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# Detects <tt>...</tt> spans that contain a single cross-reference candidate.
|
|
247
|
-
# When the candidate occupies the whole span (aside from trailing
|
|
248
|
-
# punctuation), the tt markup is replaced by the resolved cross-reference.
|
|
249
|
-
|
|
250
|
-
def convert_tt_crossref(flow_items, index)
|
|
251
|
-
opener = flow_items[index]
|
|
252
|
-
return unless tt_tag?(opener.turn_on)
|
|
253
|
-
|
|
254
|
-
string = flow_items[index + 1]
|
|
255
|
-
closer = flow_items[index + 2]
|
|
256
|
-
|
|
257
|
-
return unless String === string
|
|
258
|
-
return unless RDoc::Markup::AttrChanger === closer
|
|
259
|
-
return unless tt_tag?(closer.turn_off, true)
|
|
260
|
-
|
|
261
|
-
crossref_regexp = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
262
|
-
match = crossref_regexp.match(string)
|
|
263
|
-
return unless match
|
|
264
|
-
return unless match.begin(1).zero?
|
|
265
|
-
|
|
266
|
-
trailing = match.post_match
|
|
267
|
-
# Only convert when the remainder is punctuation/whitespace so other tt text stays literal.
|
|
268
|
-
return unless trailing.match?(/\A[[:punct:]\s]*\z/)
|
|
223
|
+
def handle_TT(code)
|
|
224
|
+
emit_inline(tt_cross_reference(code) || "<code>#{convert_string(code)}</code>")
|
|
225
|
+
end
|
|
269
226
|
|
|
270
|
-
|
|
271
|
-
|
|
227
|
+
# Applies additional special handling on top of the one defined in ToHtml.
|
|
228
|
+
# When a tidy link is <tt>{Foo}[rdoc-ref:Foo]</tt>, the label part is surrounded by <tt><code></code></tt>.
|
|
229
|
+
# TODO: reconsider this workaround.
|
|
230
|
+
def apply_tidylink_label_special_handling(label, url)
|
|
231
|
+
if url == "rdoc-ref:#{label}" && cross_reference(label)&.include?('<code>')
|
|
232
|
+
"<code>#{convert_string(label)}</code>"
|
|
233
|
+
else
|
|
234
|
+
super
|
|
235
|
+
end
|
|
236
|
+
end
|
|
272
237
|
|
|
273
|
-
|
|
238
|
+
# Handles cross-reference and suppressed-crossref inside tt tag.
|
|
239
|
+
# Returns nil if code is not an existing cross-reference nor a suppressed-crossref.
|
|
240
|
+
def tt_cross_reference(code)
|
|
241
|
+
return if in_tidylink_label?
|
|
242
|
+
|
|
243
|
+
crossref_regexp = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
|
244
|
+
# REGEXP sometimes matches a string that starts with a backslash but is not a
|
|
245
|
+
# suppressed cross-reference (for example, `\+`), so the backslash-removed
|
|
246
|
+
# part needs to be checked against crossref_regexp.
|
|
247
|
+
match = crossref_regexp.match(code.delete_prefix('\\'))
|
|
248
|
+
return unless match && match.begin(1).zero?
|
|
249
|
+
return unless match.post_match.match?(/\A[[:punct:]\s]*\z/)
|
|
250
|
+
|
|
251
|
+
# cross_reference(file_page) may return a link without code tag.
|
|
252
|
+
# We need to check it because this method shouldn't return an html text without code tag.
|
|
253
|
+
if code.start_with?('\\')
|
|
254
|
+
# Remove leading backslash if crossref exists
|
|
255
|
+
"<code>#{convert_string(code[1..])}</code>" if cross_reference(code[1..])&.include?('<code>')
|
|
256
|
+
else
|
|
257
|
+
html = cross_reference(code)
|
|
258
|
+
html if html&.include?('<code>')
|
|
259
|
+
end
|
|
274
260
|
end
|
|
275
261
|
end
|
|
@@ -34,8 +34,8 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
|
|
|
34
34
|
# next word boundary after the given number of +characters+ or +paragraphs+
|
|
35
35
|
# of text have been encountered.
|
|
36
36
|
|
|
37
|
-
def initialize(
|
|
38
|
-
super
|
|
37
|
+
def initialize(characters = 100, paragraphs = 3)
|
|
38
|
+
super()
|
|
39
39
|
|
|
40
40
|
@character_limit = characters
|
|
41
41
|
@paragraph_limit = paragraphs
|
|
@@ -107,9 +107,9 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
|
|
|
107
107
|
def accept_verbatim(verbatim)
|
|
108
108
|
throw :done if @characters >= @character_limit
|
|
109
109
|
input = verbatim.text.rstrip
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
text <<
|
|
110
|
+
text = truncate(input, @character_limit - @characters)
|
|
111
|
+
@characters += input.length
|
|
112
|
+
text << " #{TO_HTML_CHARACTERS[text.encoding][:ellipsis]}" unless text == input
|
|
113
113
|
|
|
114
114
|
super RDoc::Markup::Verbatim.new text
|
|
115
115
|
|
|
@@ -128,16 +128,8 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
|
|
|
128
128
|
##
|
|
129
129
|
# Removes escaping from the cross-references in +target+
|
|
130
130
|
|
|
131
|
-
def handle_regexp_CROSSREF(
|
|
132
|
-
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
##
|
|
136
|
-
# +target+ is a <code><br></code>
|
|
137
|
-
|
|
138
|
-
def handle_regexp_HARD_BREAK(target)
|
|
139
|
-
@characters -= 4
|
|
140
|
-
'<br>'
|
|
131
|
+
def handle_regexp_CROSSREF(text)
|
|
132
|
+
text.sub(/\A\\/, '')
|
|
141
133
|
end
|
|
142
134
|
|
|
143
135
|
##
|
|
@@ -212,74 +204,82 @@ class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml
|
|
|
212
204
|
end_accepting
|
|
213
205
|
end
|
|
214
206
|
|
|
215
|
-
|
|
216
|
-
|
|
207
|
+
def handle_PLAIN_TEXT(text) # :nodoc:
|
|
208
|
+
return if inline_limit_reached?
|
|
217
209
|
|
|
218
|
-
|
|
219
|
-
|
|
210
|
+
truncated = truncate(text, @inline_character_limit)
|
|
211
|
+
@inline_character_limit -= text.size
|
|
212
|
+
emit_inline(convert_string(truncated))
|
|
213
|
+
end
|
|
220
214
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
flow.each do |item|
|
|
225
|
-
case item
|
|
226
|
-
when RDoc::Markup::AttrChanger then
|
|
227
|
-
off_tags res, item
|
|
228
|
-
on_tags res, item
|
|
229
|
-
when String then
|
|
230
|
-
text = convert_string item
|
|
231
|
-
res << truncate(text)
|
|
232
|
-
when RDoc::Markup::RegexpHandling then
|
|
233
|
-
text = convert_regexp_handling item
|
|
234
|
-
res << truncate(text)
|
|
235
|
-
else
|
|
236
|
-
raise "Unknown flow element: #{item.inspect}"
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
if @characters >= @character_limit then
|
|
240
|
-
off_tags res, RDoc::Markup::AttrChanger.new(0, @mask)
|
|
241
|
-
break
|
|
242
|
-
end
|
|
243
|
-
end
|
|
215
|
+
def handle_REGEXP_HANDLING_TEXT(text) # :nodoc:
|
|
216
|
+
return if inline_limit_reached?
|
|
244
217
|
|
|
245
|
-
|
|
218
|
+
# We can't truncate text including html tags.
|
|
219
|
+
# Just emit as is, and count all characters including html tag part.
|
|
220
|
+
emit_inline(text)
|
|
221
|
+
@inline_character_limit -= text.size
|
|
222
|
+
end
|
|
246
223
|
|
|
247
|
-
|
|
224
|
+
def handle_BOLD(nodes)
|
|
225
|
+
super unless inline_limit_reached?
|
|
248
226
|
end
|
|
249
227
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
228
|
+
def handle_BOLD_WORD(word)
|
|
229
|
+
super unless inline_limit_reached?
|
|
230
|
+
end
|
|
253
231
|
|
|
254
|
-
def
|
|
255
|
-
|
|
232
|
+
def handle_EM(nodes)
|
|
233
|
+
super unless inline_limit_reached?
|
|
234
|
+
end
|
|
256
235
|
|
|
257
|
-
|
|
236
|
+
def handle_EM_WORD(word)
|
|
237
|
+
super unless inline_limit_reached?
|
|
258
238
|
end
|
|
259
239
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
240
|
+
def handle_TT(code)
|
|
241
|
+
super unless inline_limit_reached?
|
|
242
|
+
end
|
|
263
243
|
|
|
264
|
-
def
|
|
265
|
-
|
|
244
|
+
def handle_STRIKE(nodes)
|
|
245
|
+
super unless inline_limit_reached?
|
|
246
|
+
end
|
|
266
247
|
|
|
267
|
-
|
|
248
|
+
def handle_HARD_BREAK
|
|
249
|
+
super unless inline_limit_reached?
|
|
268
250
|
end
|
|
269
251
|
|
|
270
|
-
|
|
271
|
-
|
|
252
|
+
def handle_TIDYLINK(label_part, url)
|
|
253
|
+
traverse_inline_nodes(label_part) unless inline_limit_reached?
|
|
254
|
+
end
|
|
272
255
|
|
|
273
|
-
def
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
@characters += length
|
|
256
|
+
def inline_limit_reached?
|
|
257
|
+
@inline_character_limit <= 0
|
|
258
|
+
end
|
|
277
259
|
|
|
278
|
-
|
|
260
|
+
def handle_inline(text)
|
|
261
|
+
limit = @character_limit - @characters
|
|
262
|
+
return ['', 0] if limit <= 0
|
|
263
|
+
@inline_character_limit = limit
|
|
264
|
+
res = super
|
|
265
|
+
res << " #{TO_HTML_CHARACTERS[text.encoding][:ellipsis]}" if @inline_character_limit <= 0
|
|
266
|
+
@characters += limit - @inline_character_limit
|
|
267
|
+
res
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def to_html(item)
|
|
271
|
+
throw :done if @characters >= @character_limit
|
|
272
|
+
handle_inline(item)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
##
|
|
276
|
+
# Truncates +text+ at the end of the first word after the limit.
|
|
279
277
|
|
|
280
|
-
|
|
278
|
+
def truncate(text, limit)
|
|
279
|
+
return text if limit >= text.size
|
|
280
|
+
return '' if limit <= 0
|
|
281
281
|
|
|
282
|
-
text =~ /\A(.{#{
|
|
282
|
+
text =~ /\A(.{#{limit},}?)(\s|$)/m # TODO word-break instead of \s?
|
|
283
283
|
|
|
284
284
|
$1
|
|
285
285
|
end
|
data/lib/rdoc/markup/to_label.rb
CHANGED
|
@@ -14,24 +14,37 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
|
|
|
14
14
|
##
|
|
15
15
|
# Creates a new formatter that will output HTML-safe labels
|
|
16
16
|
|
|
17
|
-
def initialize
|
|
18
|
-
super
|
|
17
|
+
def initialize
|
|
18
|
+
super
|
|
19
19
|
|
|
20
20
|
@markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF
|
|
21
|
-
@markup.add_regexp_handling(/(((\{.*?\})|\b\S+?)\[\S+?\])/, :TIDYLINK)
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
@res = []
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def handle_PLAIN_TEXT(text)
|
|
26
|
+
@res << text
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def handle_REGEXP_HANDLING_TEXT(text)
|
|
30
|
+
@res << text
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def handle_TT(text)
|
|
34
|
+
@res << text
|
|
35
|
+
end
|
|
26
36
|
|
|
37
|
+
def extract_plaintext(text)
|
|
27
38
|
@res = []
|
|
39
|
+
handle_inline(text)
|
|
40
|
+
@res.join
|
|
28
41
|
end
|
|
29
42
|
|
|
30
43
|
##
|
|
31
44
|
# Converts +text+ to an HTML-safe label using GitHub-style anchor formatting.
|
|
32
45
|
|
|
33
46
|
def convert(text)
|
|
34
|
-
label =
|
|
47
|
+
label = extract_plaintext(text)
|
|
35
48
|
|
|
36
49
|
RDoc::Text.to_anchor(label)
|
|
37
50
|
end
|
|
@@ -41,7 +54,7 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
|
|
|
41
54
|
# Used for generating backward-compatible anchor aliases.
|
|
42
55
|
|
|
43
56
|
def convert_legacy(text)
|
|
44
|
-
label =
|
|
57
|
+
label = extract_plaintext(text)
|
|
45
58
|
|
|
46
59
|
CGI.escape(label).gsub('%', '-').sub(/^-/, '')
|
|
47
60
|
end
|
|
@@ -50,23 +63,10 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
|
|
|
50
63
|
# Converts the CROSSREF +target+ to plain text, removing the suppression
|
|
51
64
|
# marker, if any
|
|
52
65
|
|
|
53
|
-
def handle_regexp_CROSSREF(
|
|
54
|
-
text = target.text
|
|
55
|
-
|
|
66
|
+
def handle_regexp_CROSSREF(text)
|
|
56
67
|
text.sub(/^\\/, '')
|
|
57
68
|
end
|
|
58
69
|
|
|
59
|
-
##
|
|
60
|
-
# Converts the TIDYLINK +target+ to just the text part
|
|
61
|
-
|
|
62
|
-
def handle_regexp_TIDYLINK(target)
|
|
63
|
-
text = target.text
|
|
64
|
-
|
|
65
|
-
return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/
|
|
66
|
-
|
|
67
|
-
$1
|
|
68
|
-
end
|
|
69
|
-
|
|
70
70
|
alias accept_blank_line ignore
|
|
71
71
|
alias accept_block_quote ignore
|
|
72
72
|
alias accept_heading ignore
|
|
@@ -79,7 +79,6 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
|
|
|
79
79
|
alias accept_rule ignore
|
|
80
80
|
alias accept_verbatim ignore
|
|
81
81
|
alias end_accepting ignore
|
|
82
|
-
alias handle_regexp_HARD_BREAK ignore
|
|
83
82
|
alias start_accepting ignore
|
|
84
83
|
|
|
85
84
|
end
|