Class: RDoc::Markup::ToAnsi

Inherits:
Markup::ToRdoc
  • Object
show all
Defined in:
lib/rdoc/markup/to_ansi.rb

Overview

Outputs RDoc markup with vibrant ANSI color!

Constant Summary collapse

ANSI_STYLE_CODES_ON =

Maps attributes to ANSI sequences

{
  BOLD: 1,
  TT: 7,
  EM: 4,
  STRIKE: 9
}
ANSI_STYLE_CODES_OFF =
{
  BOLD: 22,
  TT: 27,
  EM: 24,
  STRIKE: 29
}

Instance Method Summary collapse

Constructor Details

#initialize ⇒ ToAnsi

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



12
13
14
15
16
17
18
19
# 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

Instance Method Details

#accept_list_item_end(list_item) ⇒ Object

Overrides indent width to ensure output lines up correctly.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 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

#accept_list_item_start(list_item) ⇒ Object

Adds coloring to note and label list items



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# 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

#add_text(text) ⇒ Object



61
62
63
64
65
66
67
# 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_attributes(attributes) ⇒ Object

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.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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

#calculate_text_width(text) ⇒ Object



133
134
135
# File 'lib/rdoc/markup/to_ansi.rb', line 133

def calculate_text_width(text)
  text.gsub(/\e\[[\d;]*m/, '').size
end

#handle_inline(text) ⇒ Object



69
70
71
72
73
74
75
# 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

#start_accepting ⇒ Object

Starts accepting with a reset screen



140
141
142
143
144
# File 'lib/rdoc/markup/to_ansi.rb', line 140

def start_accepting
  super

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