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 10
def initialize(markup = nil)
  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 78
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" 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 102
def accept_list_item_start(list_item)
  bullet = case @list_type.last
           when :BULLET then
             '*'
           when :NOTE, :LABEL then
             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 then
    @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 59
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 41
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 131
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 67
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 138
def start_accepting
  super

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