mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
244 lines
4.7 KiB
Ruby
244 lines
4.7 KiB
Ruby
|
require 'rdoc/markup/inline'
|
||
|
|
||
|
##
|
||
|
# Outputs RDoc markup as RDoc markup! (mostly)
|
||
|
|
||
|
class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
||
|
|
||
|
attr_accessor :indent
|
||
|
attr_reader :list_index
|
||
|
attr_reader :list_type
|
||
|
attr_reader :list_width
|
||
|
attr_reader :prefix
|
||
|
attr_reader :res
|
||
|
|
||
|
def initialize
|
||
|
super
|
||
|
|
||
|
@markup.add_special(/\\[^\s]/, :SUPPRESSED_CROSSREF)
|
||
|
|
||
|
@width = 78
|
||
|
@prefix = ''
|
||
|
|
||
|
init_tags
|
||
|
|
||
|
@headings = {}
|
||
|
@headings.default = []
|
||
|
|
||
|
@headings[1] = ['= ', '']
|
||
|
@headings[2] = ['== ', '']
|
||
|
@headings[3] = ['=== ', '']
|
||
|
@headings[4] = ['==== ', '']
|
||
|
@headings[5] = ['===== ', '']
|
||
|
@headings[6] = ['====== ', '']
|
||
|
end
|
||
|
|
||
|
##
|
||
|
# Maps attributes to ANSI sequences
|
||
|
|
||
|
def init_tags
|
||
|
add_tag :BOLD, "<b>", "</b>"
|
||
|
add_tag :TT, "<tt>", "</tt>"
|
||
|
add_tag :EM, "<em>", "</em>"
|
||
|
end
|
||
|
|
||
|
def accept_blank_line blank_line
|
||
|
@res << "\n"
|
||
|
end
|
||
|
|
||
|
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
|
||
|
|
||
|
def accept_list_end list
|
||
|
@list_index.pop
|
||
|
@list_type.pop
|
||
|
@list_width.pop
|
||
|
end
|
||
|
|
||
|
def accept_list_item_end list_item
|
||
|
width = case @list_type.last
|
||
|
when :BULLET then
|
||
|
2
|
||
|
when :NOTE, :LABEL then
|
||
|
@res << "\n"
|
||
|
2
|
||
|
else
|
||
|
bullet = @list_index.last.to_s
|
||
|
@list_index[-1] = @list_index.last.succ
|
||
|
bullet.length + 2
|
||
|
end
|
||
|
|
||
|
@indent -= width
|
||
|
end
|
||
|
|
||
|
def accept_list_item_start list_item
|
||
|
bullet = case @list_type.last
|
||
|
when :BULLET then
|
||
|
'*'
|
||
|
when :NOTE, :LABEL then
|
||
|
attributes(list_item.label) + ":\n"
|
||
|
else
|
||
|
@list_index.last.to_s + '.'
|
||
|
end
|
||
|
|
||
|
case @list_type.last
|
||
|
when :NOTE, :LABEL then
|
||
|
@indent += 2
|
||
|
@prefix = bullet + (' ' * @indent)
|
||
|
else
|
||
|
@prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1)
|
||
|
|
||
|
width = bullet.length + 1
|
||
|
|
||
|
@indent += width
|
||
|
end
|
||
|
end
|
||
|
|
||
|
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
|
||
|
|
||
|
def accept_paragraph paragraph
|
||
|
wrap attributes(paragraph.text)
|
||
|
end
|
||
|
|
||
|
def accept_rule rule
|
||
|
use_prefix or @res << ' ' * @indent
|
||
|
@res << '-' * (@width - @indent)
|
||
|
@res << "\n"
|
||
|
end
|
||
|
|
||
|
##
|
||
|
# Outputs +verbatim+ flush left and indented 2 columns
|
||
|
|
||
|
def accept_verbatim verbatim
|
||
|
indent = ' ' * (@indent + 2)
|
||
|
|
||
|
lines = []
|
||
|
current_line = []
|
||
|
|
||
|
# split into lines
|
||
|
verbatim.parts.each do |part|
|
||
|
current_line << part
|
||
|
|
||
|
if part == "\n" then
|
||
|
lines << current_line
|
||
|
current_line = []
|
||
|
end
|
||
|
end
|
||
|
|
||
|
lines << current_line unless current_line.empty?
|
||
|
|
||
|
# calculate margin
|
||
|
indented = lines.select { |line| line != ["\n"] }
|
||
|
margin = indented.map { |line| line.first.length }.min
|
||
|
|
||
|
# flush left
|
||
|
indented.each { |line| line[0][0...margin] = '' }
|
||
|
|
||
|
# output
|
||
|
use_prefix or @res << indent # verbatim is unlikely to have prefix
|
||
|
@res << lines.shift.join
|
||
|
|
||
|
lines.each do |line|
|
||
|
@res << indent unless line == ["\n"]
|
||
|
@res << line.join
|
||
|
end
|
||
|
|
||
|
@res << "\n"
|
||
|
end
|
||
|
|
||
|
def attributes text
|
||
|
flow = @am.flow text.dup
|
||
|
convert_flow flow
|
||
|
end
|
||
|
|
||
|
def end_accepting
|
||
|
@res.join
|
||
|
end
|
||
|
|
||
|
def handle_special_SUPPRESSED_CROSSREF special
|
||
|
special.text.sub(/\\/, '')
|
||
|
end
|
||
|
|
||
|
def start_accepting
|
||
|
@res = [""]
|
||
|
@indent = 0
|
||
|
@prefix = nil
|
||
|
|
||
|
@list_index = []
|
||
|
@list_type = []
|
||
|
@list_width = []
|
||
|
end
|
||
|
|
||
|
def use_prefix
|
||
|
prefix = @prefix
|
||
|
@prefix = nil
|
||
|
@res << prefix if prefix
|
||
|
|
||
|
prefix
|
||
|
end
|
||
|
|
||
|
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
|
||
|
|