rdoc 6.3.4.1 → 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 +195 -0
- data/History.rdoc +65 -63
- data/LEGAL.rdoc +7 -1
- data/LICENSE.rdoc +6 -0
- data/README.md +236 -0
- data/RI.md +842 -0
- data/TODO.rdoc +8 -7
- data/doc/markup_reference/markdown.md +659 -0
- data/doc/markup_reference/rdoc.rdoc +1169 -0
- data/exe/rdoc +0 -1
- data/lib/rdoc/{alias.rb → code_object/alias.rb} +4 -18
- data/lib/rdoc/{any_method.rb → code_object/any_method.rb} +50 -24
- data/lib/rdoc/{attr.rb → code_object/attr.rb} +16 -14
- data/lib/rdoc/{class_module.rb → code_object/class_module.rb} +225 -58
- data/lib/rdoc/{constant.rb → code_object/constant.rb} +44 -10
- data/lib/rdoc/code_object/context/section.rb +182 -0
- data/lib/rdoc/{context.rb → code_object/context.rb} +78 -106
- data/lib/rdoc/{extend.rb → code_object/extend.rb} +0 -1
- data/lib/rdoc/{include.rb → code_object/include.rb} +0 -1
- data/lib/rdoc/{method_attr.rb → code_object/method_attr.rb} +46 -48
- data/lib/rdoc/{mixin.rb → code_object/mixin.rb} +6 -4
- data/lib/rdoc/{normal_class.rb → code_object/normal_class.rb} +2 -3
- data/lib/rdoc/{normal_module.rb → code_object/normal_module.rb} +2 -3
- data/lib/rdoc/{require.rb → code_object/require.rb} +1 -2
- data/lib/rdoc/{single_class.rb → code_object/single_class.rb} +5 -1
- data/lib/rdoc/{top_level.rb → code_object/top_level.rb} +60 -63
- data/lib/rdoc/code_object.rb +11 -39
- data/lib/rdoc/code_objects.rb +1 -2
- data/lib/rdoc/comment.rb +202 -99
- data/lib/rdoc/cross_reference.rb +75 -62
- data/lib/rdoc/encoding.rb +8 -24
- data/lib/rdoc/erb_partial.rb +1 -2
- data/lib/rdoc/erbio.rb +3 -8
- data/lib/rdoc/generator/aliki.rb +200 -0
- data/lib/rdoc/generator/darkfish.rb +156 -122
- data/lib/rdoc/generator/json_index.rb +8 -24
- data/lib/rdoc/generator/markup.rb +70 -34
- data/lib/rdoc/generator/pot/message_extractor.rb +7 -7
- data/lib/rdoc/generator/pot/po.rb +1 -1
- data/lib/rdoc/generator/pot/po_entry.rb +8 -8
- data/lib/rdoc/generator/pot.rb +1 -5
- data/lib/rdoc/generator/ri.rb +1 -2
- data/lib/rdoc/generator/template/aliki/DESIGN.md +536 -0
- data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +8 -0
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +23 -0
- data/lib/rdoc/generator/template/aliki/_head.rhtml +163 -0
- data/lib/rdoc/generator/template/aliki/_header.rhtml +56 -0
- data/lib/rdoc/generator/template/aliki/_icons.rhtml +208 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_ancestors.rhtml +16 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_classes.rhtml +15 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +27 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +27 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +16 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_methods.rhtml +41 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +67 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +15 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +21 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +3 -0
- data/lib/rdoc/generator/template/aliki/class.rhtml +230 -0
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +2181 -0
- data/lib/rdoc/generator/template/aliki/index.rhtml +22 -0
- data/lib/rdoc/generator/template/aliki/js/aliki.js +513 -0
- data/lib/rdoc/generator/template/aliki/js/bash_highlighter.js +167 -0
- data/lib/rdoc/generator/template/aliki/js/c_highlighter.js +299 -0
- data/lib/rdoc/generator/template/aliki/js/search_controller.js +129 -0
- data/lib/rdoc/generator/template/aliki/js/search_navigation.js +105 -0
- data/lib/rdoc/generator/template/aliki/js/search_ranker.js +239 -0
- data/lib/rdoc/generator/template/aliki/js/theme-toggle.js +112 -0
- data/lib/rdoc/generator/template/aliki/page.rhtml +18 -0
- data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +14 -0
- data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +65 -0
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +3 -3
- data/lib/rdoc/generator/template/darkfish/_head.rhtml +35 -14
- data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +1 -5
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +11 -9
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +11 -9
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +7 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +20 -11
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +25 -5
- data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +4 -9
- data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +2 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +4 -4
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +28 -7
- data/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml +3 -0
- data/lib/rdoc/generator/template/darkfish/class.rhtml +138 -90
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +420 -358
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/index.rhtml +14 -12
- data/lib/rdoc/generator/template/darkfish/js/darkfish.js +59 -3
- data/lib/rdoc/generator/template/darkfish/js/search.js +15 -5
- data/lib/rdoc/generator/template/darkfish/page.rhtml +7 -6
- data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +12 -9
- data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +24 -21
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +35 -21
- data/lib/rdoc/generator/template/json_index/js/navigation.js +8 -8
- data/lib/rdoc/generator/template/json_index/js/searcher.js +48 -6
- data/lib/rdoc/generator.rb +6 -5
- data/lib/rdoc/i18n/text.rb +3 -3
- data/lib/rdoc/i18n.rb +1 -1
- data/lib/rdoc/known_classes.rb +5 -4
- data/lib/rdoc/markdown/entities.rb +0 -1
- data/lib/rdoc/markdown/literals.kpeg +0 -2
- data/lib/rdoc/markdown/literals.rb +0 -1
- data/lib/rdoc/markdown.kpeg +140 -62
- data/lib/rdoc/markdown.rb +1015 -873
- data/lib/rdoc/markup/blank_line.rb +25 -24
- data/lib/rdoc/markup/block_quote.rb +1 -2
- data/lib/rdoc/markup/document.rb +10 -11
- data/lib/rdoc/markup/element.rb +21 -0
- data/lib/rdoc/markup/formatter.rb +134 -115
- data/lib/rdoc/markup/hard_break.rb +30 -28
- data/lib/rdoc/markup/heading.rb +163 -72
- data/lib/rdoc/markup/include.rb +3 -4
- data/lib/rdoc/markup/indented_paragraph.rb +4 -5
- data/lib/rdoc/markup/inline_parser.rb +312 -0
- data/lib/rdoc/markup/list.rb +6 -7
- data/lib/rdoc/markup/list_item.rb +6 -7
- data/lib/rdoc/markup/paragraph.rb +2 -3
- data/lib/rdoc/markup/parser.rb +29 -19
- data/lib/rdoc/markup/pre_process.rb +39 -18
- data/lib/rdoc/markup/raw.rb +52 -56
- data/lib/rdoc/markup/rule.rb +2 -3
- data/lib/rdoc/markup/table.rb +49 -32
- data/lib/rdoc/markup/to_ansi.rb +58 -8
- data/lib/rdoc/markup/to_bs.rb +47 -38
- data/lib/rdoc/markup/to_html.rb +343 -105
- data/lib/rdoc/markup/to_html_crossref.rb +143 -58
- data/lib/rdoc/markup/to_html_snippet.rb +78 -76
- data/lib/rdoc/markup/to_joined_paragraph.rb +3 -9
- data/lib/rdoc/markup/to_label.rb +34 -25
- data/lib/rdoc/markup/to_markdown.rb +74 -51
- data/lib/rdoc/markup/to_rdoc.rb +141 -82
- data/lib/rdoc/markup/to_table_of_contents.rb +4 -5
- data/lib/rdoc/markup/to_test.rb +10 -3
- data/lib/rdoc/markup/to_tt_only.rb +17 -31
- data/lib/rdoc/markup/verbatim.rb +5 -6
- data/lib/rdoc/markup.rb +59 -707
- data/lib/rdoc/options.rb +228 -101
- data/lib/rdoc/parser/c.rb +186 -184
- data/lib/rdoc/parser/changelog.rb +57 -13
- data/lib/rdoc/parser/markdown.rb +0 -2
- data/lib/rdoc/parser/rbs.rb +275 -0
- data/lib/rdoc/parser/rd.rb +0 -1
- data/lib/rdoc/parser/ruby.rb +963 -2024
- data/lib/rdoc/parser/ruby_colorizer.rb +253 -0
- data/lib/rdoc/parser/simple.rb +6 -23
- data/lib/rdoc/parser/text.rb +0 -1
- data/lib/rdoc/parser.rb +35 -14
- data/lib/rdoc/rbs_helper.rb +186 -0
- data/lib/rdoc/rd/block_parser.rb +659 -11
- data/lib/rdoc/rd/block_parser.ry +13 -9
- data/lib/rdoc/rd/inline.rb +4 -5
- data/lib/rdoc/rd/inline_parser.rb +646 -2
- data/lib/rdoc/rd.rb +4 -5
- data/lib/rdoc/rdoc.rb +234 -90
- data/lib/rdoc/ri/driver.rb +172 -172
- data/lib/rdoc/ri/paths.rb +3 -3
- data/lib/rdoc/{servlet.rb → ri/servlet.rb} +28 -27
- data/lib/rdoc/ri/store.rb +0 -1
- data/lib/rdoc/ri/task.rb +3 -3
- data/lib/rdoc/ri.rb +5 -5
- data/lib/rdoc/rubygems_hook.rb +106 -25
- data/lib/rdoc/server.rb +460 -0
- data/lib/rdoc/stats/normal.rb +1 -1
- data/lib/rdoc/stats/quiet.rb +1 -2
- data/lib/rdoc/stats/verbose.rb +3 -5
- data/lib/rdoc/stats.rb +158 -136
- data/lib/rdoc/store.rb +267 -48
- data/lib/rdoc/task.rb +54 -28
- data/lib/rdoc/text.rb +60 -120
- data/lib/rdoc/token_stream.rb +30 -45
- data/lib/rdoc/tom_doc.rb +9 -15
- data/lib/rdoc/version.rb +3 -1
- data/lib/rdoc.rb +90 -52
- data/lib/rubygems_plugin.rb +14 -0
- data/man/ri.1 +2 -0
- data/rdoc-logo.svg +43 -0
- data/rdoc.gemspec +25 -200
- metadata +120 -53
- data/CONTRIBUTING.rdoc +0 -220
- data/ExampleMarkdown.md +0 -37
- data/ExampleRDoc.rdoc +0 -208
- data/Gemfile +0 -12
- data/README.rdoc +0 -129
- data/RI.rdoc +0 -57
- data/Rakefile +0 -101
- data/bin/console +0 -7
- data/bin/setup +0 -6
- data/lib/rdoc/anon_class.rb +0 -11
- data/lib/rdoc/context/section.rb +0 -232
- data/lib/rdoc/generator/template/darkfish/.document +0 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +0 -19
- data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +0 -9
- data/lib/rdoc/generator/template/json_index/.document +0 -1
- data/lib/rdoc/ghost_method.rb +0 -7
- data/lib/rdoc/markup/attr_changer.rb +0 -23
- data/lib/rdoc/markup/attr_span.rb +0 -36
- data/lib/rdoc/markup/attribute_manager.rb +0 -409
- data/lib/rdoc/markup/attributes.rb +0 -71
- data/lib/rdoc/markup/regexp_handling.rb +0 -41
- data/lib/rdoc/meta_method.rb +0 -7
- data/lib/rdoc/parser/ripper_state_lex.rb +0 -590
- data/lib/rdoc/parser/ruby_tools.rb +0 -167
data/lib/rdoc/markup/to_html.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require 'cgi'
|
|
2
|
+
require 'cgi/escape'
|
|
3
|
+
require 'cgi/util' unless defined?(CGI::EscapeExt)
|
|
4
|
+
require 'prism'
|
|
3
5
|
|
|
4
6
|
##
|
|
5
7
|
# Outputs RDoc markup as HTML.
|
|
@@ -39,35 +41,129 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
39
41
|
|
|
40
42
|
# :section:
|
|
41
43
|
|
|
44
|
+
# Maps an encoding to a Hash of characters properly transcoded for that
|
|
45
|
+
# encoding.
|
|
46
|
+
#
|
|
47
|
+
# See also encode_fallback.
|
|
48
|
+
|
|
49
|
+
TO_HTML_CHARACTERS = Hash.new do |h, encoding|
|
|
50
|
+
h[encoding] = {
|
|
51
|
+
close_dquote: encode_fallback('”', encoding, '"'),
|
|
52
|
+
close_squote: encode_fallback('’', encoding, '\''),
|
|
53
|
+
copyright: encode_fallback('©', encoding, '(c)'),
|
|
54
|
+
ellipsis: encode_fallback('…', encoding, '...'),
|
|
55
|
+
dot_ellipsis: encode_fallback('.…', encoding, '....'),
|
|
56
|
+
em_dash: encode_fallback('—', encoding, '---'),
|
|
57
|
+
en_dash: encode_fallback('–', encoding, '--'),
|
|
58
|
+
open_dquote: encode_fallback('“', encoding, '"'),
|
|
59
|
+
open_squote: encode_fallback('‘', encoding, '\''),
|
|
60
|
+
trademark: encode_fallback('®', encoding, '(r)'),
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
HTML_CHARACTER_ALIASES = {
|
|
65
|
+
'(c)' => :copyright,
|
|
66
|
+
'(C)' => :copyright,
|
|
67
|
+
'(r)' => :trademark,
|
|
68
|
+
'(R)' => :trademark,
|
|
69
|
+
'---' => :em_dash,
|
|
70
|
+
'--' => :en_dash,
|
|
71
|
+
'....' => :dot_ellipsis,
|
|
72
|
+
'...' => :ellipsis,
|
|
73
|
+
'``' => :open_dquote,
|
|
74
|
+
"''" => :close_dquote,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Transcodes +character+ to +encoding+ with a +fallback+ character.
|
|
78
|
+
|
|
79
|
+
def self.encode_fallback(character, encoding, fallback)
|
|
80
|
+
character.encode(
|
|
81
|
+
encoding,
|
|
82
|
+
fallback: { character => fallback },
|
|
83
|
+
undef: :replace,
|
|
84
|
+
replace: fallback
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Converts ascii quote pairs to multibyte quote characters
|
|
89
|
+
class QuoteConverter
|
|
90
|
+
|
|
91
|
+
def initialize
|
|
92
|
+
@in_dquote = false
|
|
93
|
+
@in_squote = false
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def convert(quote, after_word:)
|
|
97
|
+
case quote
|
|
98
|
+
when '"'
|
|
99
|
+
type = @in_dquote ? :close_dquote : :open_dquote
|
|
100
|
+
@in_dquote = !@in_dquote
|
|
101
|
+
when "'"
|
|
102
|
+
if @in_squote
|
|
103
|
+
type = :close_squote
|
|
104
|
+
@in_squote = false
|
|
105
|
+
elsif after_word
|
|
106
|
+
# Mary's dog, my parents' house: do not start paired quotes
|
|
107
|
+
type = :close_squote
|
|
108
|
+
else
|
|
109
|
+
type = :open_squote
|
|
110
|
+
@in_squote = true
|
|
111
|
+
end
|
|
112
|
+
when '`'
|
|
113
|
+
# Opening quote of <tt>`quoted sentence'</tt>.
|
|
114
|
+
# This will conflict with code blocks <tt>`puts('hello')`</tt> in the future.
|
|
115
|
+
if !@in_squote && !after_word
|
|
116
|
+
type = :open_squote
|
|
117
|
+
@in_squote = true
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
TO_HTML_CHARACTERS[quote.encoding][type] if type
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
42
124
|
##
|
|
43
125
|
# Creates a new formatter that will output HTML
|
|
44
126
|
|
|
45
|
-
def initialize
|
|
46
|
-
super
|
|
127
|
+
def initialize(pipe: false, output_decoration: true)
|
|
128
|
+
super()
|
|
47
129
|
|
|
130
|
+
@pipe = pipe
|
|
131
|
+
@output_decoration = output_decoration
|
|
48
132
|
@code_object = nil
|
|
49
133
|
@from_path = ''
|
|
50
134
|
@in_list_entry = nil
|
|
51
135
|
@list = nil
|
|
52
136
|
@th = nil
|
|
137
|
+
@quote_converter = nil
|
|
138
|
+
@in_tidylink_label = false
|
|
53
139
|
@hard_break = "<br>\n"
|
|
54
140
|
|
|
55
141
|
init_regexp_handlings
|
|
56
|
-
|
|
57
|
-
init_tags
|
|
58
142
|
end
|
|
59
143
|
|
|
60
144
|
# :section: Regexp Handling
|
|
61
145
|
#
|
|
62
146
|
# These methods are used by regexp handling markup added by RDoc::Markup#add_regexp_handling.
|
|
63
147
|
|
|
148
|
+
# :nodoc:
|
|
149
|
+
URL_CHARACTERS_REGEXP_STR = /[A-Za-z0-9\-._~:\/\?#\[\]@!$&'\(\)*+,;%=]/.source
|
|
150
|
+
|
|
64
151
|
##
|
|
65
152
|
# Adds regexp handlings.
|
|
66
153
|
|
|
67
154
|
def init_regexp_handlings
|
|
68
155
|
# external links
|
|
69
|
-
@markup.add_regexp_handling(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)
|
|
156
|
+
@markup.add_regexp_handling(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)#{URL_CHARACTERS_REGEXP_STR}+\w/,
|
|
70
157
|
:HYPERLINK)
|
|
158
|
+
|
|
159
|
+
# suppress crossref: \#method \::method \ClassName \method_with_underscores
|
|
160
|
+
@markup.add_regexp_handling(/\\(?:[#:A-Z]|[a-z]+_[a-z0-9])/, :SUPPRESSED_CROSSREF)
|
|
161
|
+
|
|
162
|
+
@markup.add_regexp_handling(Regexp.union(HTML_CHARACTER_ALIASES.keys), :HTML_CHARACTERS)
|
|
163
|
+
|
|
164
|
+
@markup.add_regexp_handling(/\b['"`]/, :QUOTE_AFTER_WORD)
|
|
165
|
+
@markup.add_regexp_handling(/\B['"`]/, :QUOTE_NOT_AFTER_WORD)
|
|
166
|
+
|
|
71
167
|
init_link_notation_regexp_handlings
|
|
72
168
|
end
|
|
73
169
|
|
|
@@ -76,14 +172,14 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
76
172
|
|
|
77
173
|
def init_link_notation_regexp_handlings
|
|
78
174
|
add_regexp_handling_RDOCLINK
|
|
79
|
-
add_regexp_handling_TIDYLINK
|
|
80
175
|
end
|
|
81
176
|
|
|
82
|
-
def handle_RDOCLINK
|
|
177
|
+
def handle_RDOCLINK(url) # :nodoc:
|
|
83
178
|
case url
|
|
84
179
|
when /^rdoc-ref:/
|
|
85
|
-
$'
|
|
180
|
+
CGI.escapeHTML($')
|
|
86
181
|
when /^rdoc-label:/
|
|
182
|
+
return CGI.escapeHTML(url) if in_tidylink_label?
|
|
87
183
|
text = $'
|
|
88
184
|
|
|
89
185
|
text = case text
|
|
@@ -93,21 +189,159 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
93
189
|
else text
|
|
94
190
|
end
|
|
95
191
|
|
|
96
|
-
gen_url url, text
|
|
192
|
+
gen_url CGI.escapeHTML(url), CGI.escapeHTML(text)
|
|
97
193
|
when /^rdoc-image:/
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
194
|
+
# Split the string after "rdoc-image:" into url and alt.
|
|
195
|
+
# "path/to/image.jpg:alt text" => ["path/to/image.jpg", "alt text"]
|
|
196
|
+
# "http://example.com/path/to/image.jpg:alt text" => ["http://example.com/path/to/image.jpg", "alt text"]
|
|
197
|
+
url, alt = $'.split(/:(?!\/)/, 2)
|
|
198
|
+
if alt && !alt.empty?
|
|
199
|
+
%[<img src="#{CGI.escapeHTML(url)}" alt="#{CGI.escapeHTML(alt)}">]
|
|
200
|
+
else
|
|
201
|
+
%[<img src="#{CGI.escapeHTML(url)}">]
|
|
202
|
+
end
|
|
203
|
+
when /\Ardoc-[a-z]+:/
|
|
204
|
+
CGI.escapeHTML($')
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def handle_PLAIN_TEXT(text)
|
|
209
|
+
emit_inline(convert_string(text))
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def handle_REGEXP_HANDLING_TEXT(text)
|
|
213
|
+
emit_inline(text)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def handle_BOLD(nodes)
|
|
217
|
+
emit_inline('<strong>')
|
|
218
|
+
super
|
|
219
|
+
emit_inline('</strong>')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def handle_EM(nodes)
|
|
223
|
+
emit_inline('<em>')
|
|
224
|
+
super
|
|
225
|
+
emit_inline('</em>')
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def handle_BOLD_WORD(word)
|
|
229
|
+
emit_inline('<strong>')
|
|
230
|
+
super
|
|
231
|
+
emit_inline('</strong>')
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def handle_EM_WORD(word)
|
|
235
|
+
emit_inline('<em>')
|
|
236
|
+
super
|
|
237
|
+
emit_inline('</em>')
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def handle_TT(code)
|
|
241
|
+
emit_inline('<code>')
|
|
242
|
+
super
|
|
243
|
+
emit_inline('</code>')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def handle_STRIKE(nodes)
|
|
247
|
+
emit_inline('<del>')
|
|
248
|
+
super
|
|
249
|
+
emit_inline('</del>')
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def handle_HARD_BREAK
|
|
253
|
+
emit_inline('<br>')
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def emit_inline(text)
|
|
257
|
+
@inline_output << text
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Returns true if we are processing inside a tidy link label.
|
|
261
|
+
|
|
262
|
+
def in_tidylink_label?
|
|
263
|
+
@in_tidylink_label
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Special handling for tidy link labels.
|
|
267
|
+
# When a tidy link is <tt>{rdoc-image:path/to/image.jpg:alt text}[http://example.com]</tt>,
|
|
268
|
+
# label part is normally considered RDOCLINK <tt>rdoc-image:path/to/image.jpg:alt</tt> and a text <tt>" text"</tt>
|
|
269
|
+
# but RDoc's test code expects the whole label part to be treated as RDOCLINK only in tidy link label.
|
|
270
|
+
# When a tidy link is <tt>{^1}[url]</tt> or <tt>{*1}[url]</tt>, the label part needs to drop leading * or ^.
|
|
271
|
+
# TODO: reconsider this workaround.
|
|
101
272
|
|
|
102
|
-
|
|
273
|
+
def apply_tidylink_label_special_handling(label, url)
|
|
274
|
+
# ^1 *1 will be converted to just 1 in tidy link label.
|
|
275
|
+
return label[1..] if label.match?(/\A[*^]\d+\z/)
|
|
276
|
+
|
|
277
|
+
# rdoc-image in label specially allows spaces in alt text.
|
|
278
|
+
return handle_RDOCLINK(label) if label.start_with?('rdoc-image:')
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def handle_TIDYLINK(label_part, url)
|
|
282
|
+
# When url is an image, ignore label part (maybe bug?) and just generate img tag.
|
|
283
|
+
if url.match?(/\Ahttps?:\/\/.+\.(png|gif|jpg|jpeg|bmp)\z/)
|
|
284
|
+
emit_inline("<img src=\"#{CGI.escapeHTML(url)}\" />")
|
|
285
|
+
return
|
|
286
|
+
elsif url.match?(/\Ardoc-image:/)
|
|
287
|
+
emit_inline(handle_RDOCLINK(url))
|
|
288
|
+
return
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
if label_part.size == 1 && String === label_part[0]
|
|
292
|
+
raw_label = label_part[0]
|
|
293
|
+
|
|
294
|
+
@in_tidylink_label = true
|
|
295
|
+
special = apply_tidylink_label_special_handling(raw_label, url)
|
|
296
|
+
@in_tidylink_label = false
|
|
297
|
+
|
|
298
|
+
if special
|
|
299
|
+
tag = gen_url(CGI.escapeHTML(url), special)
|
|
300
|
+
unless tag.empty?
|
|
301
|
+
emit_inline(tag)
|
|
302
|
+
return
|
|
303
|
+
end
|
|
304
|
+
end
|
|
103
305
|
end
|
|
306
|
+
|
|
307
|
+
tag = gen_url(CGI.escapeHTML(url), '')
|
|
308
|
+
open_tag, close_tag = tag.split(/(?=<\/a>)/, 2)
|
|
309
|
+
valid_tag = open_tag && close_tag
|
|
310
|
+
emit_inline(open_tag) if valid_tag
|
|
311
|
+
@in_tidylink_label = true
|
|
312
|
+
traverse_inline_nodes(label_part)
|
|
313
|
+
@in_tidylink_label = false
|
|
314
|
+
emit_inline(close_tag) if valid_tag
|
|
104
315
|
end
|
|
105
316
|
|
|
106
|
-
|
|
107
|
-
|
|
317
|
+
def handle_inline(text) # :nodoc:
|
|
318
|
+
@inline_output = +''
|
|
319
|
+
@quote_converter = QuoteConverter.new
|
|
320
|
+
super
|
|
321
|
+
out = @inline_output
|
|
322
|
+
@inline_output = nil
|
|
323
|
+
@quote_converter = nil
|
|
324
|
+
out
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Converts <tt>(c), (r), --, --- , ..., ...., ``, ''</tt> to HTML characters.
|
|
328
|
+
def handle_regexp_HTML_CHARACTERS(text)
|
|
329
|
+
name = HTML_CHARACTER_ALIASES[text]
|
|
330
|
+
TO_HTML_CHARACTERS[text.encoding][name] if name
|
|
331
|
+
end
|
|
108
332
|
|
|
109
|
-
def
|
|
110
|
-
|
|
333
|
+
def handle_regexp_QUOTE_NOT_AFTER_WORD(text)
|
|
334
|
+
@quote_converter.convert(text, after_word: false) || convert_string(text)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def handle_regexp_QUOTE_AFTER_WORD(text)
|
|
338
|
+
@quote_converter.convert(text, after_word: true) || convert_string(text)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Converts suppressed cross-reference +text+ to HTML by removing the leading backslash.
|
|
342
|
+
|
|
343
|
+
def handle_regexp_SUPPRESSED_CROSSREF(text)
|
|
344
|
+
convert_string(text.delete_prefix('\\'))
|
|
111
345
|
end
|
|
112
346
|
|
|
113
347
|
##
|
|
@@ -122,9 +356,10 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
122
356
|
# <tt>link:</tt>::
|
|
123
357
|
# Reference to a local file relative to the output directory.
|
|
124
358
|
|
|
125
|
-
def handle_regexp_HYPERLINK(
|
|
126
|
-
|
|
359
|
+
def handle_regexp_HYPERLINK(text)
|
|
360
|
+
return convert_string(text) if in_tidylink_label?
|
|
127
361
|
|
|
362
|
+
url = CGI.escapeHTML(text)
|
|
128
363
|
gen_url url, url
|
|
129
364
|
end
|
|
130
365
|
|
|
@@ -137,26 +372,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
137
372
|
# For the +rdoc-label+ scheme the footnote and label prefixes are stripped
|
|
138
373
|
# when creating a link. All other contents will be linked verbatim.
|
|
139
374
|
|
|
140
|
-
def handle_regexp_RDOCLINK
|
|
141
|
-
handle_RDOCLINK
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
##
|
|
145
|
-
# This +target+ is a link where the label is different from the URL
|
|
146
|
-
# <tt>label[url]</tt> or <tt>{long label}[url]</tt>
|
|
147
|
-
|
|
148
|
-
def handle_regexp_TIDYLINK(target)
|
|
149
|
-
text = target.text
|
|
150
|
-
|
|
151
|
-
return text unless
|
|
152
|
-
text =~ /^\{(.*)\}\[(.*?)\]$/ or text =~ /^(\S+)\[(.*?)\]$/
|
|
153
|
-
|
|
154
|
-
label = $1
|
|
155
|
-
url = $2
|
|
156
|
-
|
|
157
|
-
label = handle_RDOCLINK label if /^rdoc-image:/ =~ label
|
|
158
|
-
|
|
159
|
-
gen_url url, label
|
|
375
|
+
def handle_regexp_RDOCLINK(text)
|
|
376
|
+
handle_RDOCLINK text
|
|
160
377
|
end
|
|
161
378
|
|
|
162
379
|
# :section: Visitor
|
|
@@ -170,6 +387,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
170
387
|
@res = []
|
|
171
388
|
@in_list_entry = []
|
|
172
389
|
@list = []
|
|
390
|
+
@heading_ids = {}
|
|
173
391
|
end
|
|
174
392
|
|
|
175
393
|
##
|
|
@@ -182,7 +400,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
182
400
|
##
|
|
183
401
|
# Adds +block_quote+ to the output
|
|
184
402
|
|
|
185
|
-
def accept_block_quote
|
|
403
|
+
def accept_block_quote(block_quote)
|
|
186
404
|
@res << "\n<blockquote>"
|
|
187
405
|
|
|
188
406
|
block_quote.parts.each do |part|
|
|
@@ -195,38 +413,45 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
195
413
|
##
|
|
196
414
|
# Adds +paragraph+ to the output
|
|
197
415
|
|
|
198
|
-
def accept_paragraph
|
|
416
|
+
def accept_paragraph(paragraph)
|
|
199
417
|
@res << "\n<p>"
|
|
200
418
|
text = paragraph.text @hard_break
|
|
201
|
-
text = text.gsub(
|
|
419
|
+
text = text.gsub(/(#{SPACE_SEPARATED_LETTER_CLASS})?\K(?:\r?\n)+(?=(?(1)(#{SPACE_SEPARATED_LETTER_CLASS})?))/o) {
|
|
420
|
+
defined?($2) && ' '
|
|
421
|
+
}
|
|
202
422
|
@res << to_html(text)
|
|
203
423
|
@res << "</p>\n"
|
|
204
424
|
end
|
|
205
425
|
|
|
426
|
+
# Generate syntax highlighted html for ruby-like text.
|
|
427
|
+
|
|
428
|
+
def parsable_text_to_html(text)
|
|
429
|
+
tokens = RDoc::Parser::RubyColorizer.colorize(text)
|
|
430
|
+
result = RDoc::TokenStream.to_html tokens
|
|
431
|
+
result = result + "\n" unless result.end_with?("\n")
|
|
432
|
+
result
|
|
433
|
+
end
|
|
434
|
+
|
|
206
435
|
##
|
|
207
436
|
# Adds +verbatim+ to the output
|
|
208
437
|
|
|
209
|
-
def accept_verbatim
|
|
438
|
+
def accept_verbatim(verbatim)
|
|
210
439
|
text = verbatim.text.rstrip
|
|
440
|
+
format = verbatim.format
|
|
441
|
+
|
|
442
|
+
# Apply Ruby syntax highlighting if
|
|
443
|
+
# - explicitly marked as Ruby (via ruby? which accepts :ruby or :rb)
|
|
444
|
+
# - no format specified but the text is parseable as Ruby
|
|
445
|
+
# Otherwise, add language class when applicable and skip Ruby highlighting
|
|
446
|
+
if verbatim.ruby? || (format.nil? && parseable?(text))
|
|
447
|
+
content = parsable_text_to_html(text)
|
|
448
|
+
klass = ' class="ruby"'
|
|
449
|
+
else
|
|
450
|
+
content = CGI.escapeHTML text
|
|
451
|
+
klass = " class=\"#{format}\"" if format
|
|
452
|
+
end
|
|
211
453
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
content = if verbatim.ruby? or parseable? text then
|
|
215
|
-
begin
|
|
216
|
-
tokens = RDoc::Parser::RipperStateLex.parse text
|
|
217
|
-
klass = ' class="ruby"'
|
|
218
|
-
|
|
219
|
-
result = RDoc::TokenStream.to_html tokens
|
|
220
|
-
result = result + "\n" unless "\n" == result[-1]
|
|
221
|
-
result
|
|
222
|
-
rescue
|
|
223
|
-
CGI.escapeHTML text
|
|
224
|
-
end
|
|
225
|
-
else
|
|
226
|
-
CGI.escapeHTML text
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
if @options.pipe then
|
|
454
|
+
if @pipe
|
|
230
455
|
@res << "\n<pre><code>#{CGI.escapeHTML text}\n</code></pre>\n"
|
|
231
456
|
else
|
|
232
457
|
@res << "\n<pre#{klass}>#{content}</pre>\n"
|
|
@@ -236,7 +461,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
236
461
|
##
|
|
237
462
|
# Adds +rule+ to the output
|
|
238
463
|
|
|
239
|
-
def accept_rule
|
|
464
|
+
def accept_rule(rule)
|
|
240
465
|
@res << "<hr>\n"
|
|
241
466
|
end
|
|
242
467
|
|
|
@@ -289,40 +514,49 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
289
514
|
# Adds +heading+ to the output. The headings greater than 6 are trimmed to
|
|
290
515
|
# level 6.
|
|
291
516
|
|
|
292
|
-
def accept_heading
|
|
517
|
+
def accept_heading(heading)
|
|
293
518
|
level = [6, heading.level].min
|
|
294
519
|
|
|
295
|
-
label = heading.label
|
|
520
|
+
label = deduplicate_heading_id(heading.label(@code_object))
|
|
521
|
+
legacy_label = deduplicate_heading_id(heading.legacy_label(@code_object))
|
|
296
522
|
|
|
297
|
-
|
|
523
|
+
# Add legacy anchor before the heading for backward compatibility.
|
|
524
|
+
# This allows old links with label- prefix to still work.
|
|
525
|
+
if @output_decoration && !@pipe
|
|
526
|
+
@res << "\n<span id=\"#{legacy_label}\" class=\"legacy-anchor\"></span>"
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
@res << if @output_decoration
|
|
298
530
|
"\n<h#{level} id=\"#{label}\">"
|
|
299
531
|
else
|
|
300
532
|
"\n<h#{level}>"
|
|
301
533
|
end
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
@res <<
|
|
305
|
-
|
|
534
|
+
|
|
535
|
+
if @pipe
|
|
536
|
+
@res << to_html(heading.text)
|
|
537
|
+
else
|
|
538
|
+
@res << "<a href=\"##{label}\">#{to_html(heading.text)}</a>"
|
|
306
539
|
end
|
|
540
|
+
|
|
307
541
|
@res << "</h#{level}>\n"
|
|
308
542
|
end
|
|
309
543
|
|
|
310
544
|
##
|
|
311
545
|
# Adds +raw+ to the output
|
|
312
546
|
|
|
313
|
-
def accept_raw
|
|
547
|
+
def accept_raw(raw)
|
|
314
548
|
@res << raw.parts.join("\n")
|
|
315
549
|
end
|
|
316
550
|
|
|
317
551
|
##
|
|
318
552
|
# Adds +table+ to the output
|
|
319
553
|
|
|
320
|
-
def accept_table
|
|
554
|
+
def accept_table(header, body, aligns)
|
|
321
555
|
@res << "\n<table role=\"table\">\n<thead>\n<tr>\n"
|
|
322
556
|
header.zip(aligns) do |text, align|
|
|
323
557
|
@res << '<th'
|
|
324
558
|
@res << ' align="' << align << '"' if align
|
|
325
|
-
@res << '>' <<
|
|
559
|
+
@res << '>' << to_html(text) << "</th>\n"
|
|
326
560
|
end
|
|
327
561
|
@res << "</tr>\n</thead>\n<tbody>\n"
|
|
328
562
|
body.each do |row|
|
|
@@ -330,7 +564,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
330
564
|
row.zip(aligns) do |text, align|
|
|
331
565
|
@res << '<td'
|
|
332
566
|
@res << ' align="' << align << '"' if align
|
|
333
|
-
@res << '>' <<
|
|
567
|
+
@res << '>' << to_html(text) << "</td>\n"
|
|
334
568
|
end
|
|
335
569
|
@res << "</tr>\n"
|
|
336
570
|
end
|
|
@@ -339,6 +573,20 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
339
573
|
|
|
340
574
|
# :section: Utilities
|
|
341
575
|
|
|
576
|
+
##
|
|
577
|
+
# Returns a unique heading ID, appending -1, -2, etc. for duplicates.
|
|
578
|
+
# Matches GitHub's behavior for duplicate heading anchors.
|
|
579
|
+
|
|
580
|
+
def deduplicate_heading_id(id)
|
|
581
|
+
if @heading_ids.key?(id)
|
|
582
|
+
@heading_ids[id] += 1
|
|
583
|
+
"#{id}-#{@heading_ids[id]}"
|
|
584
|
+
else
|
|
585
|
+
@heading_ids[id] = 0
|
|
586
|
+
id
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
|
|
342
590
|
##
|
|
343
591
|
# CGI-escapes +text+
|
|
344
592
|
|
|
@@ -347,18 +595,22 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
347
595
|
end
|
|
348
596
|
|
|
349
597
|
##
|
|
350
|
-
#
|
|
351
|
-
#
|
|
598
|
+
# Generates an HTML link or image tag for the given +url+ and +text+.
|
|
599
|
+
#
|
|
600
|
+
# - Image URLs (http/https/link ending in .gif, .png, .jpg, .jpeg, .bmp)
|
|
601
|
+
# become <img> tags
|
|
602
|
+
# - File references (.rb, .rdoc, .md) are converted to .html paths
|
|
603
|
+
# - Anchor URLs (#foo) pass through unchanged for GitHub-style header linking
|
|
604
|
+
# - Footnote links get wrapped in <sup> tags
|
|
352
605
|
|
|
353
|
-
def gen_url
|
|
606
|
+
def gen_url(url, text)
|
|
354
607
|
scheme, url, id = parse_url url
|
|
355
608
|
|
|
356
|
-
if %w[http https link].include?(scheme)
|
|
357
|
-
url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
|
|
609
|
+
if %w[http https link].include?(scheme) && url =~ /\.(gif|png|jpg|jpeg|bmp)\z/
|
|
358
610
|
"<img src=\"#{url}\" />"
|
|
359
611
|
else
|
|
360
|
-
if scheme != 'link' and
|
|
361
|
-
url =
|
|
612
|
+
if scheme != 'link' and %r%\A((?!https?:)(?:[^/#]*/)*+)([^/#]+)\.(rb|rdoc|md)(?=\z|#)%i =~ url
|
|
613
|
+
url = "#$1#{$2.tr('.', '_')}_#$3.html#$'"
|
|
362
614
|
end
|
|
363
615
|
|
|
364
616
|
text = text.sub %r%^#{scheme}:/*%i, ''
|
|
@@ -366,9 +618,11 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
366
618
|
|
|
367
619
|
link = "<a#{id} href=\"#{url}\">#{text}</a>"
|
|
368
620
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
621
|
+
if /"foot/.match?(id)
|
|
622
|
+
"<sup>#{link}</sup>"
|
|
623
|
+
else
|
|
624
|
+
link
|
|
625
|
+
end
|
|
372
626
|
end
|
|
373
627
|
end
|
|
374
628
|
|
|
@@ -381,15 +635,6 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
381
635
|
tags[open_tag ? 0 : 1]
|
|
382
636
|
end
|
|
383
637
|
|
|
384
|
-
##
|
|
385
|
-
# Maps attributes to HTML tags
|
|
386
|
-
|
|
387
|
-
def init_tags
|
|
388
|
-
add_tag :BOLD, "<strong>", "</strong>"
|
|
389
|
-
add_tag :TT, "<code>", "</code>"
|
|
390
|
-
add_tag :EM, "<em>", "</em>"
|
|
391
|
-
end
|
|
392
|
-
|
|
393
638
|
##
|
|
394
639
|
# Returns the HTML tag for +list_type+, possible using a label from
|
|
395
640
|
# +list_item+
|
|
@@ -400,7 +645,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
400
645
|
"<li>"
|
|
401
646
|
when :LABEL, :NOTE then
|
|
402
647
|
Array(list_item.label).map do |label|
|
|
403
|
-
"<dt>#{to_html label}
|
|
648
|
+
"<dt>#{to_html label}</dt>\n"
|
|
404
649
|
end.join << "<dd>"
|
|
405
650
|
else
|
|
406
651
|
raise RDoc::Error, "Invalid list type: #{list_type.inspect}"
|
|
@@ -424,21 +669,14 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
424
669
|
##
|
|
425
670
|
# Returns true if text is valid ruby syntax
|
|
426
671
|
|
|
427
|
-
def parseable?
|
|
428
|
-
|
|
429
|
-
eval("BEGIN {return true}\n#{text}")
|
|
430
|
-
rescue SyntaxError
|
|
431
|
-
false
|
|
432
|
-
ensure
|
|
433
|
-
$VERBOSE = verbose
|
|
672
|
+
def parseable?(text)
|
|
673
|
+
Prism.parse_success?(text)
|
|
434
674
|
end
|
|
435
675
|
|
|
436
676
|
##
|
|
437
677
|
# Converts +item+ to HTML using RDoc::Text#to_html
|
|
438
678
|
|
|
439
|
-
def to_html
|
|
440
|
-
|
|
679
|
+
def to_html(item)
|
|
680
|
+
handle_inline(item)
|
|
441
681
|
end
|
|
442
|
-
|
|
443
682
|
end
|
|
444
|
-
|