1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/lib/rdoc/markup/to_rdoc.rb
nagachika 2a70d21484 merge revision(s) b1c73f239fe9af97de837331849f55d67c27561e,bb570ce6d80d28cfc7131dcb72885eed2f989b30,b88d1e6b44164bca0c2b85ea6639469813e1e1d8,127f735c1e5e0771076caf2a74390757a42fb177,f3f1a666c77f8c528b0adc9ccf78e4b9910bd6e0,fa048a0f8523cefde5428805dd334691486319e6,d5d1c41728d65acfb8aa2cf95f2d8ac88f271cd1,52ebaf718e6a78297ceb0dff49815eeed28eae45,7fe22152fc28084f4395fece84ff6e5eb2d6b288,19e6d271266eca5925e66fc8ec39b251a2fa6bcd,05898c5b9001c0b1e8bd7bf0d12b42a8e7c388b8,3651f678a719ae3a35825bcb4e0dabbc7c60d8df,10b082064e6ab0943cce4ef43e567d8044c7096d,de8e6218a3257fe19b46ff0aa157e66f452ac8b7,971a0cd246db6578e1ea8760a903e1a23e3681f3,61a29a41e1d0d11a9963315aa86d25ed690124c0,ff9a00887161840eb8a34d53749a7d7962181cfe,fad3412d475b57055f426cf4e86eafeab516672b,54aa11efa8b1be2c5d20402890d6d2fa90aa19a8,e84d275fe6d0c14ba58ce73b13323879c060b7ae,61e1cf23ac0d122fba3ad4cbaa402c7c94ad54d3,a6948329f8f89fb390215086fe4a888915fd589e,64b991b0cd98ee8f23266b8cbea0fa34bdaab1ec,b1c73f239fe9af97de837331849f55d67c27561e,0ee24b4fab1a1faef600a42c29863e1c3edd8c61: [Backport #17877]
Synchronize rdoc with upstream version v6.3.1.

	[ruby/rdoc] Use File.open to fix the OS Command Injection
	 vulnerability in CVE-2021-31799

	a7f5d6ab88
	---
	 lib/rdoc/rdoc.rb            |  2 +-
	 test/rdoc/test_rdoc_rdoc.rb | 12 ++++++++++++
	 2 files changed, 13 insertions(+), 1 deletion(-)

	[ruby/rdoc] Support ChangeLog generated by `git log`

	5e0a123ca1
	---
	 lib/rdoc/parser/changelog.rb            | 35 +++++++++++++++++++++
	 test/rdoc/test_rdoc_parser_changelog.rb | 56 +++++++++++++++++++++++++++++++++
	 2 files changed, 91 insertions(+)

	[ruby/rdoc] Make each commit entries h3

	11eefb2ae9
	---
	 lib/rdoc/parser/changelog.rb            | 12 ++++++------
	 test/rdoc/test_rdoc_parser_changelog.rb | 12 ++++--------
	 2 files changed, 10 insertions(+), 14 deletions(-)

	[ruby/rdoc] Tweak log entry markdown

	* add 3 levels to headings
	* prefix commit log to labels to make unique IDs

	5074c13209
	---
	 lib/rdoc/parser/changelog.rb            | 20 +++++++++++++++++-
	 test/rdoc/test_rdoc_parser_changelog.rb | 36 ++++++++++++++++++++++++++++++++-
	 2 files changed, 54 insertions(+), 2 deletions(-)

	[ruby/rdoc] Shorten commit hashes

	5d3e153963
	---
	 lib/rdoc/parser/changelog.rb            | 2 +-
	 test/rdoc/test_rdoc_parser_changelog.rb | 2 +-
	 2 files changed, 2 insertions(+), 2 deletions(-)

	[ruby/rdoc] Add links to the commits

	1821628076
	---
	 lib/rdoc/parser/changelog.rb            | 107 +++++++++++++++++++++++++-------
	 test/rdoc/test_rdoc_parser_changelog.rb |  36 ++++++-----
	 2 files changed, 107 insertions(+), 36 deletions(-)

	[ruby/rdoc] Sort by CommitDate if available

	455715e930
	---
	 lib/rdoc/parser/changelog.rb            | 11 ++++++---
	 test/rdoc/test_rdoc_parser_changelog.rb | 40 +++++++++++++++++++++++++++++++++
	 2 files changed, 48 insertions(+), 3 deletions(-)

	[ruby/rdoc] Skip non-date logs by git-log

	`RDoc::Parser::ChangeLog` mis-parses ChangeLog generated by
	git-log, because of too heuristic `Time.parse`.

	For instance, "commit 8187228de0"
	results in "8187-08-16", that is, day 228 in the year 8187.

	9711e6f6d9
	---
	 lib/rdoc/parser/changelog.rb            | 36 ++++++++++++++++++++-------------
	 test/rdoc/test_rdoc_parser_changelog.rb |  2 ++
	 2 files changed, 24 insertions(+), 14 deletions(-)

	[ruby/rdoc] Support other date formats in git-log

	ad8cf37d72
	---
	 lib/rdoc/parser/changelog.rb            |  6 +++---
	 test/rdoc/test_rdoc_parser_changelog.rb | 22 ++++++++++++++++++++++
	 2 files changed, 25 insertions(+), 3 deletions(-)

	[ruby/rdoc] Support iso-strict format in git-log

	2a6c22da63
	---
	 lib/rdoc/parser/changelog.rb            |  6 +++---
	 test/rdoc/test_rdoc_parser_changelog.rb | 11 +++++++++++
	 2 files changed, 14 insertions(+), 3 deletions(-)

	[ruby/rdoc] Update Rdoc.css sidebar panel.

	Updates css so the sidebar look like a panel instead of looking like chopped edges.

	b0098c6d72
	---
	 lib/rdoc/generator/template/darkfish/css/rdoc.css | 1 +
	 1 file changed, 1 insertion(+)

	[ruby/rdoc] Support GFM table

	9dc933df16
	---
	 lib/rdoc/markdown.rb                    | 349 +++++++++++++++++++++++++++++++-
	 lib/rdoc/markup.rb                      |   1 +
	 lib/rdoc/markup/table.rb                |  47 +++++
	 lib/rdoc/markup/to_html.rb              |  23 +++
	 lib/rdoc/markup/to_joined_paragraph.rb  |   1 +
	 lib/rdoc/markup/to_rdoc.rb              |  28 +++
	 lib/rdoc/markup/to_table_of_contents.rb |   1 +
	 test/rdoc/test_rdoc_markdown.rb         |  23 +++
	 8 files changed, 471 insertions(+), 2 deletions(-)
	 create mode 100644 lib/rdoc/markup/table.rb

	[ruby/rdoc] Add table style

	2219c5ae80
	---
	 lib/rdoc/generator/template/darkfish/css/rdoc.css | 19 +++++++++++++++++++
	 1 file changed, 19 insertions(+)

	[ruby/rdoc] Fixed CodeFence without blank lines

	Currently a fenced code block needs a preceding blank line, it
	should not be required, as:
	https://github.github.com/gfm/#fenced-code-blocks
	> A fenced code block may interrupt a paragraph, and does not
	> require a blank line either before or after.

	Just recommended:
	https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks
	> We recommend placing a blank line before and after code blocks
	> to make the raw formatting easier to read.

	0e1776caf3
	---
	 lib/rdoc/markdown.rb            | 447 +++++++---------------------------------
	 test/rdoc/test_rdoc_markdown.rb |  36 +++-
	 2 files changed, 112 insertions(+), 371 deletions(-)

	[ruby/rdoc] Allow partial default values to be overridden with
	 .rdoc_options

	e14800891f
	---
	 lib/rdoc/options.rb         | 34 +++++++++++++++++++++++++++++++++-
	 lib/rdoc/rdoc.rb            |  7 ++++++-
	 test/rdoc/test_rdoc_rdoc.rb | 12 ++++++++++++
	 3 files changed, 51 insertions(+), 2 deletions(-)

	[ruby/rdoc] Allow empty .rdoc_options

	0c8cb25b50
	---
	 lib/rdoc/rdoc.rb            |  2 ++
	 test/rdoc/test_rdoc_rdoc.rb | 11 +++++++++++
	 2 files changed, 13 insertions(+)

	[ruby/rdoc] Suppress unused variable warning of "text"

	3a4120b155
	---
	 lib/rdoc/markdown.rb | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++-
	 1 file changed, 343 insertions(+), 2 deletions(-)

	[ruby/rdoc] Get rid of a trailing space

	7b7b91768e
	---
	 lib/rdoc/markdown.rb | 7 +++----
	 1 file changed, 3 insertions(+), 4 deletions(-)

	[ruby/rdoc] Disable other notations in <code> tags

	0cd3b55210
	---
	 lib/rdoc/markup/attr_span.rb                    |  10 ++-
	 lib/rdoc/markup/attribute_manager.rb            | 102 ++++++++++++++++++------
	 test/rdoc/test_rdoc_markup_attribute_manager.rb |  24 +++++-
	 test/rdoc/test_rdoc_markup_to_html.rb           |   6 ++
	 4 files changed, 114 insertions(+), 28 deletions(-)

	[ruby/rdoc] Treat other tags as word boundaries

	8222f85a17
	---
	 lib/rdoc/markup/attribute_manager.rb  | 17 +++++++++++++----
	 test/rdoc/test_rdoc_markup_to_html.rb |  5 +++++
	 2 files changed, 18 insertions(+), 4 deletions(-)

	[ruby/rdoc] Treat emphasis tags as excluding other notations

	And exclusive notations don't exclude other exclusive notations.

	b8baa9a435
	---
	 lib/rdoc/markup/attr_span.rb                    |  2 +-
	 lib/rdoc/markup/attribute_manager.rb            | 10 +++++-----
	 test/rdoc/test_rdoc_markup_attribute_manager.rb |  1 +
	 3 files changed, 7 insertions(+), 6 deletions(-)

	[ruby/rdoc] Clarify that dots in URL are replaced

	The dots in all path components from the document root are
	replaced with underscores, not only in the basename.

	7a3417ea4c
	---
	 test/rdoc/test_rdoc_top_level.rb | 3 +++
	 1 file changed, 3 insertions(+)

	[ruby/rdoc] Links to document texts without "rdoc-ref:" prefix

	While links to generated HTML from RDoc file needs to be prefixed
	by "rdoc-ref:" currently, in case of explicit references this
	seems just redundant.

	Also GitHub RDoc support does not work with this prefix.

	This patch lets links to such document texts (".rb", ".rdoc" and
	".md" now) refer URLs generated by `RDoc::TopLevel#http_url`
	without the prefix.

	f18b27b69d
	---
	 lib/rdoc/markup/to_html.rb            |  4 ++++
	 test/rdoc/test_rdoc_markup_to_html.rb | 21 +++++++++++++++++++++
	 2 files changed, 25 insertions(+)

	[ruby/rdoc] Use File.open to fix the OS Command Injection
	 vulnerability in CVE-2021-31799

	a7f5d6ab88
	---
	 lib/rdoc/rdoc.rb            |  2 +-
	 test/rdoc/test_rdoc_rdoc.rb | 12 ++++++++++++
	 2 files changed, 13 insertions(+), 1 deletion(-)

	[ruby/rdoc] Version 6.3.1

	9307f932b7
	---
	 lib/rdoc/version.rb | 2 +-
	 1 file changed, 1 insertion(+), 1 deletion(-)
2021-05-22 14:51:55 +09:00

362 lines
6.7 KiB
Ruby

# frozen_string_literal: true
##
# Outputs RDoc markup as RDoc markup! (mostly)
class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
##
# Current indent amount for output in characters
attr_accessor :indent
##
# Output width in characters
attr_accessor :width
##
# Stack of current list indexes for alphabetic and numeric lists
attr_reader :list_index
##
# Stack of list types
attr_reader :list_type
##
# Stack of list widths for indentation
attr_reader :list_width
##
# Prefix for the next list item. See #use_prefix
attr_reader :prefix
##
# Output accumulator
attr_reader :res
##
# Creates a new formatter that will output (mostly) \RDoc markup
def initialize markup = nil
super nil, markup
@markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF)
@width = 78
init_tags
@headings = {}
@headings.default = []
@headings[1] = ['= ', '']
@headings[2] = ['== ', '']
@headings[3] = ['=== ', '']
@headings[4] = ['==== ', '']
@headings[5] = ['===== ', '']
@headings[6] = ['====== ', '']
@hard_break = "\n"
end
##
# Maps attributes to HTML sequences
def init_tags
add_tag :BOLD, "<b>", "</b>"
add_tag :TT, "<tt>", "</tt>"
add_tag :EM, "<em>", "</em>"
end
##
# Adds +blank_line+ to the output
def accept_blank_line blank_line
@res << "\n"
end
##
# Adds +paragraph+ to the output
def accept_block_quote block_quote
@indent += 2
block_quote.parts.each do |part|
@prefix = '> '
part.accept self
end
@indent -= 2
end
##
# Adds +heading+ to the output
def accept_heading heading
use_prefix or @res << ' ' * @indent
@res << @headings[heading.level][0]
@res << attributes(heading.text)
@res << @headings[heading.level][1]
@res << "\n"
end
##
# Finishes consumption of +list+
def accept_list_end list
@list_index.pop
@list_type.pop
@list_width.pop
end
##
# Finishes consumption of +list_item+
def accept_list_item_end list_item
width = case @list_type.last
when :BULLET then
2
when :NOTE, :LABEL then
if @prefix then
@res << @prefix.strip
@prefix = nil
end
@res << "\n"
2
else
bullet = @list_index.last.to_s
@list_index[-1] = @list_index.last.succ
bullet.length + 2
end
@indent -= width
end
##
# Prepares the visitor for consuming +list_item+
def accept_list_item_start list_item
type = @list_type.last
case type
when :NOTE, :LABEL then
bullets = Array(list_item.label).map do |label|
attributes(label).strip
end.join "\n"
bullets << ":\n" unless bullets.empty?
@prefix = ' ' * @indent
@indent += 2
@prefix << bullets + (' ' * @indent)
else
bullet = type == :BULLET ? '*' : @list_index.last.to_s + '.'
@prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1)
width = bullet.length + 1
@indent += width
end
end
##
# Prepares the visitor for consuming +list+
def accept_list_start list
case list.type
when :BULLET then
@list_index << nil
@list_width << 1
when :LABEL, :NOTE then
@list_index << nil
@list_width << 2
when :LALPHA then
@list_index << 'a'
@list_width << list.items.length.to_s.length
when :NUMBER then
@list_index << 1
@list_width << list.items.length.to_s.length
when :UALPHA then
@list_index << 'A'
@list_width << list.items.length.to_s.length
else
raise RDoc::Error, "invalid list type #{list.type}"
end
@list_type << list.type
end
##
# Adds +paragraph+ to the output
def accept_paragraph paragraph
text = paragraph.text @hard_break
wrap attributes text
end
##
# Adds +paragraph+ to the output
def accept_indented_paragraph paragraph
@indent += paragraph.indent
text = paragraph.text @hard_break
wrap attributes text
@indent -= paragraph.indent
end
##
# Adds +raw+ to the output
def accept_raw raw
@res << raw.parts.join("\n")
end
##
# Adds +rule+ to the output
def accept_rule rule
use_prefix or @res << ' ' * @indent
@res << '-' * (@width - @indent)
@res << "\n"
end
##
# Outputs +verbatim+ indented 2 columns
def accept_verbatim verbatim
indent = ' ' * (@indent + 2)
verbatim.parts.each do |part|
@res << indent unless part == "\n"
@res << part
end
@res << "\n"
end
##
# Adds +table+ to the output
def accept_table header, body, aligns
widths = header.zip(body) do |h, b|
[h.size, b.size].max
end
aligns = aligns.map do |a|
case a
when nil
:center
when :left
:ljust
when :right
:rjust
end
end
@res << header.zip(widths, aligns) do |h, w, a|
h.__send__(a, w)
end.join("|").rstrip << "\n"
@res << widths.map {|w| "-" * w }.join("|") << "\n"
body.each do |row|
@res << row.zip(widths, aligns) do |t, w, a|
t.__send__(a, w)
end.join("|").rstrip << "\n"
end
end
##
# Applies attribute-specific markup to +text+ using RDoc::AttributeManager
def attributes text
flow = @am.flow text.dup
convert_flow flow
end
##
# Returns the generated output
def end_accepting
@res.join
end
##
# Removes preceding \\ from the suppressed crossref +target+
def handle_regexp_SUPPRESSED_CROSSREF target
text = target.text
text = text.sub('\\', '') unless in_tt?
text
end
##
# Adds a newline to the output
def handle_regexp_HARD_BREAK target
"\n"
end
##
# Prepares the visitor for text generation
def start_accepting
@res = [""]
@indent = 0
@prefix = nil
@list_index = []
@list_type = []
@list_width = []
end
##
# Adds the stored #prefix to the output and clears it. Lists generate a
# prefix for later consumption.
def use_prefix
prefix, @prefix = @prefix, nil
@res << prefix if prefix
prefix
end
##
# Wraps +text+ to #width
def wrap text
return unless text && !text.empty?
text_len = @width - @indent
text_len = 20 if text_len < 20
re = /^(.{0,#{text_len}})[ \n]/
next_prefix = ' ' * @indent
prefix = @prefix || next_prefix
@prefix = nil
@res << prefix
while text.length > text_len
if text =~ re then
@res << $1
text.slice!(0, $&.length)
else
@res << text.slice!(0, text_len)
end
@res << "\n" << next_prefix
end
if text.empty? then
@res.pop
@res.pop
else
@res << text
@res << "\n"
end
end
end