class RDoc::Markup::ToAnsi

Outputs RDoc markup with vibrant ANSI color!

Constants

ANSI_STYLE_CODES_OFF
ANSI_STYLE_CODES_ON

Maps attributes to ANSI sequences

Public Class Methods

Creates a new ToAnsi visitor that is ready to output vibrant ANSI color!

Calls superclass method RDoc::Markup::ToRdoc::new
# File lib/rdoc/markup/to_ansi.rb, line 12
def initialize
  super

  @headings.clear
  @headings[1] = ["\e[1;32m", "\e[m"] # bold
  @headings[2] = ["\e[4;32m", "\e[m"] # underline
  @headings[3] = ["\e[32m",   "\e[m"] # just green
end

Public Instance Methods

Overrides indent width to ensure output lines up correctly.

# File lib/rdoc/markup/to_ansi.rb, line 80
def accept_list_item_end(list_item)
  width = case @list_type.last
          when :BULLET
            2
          when :NOTE, :LABEL
            if @prefix
              @res << @prefix.strip
              @prefix = nil
            end

            @res << "\n" unless res.length == 1
            2
          else
            bullet = @list_index.last.to_s
            @list_index[-1] = @list_index.last.succ
            bullet.length + 2
          end

  @indent -= width
end

Adds coloring to note and label list items

# File lib/rdoc/markup/to_ansi.rb, line 104
def accept_list_item_start(list_item)
  bullet = case @list_type.last
           when :BULLET
             '*'
           when :NOTE, :LABEL
             labels = Array(list_item.label).map do |label|
               attributes(label).strip
             end.join "\n"

             labels << ":\n" unless labels.empty?

             labels
           else
             @list_index.last.to_s + '.'
           end

  case @list_type.last
  when :NOTE, :LABEL
    @indent += 2
    @prefix = bullet + (' ' * @indent)
  else
    @prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1)

    width = bullet.gsub(/\e\[[\d;]*m/, '').length + 1

    @indent += width
  end
end
# File lib/rdoc/markup/to_ansi.rb, line 61
def add_text(text)
  attrs = @attributes.keys
  if @applied_attributes != attrs
    apply_attributes(attrs)
  end
  emit_inline(text)
end

Apply the given attributes by emitting ANSI sequences. Emitting attribute changes are deferred until new text is added and applied in batch. This method computes the necessary ANSI codes to transition from the current set of applied attributes to the new set of attributes.

# File lib/rdoc/markup/to_ansi.rb, line 43
def apply_attributes(attributes)
  before = @applied_attributes
  after = attributes.sort
  return if before == after

  if after.empty?
    emit_inline("\e[m")
  elsif !before.empty? && before.size > (before & after).size + 1
    codes = after.map {|attr| ANSI_STYLE_CODES_ON[attr] }.compact
    emit_inline("\e[#{[0, *codes].join(';')}m")
  else
    off_codes = (before - after).map {|attr| ANSI_STYLE_CODES_OFF[attr] }.compact
    on_codes = (after - before).map {|attr| ANSI_STYLE_CODES_ON[attr] }.compact
    emit_inline("\e[#{(off_codes + on_codes).join(';')}m")
  end
  @applied_attributes = attributes
end
# File lib/rdoc/markup/to_ansi.rb, line 133
def calculate_text_width(text)
  text.gsub(/\e\[[\d;]*m/, '').size
end
Calls superclass method RDoc::Markup::ToRdoc#handle_inline
# File lib/rdoc/markup/to_ansi.rb, line 69
def handle_inline(text)
  @applied_attributes = []
  res = super
  res << "\e[m" unless @applied_attributes.empty?
  @applied_attributes = []
  res
end

Starts accepting with a reset screen

Calls superclass method RDoc::Markup::ToRdoc#start_accepting
# File lib/rdoc/markup/to_ansi.rb, line 140
def start_accepting
  super

  @res = ["\e[0m"]
end