rdoc 6.14.2 → 7.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 +196 -0
- data/History.rdoc +1 -1
- data/LEGAL.rdoc +6 -0
- data/README.md +195 -0
- data/RI.md +1 -1
- data/doc/markup_reference/markdown.md +558 -0
- data/doc/markup_reference/rdoc.rdoc +1169 -0
- data/lib/rdoc/code_object/any_method.rb +15 -7
- data/lib/rdoc/code_object/class_module.rb +62 -11
- data/lib/rdoc/code_object/constant.rb +9 -0
- data/lib/rdoc/code_object/context/section.rb +20 -1
- data/lib/rdoc/code_object/method_attr.rb +13 -1
- data/lib/rdoc/code_object/top_level.rb +31 -26
- data/lib/rdoc/comment.rb +190 -8
- data/lib/rdoc/cross_reference.rb +31 -22
- data/lib/rdoc/generator/aliki.rb +183 -0
- data/lib/rdoc/generator/darkfish.rb +8 -2
- 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 +158 -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 +25 -0
- data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +25 -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 +220 -0
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +1963 -0
- data/lib/rdoc/generator/template/aliki/index.rhtml +22 -0
- data/lib/rdoc/generator/template/aliki/js/aliki.js +505 -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 +14 -19
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -8
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -8
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +7 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +6 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +18 -18
- data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +2 -2
- data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +1 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +3 -3
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +14 -14
- data/lib/rdoc/generator/template/darkfish/class.rhtml +70 -68
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +19 -0
- data/lib/rdoc/generator/template/darkfish/index.rhtml +4 -3
- data/lib/rdoc/generator/template/darkfish/js/darkfish.js +21 -1
- data/lib/rdoc/generator/template/darkfish/js/search.js +11 -1
- data/lib/rdoc/generator/template/darkfish/page.rhtml +2 -1
- data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +2 -1
- data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +19 -19
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +19 -17
- data/lib/rdoc/generator/template/json_index/js/searcher.js +48 -6
- data/lib/rdoc/generator.rb +1 -0
- data/lib/rdoc/markdown.kpeg +29 -22
- data/lib/rdoc/markdown.rb +366 -549
- data/lib/rdoc/markup/attribute_manager.rb +28 -1
- data/lib/rdoc/markup/blank_line.rb +25 -23
- data/lib/rdoc/markup/element.rb +21 -0
- data/lib/rdoc/markup/hard_break.rb +30 -27
- data/lib/rdoc/markup/heading.rb +166 -77
- data/lib/rdoc/markup/pre_process.rb +34 -10
- data/lib/rdoc/markup/raw.rb +52 -55
- data/lib/rdoc/markup/table.rb +48 -40
- data/lib/rdoc/markup/to_ansi.rb +4 -0
- data/lib/rdoc/markup/to_bs.rb +4 -0
- data/lib/rdoc/markup/to_html.rb +193 -25
- data/lib/rdoc/markup/to_html_crossref.rb +77 -28
- data/lib/rdoc/markup/to_label.rb +11 -1
- data/lib/rdoc/markup/to_rdoc.rb +11 -3
- data/lib/rdoc/markup/verbatim.rb +1 -1
- data/lib/rdoc/markup.rb +3 -2
- data/lib/rdoc/options.rb +22 -11
- data/lib/rdoc/parser/c.rb +15 -46
- data/lib/rdoc/parser/changelog.rb +8 -0
- data/lib/rdoc/parser/prism_ruby.rb +121 -113
- data/lib/rdoc/parser/ruby.rb +8 -8
- data/lib/rdoc/parser/ruby_tools.rb +5 -7
- data/lib/rdoc/parser/simple.rb +4 -21
- data/lib/rdoc/rdoc.rb +1 -0
- data/lib/rdoc/ri/task.rb +2 -2
- data/lib/rdoc/rubygems_hook.rb +3 -3
- data/lib/rdoc/store.rb +2 -2
- data/lib/rdoc/task.rb +4 -4
- data/lib/rdoc/text.rb +16 -1
- data/lib/rdoc/token_stream.rb +17 -9
- data/lib/rdoc/tom_doc.rb +1 -1
- data/lib/rdoc/version.rb +1 -1
- data/rdoc.gemspec +6 -5
- metadata +53 -12
- data/CONTRIBUTING.rdoc +0 -219
- data/ExampleMarkdown.md +0 -39
- data/ExampleRDoc.rdoc +0 -210
- data/README.rdoc +0 -144
data/lib/rdoc/markup/table.rb
CHANGED
|
@@ -1,52 +1,60 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
##
|
|
3
|
-
# A section of table
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
module RDoc
|
|
4
|
+
class Markup
|
|
5
|
+
# A section of table
|
|
6
|
+
class Table < Element
|
|
7
|
+
# Headers of each column
|
|
8
|
+
#: Array[String]
|
|
9
|
+
attr_accessor :header
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
# Alignments of each column
|
|
12
|
+
#: Array[Symbol?]
|
|
13
|
+
attr_accessor :align
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
# Body texts of each column
|
|
16
|
+
#: Array[String]
|
|
17
|
+
attr_accessor :body
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# :stopdoc:
|
|
21
|
-
def ==(other)
|
|
22
|
-
self.class == other.class and
|
|
23
|
-
@header == other.header and
|
|
24
|
-
@align == other.align and
|
|
25
|
-
@body == other.body
|
|
26
|
-
end
|
|
19
|
+
#: (Array[String], Array[Symbol?], Array[String]) -> void
|
|
20
|
+
def initialize(header, align, body)
|
|
21
|
+
@header, @align, @body = header, align, body
|
|
22
|
+
end
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
#: (Object) -> bool
|
|
25
|
+
def ==(other)
|
|
26
|
+
self.class == other.class && @header == other.header &&
|
|
27
|
+
@align == other.align && @body == other.body
|
|
28
|
+
end
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
q.pp text
|
|
37
|
-
if align
|
|
38
|
-
q.text ":"
|
|
39
|
-
q.breakable
|
|
40
|
-
q.text align.to_s
|
|
41
|
-
end
|
|
42
|
-
end
|
|
30
|
+
# @override
|
|
31
|
+
#: (untyped) -> void
|
|
32
|
+
def accept(visitor)
|
|
33
|
+
visitor.accept_table(@header, @body, @align)
|
|
43
34
|
end
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
|
|
36
|
+
# @override
|
|
37
|
+
#: (untyped) -> String
|
|
38
|
+
def pretty_print(q)
|
|
39
|
+
q.group 2, '[Table: ', ']' do
|
|
40
|
+
q.group 2, '[Head: ', ']' do
|
|
41
|
+
q.seplist @header.zip(@align) do |text, align|
|
|
49
42
|
q.pp text
|
|
43
|
+
if align
|
|
44
|
+
q.text ":"
|
|
45
|
+
q.breakable
|
|
46
|
+
q.text align.to_s
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
q.breakable
|
|
51
|
+
q.group 2, '[Body: ', ']' do
|
|
52
|
+
q.seplist @body do |body|
|
|
53
|
+
q.group 2, '[', ']' do
|
|
54
|
+
q.seplist body do |text|
|
|
55
|
+
q.pp text
|
|
56
|
+
end
|
|
57
|
+
end
|
|
50
58
|
end
|
|
51
59
|
end
|
|
52
60
|
end
|
data/lib/rdoc/markup/to_ansi.rb
CHANGED
data/lib/rdoc/markup/to_bs.rb
CHANGED
data/lib/rdoc/markup/to_html.rb
CHANGED
|
@@ -158,19 +158,16 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
158
158
|
def handle_regexp_TIDYLINK(target)
|
|
159
159
|
text = target.text
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
label = $1
|
|
165
|
-
url = CGI.escapeHTML($2)
|
|
161
|
+
if tidy_link_capturing?
|
|
162
|
+
return finish_tidy_link(text)
|
|
163
|
+
end
|
|
166
164
|
|
|
167
|
-
if
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
label = CGI.escapeHTML(label)
|
|
165
|
+
if text.start_with?('{') && !text.include?('}')
|
|
166
|
+
start_tidy_link text
|
|
167
|
+
return ''
|
|
171
168
|
end
|
|
172
169
|
|
|
173
|
-
|
|
170
|
+
convert_complete_tidy_link(text)
|
|
174
171
|
end
|
|
175
172
|
|
|
176
173
|
# :section: Visitor
|
|
@@ -224,10 +221,15 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
224
221
|
|
|
225
222
|
def accept_verbatim(verbatim)
|
|
226
223
|
text = verbatim.text.rstrip
|
|
224
|
+
format = verbatim.format
|
|
227
225
|
|
|
228
226
|
klass = nil
|
|
229
227
|
|
|
230
|
-
|
|
228
|
+
# Apply Ruby syntax highlighting if
|
|
229
|
+
# - explicitly marked as Ruby (via ruby? which accepts :ruby or :rb)
|
|
230
|
+
# - no format specified but the text is parseable as Ruby
|
|
231
|
+
# Otherwise, add language class when applicable and skip Ruby highlighting
|
|
232
|
+
content = if verbatim.ruby? || (format.nil? && parseable?(text))
|
|
231
233
|
begin
|
|
232
234
|
tokens = RDoc::Parser::RipperStateLex.parse text
|
|
233
235
|
klass = ' class="ruby"'
|
|
@@ -239,6 +241,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
239
241
|
CGI.escapeHTML text
|
|
240
242
|
end
|
|
241
243
|
else
|
|
244
|
+
klass = " class=\"#{format}\"" if format
|
|
242
245
|
CGI.escapeHTML text
|
|
243
246
|
end
|
|
244
247
|
|
|
@@ -309,17 +312,26 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
309
312
|
level = [6, heading.level].min
|
|
310
313
|
|
|
311
314
|
label = heading.label @code_object
|
|
315
|
+
legacy_label = heading.legacy_label @code_object
|
|
316
|
+
|
|
317
|
+
# Add legacy anchor before the heading for backward compatibility.
|
|
318
|
+
# This allows old links with label- prefix to still work.
|
|
319
|
+
if @options.output_decoration && !@options.pipe
|
|
320
|
+
@res << "\n<span id=\"#{legacy_label}\" class=\"legacy-anchor\"></span>"
|
|
321
|
+
end
|
|
312
322
|
|
|
313
323
|
@res << if @options.output_decoration
|
|
314
324
|
"\n<h#{level} id=\"#{label}\">"
|
|
315
325
|
else
|
|
316
326
|
"\n<h#{level}>"
|
|
317
327
|
end
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
@res <<
|
|
321
|
-
|
|
328
|
+
|
|
329
|
+
if @options.pipe
|
|
330
|
+
@res << to_html(heading.text)
|
|
331
|
+
else
|
|
332
|
+
@res << "<a href=\"##{label}\">#{to_html(heading.text)}</a>"
|
|
322
333
|
end
|
|
334
|
+
|
|
323
335
|
@res << "</h#{level}>\n"
|
|
324
336
|
end
|
|
325
337
|
|
|
@@ -363,14 +375,18 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
363
375
|
end
|
|
364
376
|
|
|
365
377
|
##
|
|
366
|
-
#
|
|
367
|
-
#
|
|
378
|
+
# Generates an HTML link or image tag for the given +url+ and +text+.
|
|
379
|
+
#
|
|
380
|
+
# - Image URLs (http/https/link ending in .gif, .png, .jpg, .jpeg, .bmp)
|
|
381
|
+
# become <img> tags
|
|
382
|
+
# - File references (.rb, .rdoc, .md) are converted to .html paths
|
|
383
|
+
# - Anchor URLs (#foo) pass through unchanged for GitHub-style header linking
|
|
384
|
+
# - Footnote links get wrapped in <sup> tags
|
|
368
385
|
|
|
369
386
|
def gen_url(url, text)
|
|
370
387
|
scheme, url, id = parse_url url
|
|
371
388
|
|
|
372
|
-
if %w[http https link].include?(scheme)
|
|
373
|
-
url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
|
|
389
|
+
if %w[http https link].include?(scheme) && url =~ /\.(gif|png|jpg|jpeg|bmp)\z/
|
|
374
390
|
"<img src=\"#{url}\" />"
|
|
375
391
|
else
|
|
376
392
|
if scheme != 'link' and %r%\A((?!https?:)(?:[^/#]*/)*+)([^/#]+)\.(rb|rdoc|md)(?=\z|#)%i =~ url
|
|
@@ -382,9 +398,11 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
382
398
|
|
|
383
399
|
link = "<a#{id} href=\"#{url}\">#{text}</a>"
|
|
384
400
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
401
|
+
if /"foot/.match?(id)
|
|
402
|
+
"<sup>#{link}</sup>"
|
|
403
|
+
else
|
|
404
|
+
link
|
|
405
|
+
end
|
|
388
406
|
end
|
|
389
407
|
end
|
|
390
408
|
|
|
@@ -401,9 +419,10 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
401
419
|
# Maps attributes to HTML tags
|
|
402
420
|
|
|
403
421
|
def init_tags
|
|
404
|
-
add_tag :BOLD,
|
|
405
|
-
add_tag :TT,
|
|
406
|
-
add_tag :EM,
|
|
422
|
+
add_tag :BOLD, "<strong>", "</strong>"
|
|
423
|
+
add_tag :TT, "<code>", "</code>"
|
|
424
|
+
add_tag :EM, "<em>", "</em>"
|
|
425
|
+
add_tag :STRIKE, "<del>", "</del>"
|
|
407
426
|
end
|
|
408
427
|
|
|
409
428
|
##
|
|
@@ -458,4 +477,153 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|
|
458
477
|
super convert_flow @am.flow item
|
|
459
478
|
end
|
|
460
479
|
|
|
480
|
+
private
|
|
481
|
+
|
|
482
|
+
def convert_flow(flow_items)
|
|
483
|
+
res = []
|
|
484
|
+
|
|
485
|
+
flow_items.each do |item|
|
|
486
|
+
case item
|
|
487
|
+
when String
|
|
488
|
+
append_flow_fragment res, convert_string(item)
|
|
489
|
+
when RDoc::Markup::AttrChanger
|
|
490
|
+
off_tags res, item
|
|
491
|
+
on_tags res, item
|
|
492
|
+
when RDoc::Markup::RegexpHandling
|
|
493
|
+
append_flow_fragment res, convert_regexp_handling(item)
|
|
494
|
+
else
|
|
495
|
+
raise "Unknown flow element: #{item.inspect}"
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
res.join
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def append_flow_fragment(res, fragment)
|
|
503
|
+
return if fragment.nil? || fragment.empty?
|
|
504
|
+
|
|
505
|
+
emit_tidy_link_fragment(res, fragment)
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def append_to_tidy_label(fragment)
|
|
509
|
+
@tidy_link_buffer << fragment
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
##
|
|
513
|
+
# Matches an entire tidy link with a braced label "{label}[url]".
|
|
514
|
+
#
|
|
515
|
+
# Capture 1: label contents.
|
|
516
|
+
# Capture 2: URL text.
|
|
517
|
+
# Capture 3: trailing content.
|
|
518
|
+
TIDY_LINK_WITH_BRACES = /\A\{(.*?)\}\[(.*?)\](.*)\z/
|
|
519
|
+
|
|
520
|
+
##
|
|
521
|
+
# Matches the tail of a braced tidy link when the opening brace was
|
|
522
|
+
# consumed earlier while accumulating the label text.
|
|
523
|
+
#
|
|
524
|
+
# Capture 1: remaining label content.
|
|
525
|
+
# Capture 2: URL text.
|
|
526
|
+
# Capture 3: trailing content.
|
|
527
|
+
TIDY_LINK_WITH_BRACES_TAIL = /\A(.*?)\}\[(.*?)\](.*)\z/
|
|
528
|
+
|
|
529
|
+
##
|
|
530
|
+
# Matches a tidy link with a single-word label "label[url]".
|
|
531
|
+
#
|
|
532
|
+
# Capture 1: the single-word label (no whitespace).
|
|
533
|
+
# Capture 2: URL text between the brackets.
|
|
534
|
+
TIDY_LINK_SINGLE_WORD = /\A(\S+)\[(.*?)\](.*)\z/
|
|
535
|
+
|
|
536
|
+
def convert_complete_tidy_link(text)
|
|
537
|
+
return text unless
|
|
538
|
+
text =~ TIDY_LINK_WITH_BRACES or text =~ TIDY_LINK_SINGLE_WORD
|
|
539
|
+
|
|
540
|
+
label = $1
|
|
541
|
+
url = CGI.escapeHTML($2)
|
|
542
|
+
|
|
543
|
+
label_html = if /^rdoc-image:/ =~ label
|
|
544
|
+
handle_RDOCLINK(label)
|
|
545
|
+
else
|
|
546
|
+
render_tidy_link_label(label)
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
gen_url url, label_html
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
def emit_tidy_link_fragment(res, fragment)
|
|
553
|
+
if tidy_link_capturing?
|
|
554
|
+
append_to_tidy_label fragment
|
|
555
|
+
else
|
|
556
|
+
res << fragment
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def finish_tidy_link(text)
|
|
561
|
+
label_tail, url, trailing = extract_tidy_link_parts(text)
|
|
562
|
+
append_to_tidy_label CGI.escapeHTML(label_tail) unless label_tail.empty?
|
|
563
|
+
|
|
564
|
+
return '' unless url
|
|
565
|
+
|
|
566
|
+
label_html = @tidy_link_buffer
|
|
567
|
+
@tidy_link_buffer = nil
|
|
568
|
+
link = gen_url(url, label_html)
|
|
569
|
+
|
|
570
|
+
return link if trailing.empty?
|
|
571
|
+
|
|
572
|
+
link + CGI.escapeHTML(trailing)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def extract_tidy_link_parts(text)
|
|
576
|
+
if text =~ TIDY_LINK_WITH_BRACES
|
|
577
|
+
[$1, CGI.escapeHTML($2), $3]
|
|
578
|
+
elsif text =~ TIDY_LINK_WITH_BRACES_TAIL
|
|
579
|
+
[$1, CGI.escapeHTML($2), $3]
|
|
580
|
+
elsif text =~ TIDY_LINK_SINGLE_WORD
|
|
581
|
+
[$1, CGI.escapeHTML($2), $3]
|
|
582
|
+
else
|
|
583
|
+
[text, nil, '']
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def on_tags(res, item)
|
|
588
|
+
each_attr_tag(item.turn_on) do |tag|
|
|
589
|
+
emit_tidy_link_fragment(res, annotate(tag.on))
|
|
590
|
+
@in_tt += 1 if tt? tag
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def off_tags(res, item)
|
|
595
|
+
each_attr_tag(item.turn_off, true) do |tag|
|
|
596
|
+
emit_tidy_link_fragment(res, annotate(tag.off))
|
|
597
|
+
@in_tt -= 1 if tt? tag
|
|
598
|
+
end
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
def start_tidy_link(text)
|
|
602
|
+
@tidy_link_buffer = String.new
|
|
603
|
+
append_to_tidy_label CGI.escapeHTML(text.delete_prefix('{'))
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def tidy_link_capturing?
|
|
607
|
+
!!@tidy_link_buffer
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def render_tidy_link_label(label)
|
|
611
|
+
RDoc::Markup::LinkLabelToHtml.render(label, @options, @from_path)
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
##
|
|
616
|
+
# Formatter dedicated to rendering tidy link labels without mutating the
|
|
617
|
+
# calling formatter's state.
|
|
618
|
+
|
|
619
|
+
class RDoc::Markup::LinkLabelToHtml < RDoc::Markup::ToHtml
|
|
620
|
+
def self.render(label, options, from_path)
|
|
621
|
+
new(options, from_path).to_html(label)
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
def initialize(options, from_path = nil)
|
|
625
|
+
super(options)
|
|
626
|
+
|
|
627
|
+
self.from_path = from_path if from_path
|
|
628
|
+
end
|
|
461
629
|
end
|
|
@@ -169,14 +169,33 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
if label
|
|
172
|
+
# Convert label to GitHub-style anchor format
|
|
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
|
|
172
179
|
if path =~ /#/
|
|
173
|
-
path << "
|
|
174
|
-
|
|
175
|
-
|
|
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
|
|
176
191
|
elsif ref.respond_to?(:aref)
|
|
177
|
-
path << "##{ref.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
|
|
178
197
|
else
|
|
179
|
-
path << "
|
|
198
|
+
path << "##{formatted_label}"
|
|
180
199
|
end
|
|
181
200
|
end
|
|
182
201
|
|
|
@@ -184,38 +203,35 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
184
203
|
end
|
|
185
204
|
end
|
|
186
205
|
|
|
187
|
-
def convert_flow(
|
|
206
|
+
def convert_flow(flow_items, &block)
|
|
188
207
|
res = []
|
|
189
208
|
|
|
190
209
|
i = 0
|
|
191
|
-
while i <
|
|
192
|
-
item =
|
|
193
|
-
|
|
210
|
+
while i < flow_items.size
|
|
211
|
+
item = flow_items[i]
|
|
212
|
+
|
|
194
213
|
case item
|
|
195
|
-
when RDoc::Markup::AttrChanger
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
tt_tag?(flow[i+1].turn_off, true) and
|
|
201
|
-
(@options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP).match?(str) and
|
|
202
|
-
(text = cross_reference str) != str
|
|
203
|
-
then
|
|
204
|
-
text = yield text, res if defined?(yield)
|
|
205
|
-
res << text
|
|
206
|
-
i += 2
|
|
214
|
+
when RDoc::Markup::AttrChanger
|
|
215
|
+
if !tidy_link_capturing? && (text = convert_tt_crossref(flow_items, i))
|
|
216
|
+
text = block.call(text, res) if block
|
|
217
|
+
append_flow_fragment res, text
|
|
218
|
+
i += 3
|
|
207
219
|
next
|
|
208
220
|
end
|
|
221
|
+
|
|
209
222
|
off_tags res, item
|
|
210
|
-
on_tags
|
|
211
|
-
|
|
223
|
+
on_tags res, item
|
|
224
|
+
i += 1
|
|
225
|
+
when String
|
|
212
226
|
text = convert_string(item)
|
|
213
|
-
text =
|
|
214
|
-
res
|
|
215
|
-
|
|
227
|
+
text = block.call(text, res) if block
|
|
228
|
+
append_flow_fragment res, text
|
|
229
|
+
i += 1
|
|
230
|
+
when RDoc::Markup::RegexpHandling
|
|
216
231
|
text = convert_regexp_handling(item)
|
|
217
|
-
text =
|
|
218
|
-
res
|
|
232
|
+
text = block.call(text, res) if block
|
|
233
|
+
append_flow_fragment res, text
|
|
234
|
+
i += 1
|
|
219
235
|
else
|
|
220
236
|
raise "Unknown flow element: #{item.inspect}"
|
|
221
237
|
end
|
|
@@ -223,4 +239,37 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|
|
223
239
|
|
|
224
240
|
res.join('')
|
|
225
241
|
end
|
|
242
|
+
|
|
243
|
+
private
|
|
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/)
|
|
269
|
+
|
|
270
|
+
text = cross_reference(string)
|
|
271
|
+
return if text == string
|
|
272
|
+
|
|
273
|
+
text
|
|
274
|
+
end
|
|
226
275
|
end
|
data/lib/rdoc/markup/to_label.rb
CHANGED
|
@@ -28,11 +28,21 @@ class RDoc::Markup::ToLabel < RDoc::Markup::Formatter
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
##
|
|
31
|
-
# Converts +text+ to an HTML-safe label
|
|
31
|
+
# Converts +text+ to an HTML-safe label using GitHub-style anchor formatting.
|
|
32
32
|
|
|
33
33
|
def convert(text)
|
|
34
34
|
label = convert_flow @am.flow text
|
|
35
35
|
|
|
36
|
+
RDoc::Text.to_anchor(label)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Converts +text+ to an HTML-safe label using legacy RDoc formatting.
|
|
41
|
+
# Used for generating backward-compatible anchor aliases.
|
|
42
|
+
|
|
43
|
+
def convert_legacy(text)
|
|
44
|
+
label = convert_flow @am.flow text
|
|
45
|
+
|
|
36
46
|
CGI.escape(label).gsub('%', '-').sub(/^-/, '')
|
|
37
47
|
end
|
|
38
48
|
|
data/lib/rdoc/markup/to_rdoc.rb
CHANGED
|
@@ -250,8 +250,10 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|
|
250
250
|
# Adds +table+ to the output
|
|
251
251
|
|
|
252
252
|
def accept_table(header, body, aligns)
|
|
253
|
+
header = header.map { |h| attributes h }
|
|
254
|
+
body = body.map { |row| row.map { |t| attributes t } }
|
|
253
255
|
widths = header.zip(*body).map do |cols|
|
|
254
|
-
cols.map(
|
|
256
|
+
cols.map { |col| calculate_text_width(col) }.max
|
|
255
257
|
end
|
|
256
258
|
aligns = aligns.map do |a|
|
|
257
259
|
case a
|
|
@@ -264,16 +266,22 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|
|
264
266
|
end
|
|
265
267
|
end
|
|
266
268
|
@res << header.zip(widths, aligns).map do |h, w, a|
|
|
267
|
-
h.
|
|
269
|
+
extra_width = h.size - calculate_text_width(h)
|
|
270
|
+
h.__send__(a, w + extra_width)
|
|
268
271
|
end.join("|").rstrip << "\n"
|
|
269
272
|
@res << widths.map {|w| "-" * w }.join("|") << "\n"
|
|
270
273
|
body.each do |row|
|
|
271
274
|
@res << row.zip(widths, aligns).map do |t, w, a|
|
|
272
|
-
t.
|
|
275
|
+
extra_width = t.size - calculate_text_width(t)
|
|
276
|
+
t.__send__(a, w + extra_width)
|
|
273
277
|
end.join("|").rstrip << "\n"
|
|
274
278
|
end
|
|
275
279
|
end
|
|
276
280
|
|
|
281
|
+
def calculate_text_width(text)
|
|
282
|
+
text.size
|
|
283
|
+
end
|
|
284
|
+
|
|
277
285
|
##
|
|
278
286
|
# Applies attribute-specific markup to +text+ using RDoc::AttributeManager
|
|
279
287
|
|
data/lib/rdoc/markup/verbatim.rb
CHANGED
data/lib/rdoc/markup.rb
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#
|
|
17
17
|
# - +rdoc+:
|
|
18
18
|
# the +RDoc+ markup format;
|
|
19
|
-
# see RDoc
|
|
19
|
+
# see {RDoc Markup Reference}[rdoc-ref:doc/markup_reference/rdoc.rdoc]
|
|
20
20
|
# - +markdown+:
|
|
21
21
|
# The +markdown+ markup format as described in
|
|
22
22
|
# the {Markdown Guide}[https://www.markdownguide.org];
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
#
|
|
103
103
|
# = \RDoc Markup Reference
|
|
104
104
|
#
|
|
105
|
-
# See RDoc
|
|
105
|
+
# See {RDoc Markup Reference}[rdoc-ref:doc/markup_reference/rdoc.rdoc]
|
|
106
106
|
#
|
|
107
107
|
#--
|
|
108
108
|
# Original Author:: Dave Thomas, dave@pragmaticprogrammer.com
|
|
@@ -210,6 +210,7 @@ https://github.com/ruby/rdoc/issues
|
|
|
210
210
|
autoload :BlankLine, "#{__dir__}/markup/blank_line"
|
|
211
211
|
autoload :BlockQuote, "#{__dir__}/markup/block_quote"
|
|
212
212
|
autoload :Document, "#{__dir__}/markup/document"
|
|
213
|
+
autoload :Element, "#{__dir__}/markup/element"
|
|
213
214
|
autoload :HardBreak, "#{__dir__}/markup/hard_break"
|
|
214
215
|
autoload :Heading, "#{__dir__}/markup/heading"
|
|
215
216
|
autoload :Include, "#{__dir__}/markup/include"
|