class RDoc::Markup::ToRdoc

Outputs RDoc markup as RDoc markup! (mostly)

Constants

DEFAULT_HEADINGS

Attributes

Current indent amount for output in characters

Stack of current list indexes for alphabetic and numeric lists

Stack of list types

Stack of list widths for indentation

Prefix for the next list item. See use_prefix

Output accumulator

Output width in characters

Public Class Methods

Creates a new formatter that will output (mostly) RDoc markup

Calls superclass method RDoc::Markup::Formatter::new
# File lib/rdoc/markup/to_rdoc.rb, line 55
def initialize(markup = nil)
  super nil, markup

  @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF)
  @width = 78
  init_tags

  @headings = DEFAULT_HEADINGS.dup
  @hard_break = "\n"
end

Public Instance Methods

Adds blank_line to the output

# File lib/rdoc/markup/to_rdoc.rb, line 78
def accept_blank_line(blank_line)
  @res << "\n"
end

Adds paragraph to the output

# File lib/rdoc/markup/to_rdoc.rb, line 85
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

# File lib/rdoc/markup/to_rdoc.rb, line 100
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

Adds paragraph to the output

# File lib/rdoc/markup/to_rdoc.rb, line 212
def accept_indented_paragraph(paragraph)
  @indent += paragraph.indent
  text = paragraph.text @hard_break
  wrap attributes text
  @indent -= paragraph.indent
end

Finishes consumption of list

# File lib/rdoc/markup/to_rdoc.rb, line 111
def accept_list_end(list)
  @list_index.pop
  @list_type.pop
  @list_width.pop
end

Finishes consumption of list_item

# File lib/rdoc/markup/to_rdoc.rb, line 120
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

# File lib/rdoc/markup/to_rdoc.rb, line 144
def accept_list_item_start(list_item)
  type = @list_type.last

  case type
  when :NOTE, :LABEL then
    stripped_labels = Array(list_item.label).map do |label|
      attributes(label).strip
    end

    bullets = case type
    when :NOTE
      stripped_labels.map { |b| "#{b}::" }
    when :LABEL
      stripped_labels.map { |b| "[#{b}]" }
    end

    bullets = bullets.join("\n")
    bullets << "\n" unless stripped_labels.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

# File lib/rdoc/markup/to_rdoc.rb, line 177
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

# File lib/rdoc/markup/to_rdoc.rb, line 204
def accept_paragraph(paragraph)
  text = paragraph.text @hard_break
  wrap attributes text
end

Adds raw to the output

# File lib/rdoc/markup/to_rdoc.rb, line 222
def accept_raw(raw)
  @res << raw.parts.join("\n")
end

Adds rule to the output

# File lib/rdoc/markup/to_rdoc.rb, line 229
def accept_rule(rule)
  use_prefix or @res << ' ' * @indent
  @res << '-' * (@width - @indent)
  @res << "\n"
end

Adds table to the output

# File lib/rdoc/markup/to_rdoc.rb, line 252
def accept_table(header, body, aligns)
  widths = header.zip(*body).map do |cols|
    cols.map(&:size).max
  end
  aligns = aligns.map do |a|
    case a
    when nil, :center
      :center
    when :left
      :ljust
    when :right
      :rjust
    end
  end
  @res << header.zip(widths, aligns).map 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).map do |t, w, a|
      t.__send__(a, w)
    end.join("|").rstrip << "\n"
  end
end

Outputs verbatim indented 2 columns

# File lib/rdoc/markup/to_rdoc.rb, line 238
def accept_verbatim(verbatim)
  indent = ' ' * (@indent + 2)

  verbatim.parts.each do |part|
    @res << indent unless part == "\n"
    @res << part
  end

  @res << "\n"
end

Applies attribute-specific markup to text using RDoc::AttributeManager

# File lib/rdoc/markup/to_rdoc.rb, line 280
def attributes(text)
  flow = @am.flow text.dup
  convert_flow flow
end

Returns the generated output

# File lib/rdoc/markup/to_rdoc.rb, line 288
def end_accepting
  @res.join
end

Adds a newline to the output

# File lib/rdoc/markup/to_rdoc.rb, line 304
def handle_regexp_HARD_BREAK(target)
  "\n"
end

Removes preceding \ from the suppressed crossref target

# File lib/rdoc/markup/to_rdoc.rb, line 295
def handle_regexp_SUPPRESSED_CROSSREF(target)
  text = target.text
  text = text.sub('\\', '') unless in_tt?
  text
end

Maps attributes to HTML sequences

# File lib/rdoc/markup/to_rdoc.rb, line 69
def init_tags
  add_tag :BOLD, "<b>", "</b>"
  add_tag :TT,   "<tt>", "</tt>"
  add_tag :EM,   "<em>", "</em>"
end

Prepares the visitor for text generation

# File lib/rdoc/markup/to_rdoc.rb, line 311
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.

# File lib/rdoc/markup/to_rdoc.rb, line 325
def use_prefix
  prefix, @prefix = @prefix, nil
  @res << prefix if prefix

  prefix
end

Wraps text to width

# File lib/rdoc/markup/to_rdoc.rb, line 335
def wrap(text)
  return unless text && !text.empty?

  text_len = @width - @indent

  text_len = 20 if text_len < 20

  next_prefix = ' ' * @indent

  prefix = @prefix || next_prefix
  @prefix = nil

  text.scan(/\G(?:([^ \n]{#{text_len}})(?=[^ \n])|(.{1,#{text_len}})(?:[ \n]|\z))/) do
    @res << prefix << ($1 || $2) << "\n"
    prefix = next_prefix
  end
end