Chris@909
|
1 module CodeRay
|
Chris@909
|
2 module Encoders
|
Chris@909
|
3
|
Chris@909
|
4 # Outputs code highlighted for a color terminal.
|
Chris@909
|
5 #
|
Chris@909
|
6 # Note: This encoder is in beta. It currently doesn't use the Styles.
|
Chris@909
|
7 #
|
Chris@909
|
8 # Alias: +term+
|
Chris@909
|
9 #
|
Chris@909
|
10 # == Authors & License
|
Chris@909
|
11 #
|
Chris@909
|
12 # By Rob Aldred (http://robaldred.co.uk)
|
Chris@909
|
13 #
|
Chris@909
|
14 # Based on idea by Nathan Weizenbaum (http://nex-3.com)
|
Chris@909
|
15 #
|
Chris@909
|
16 # MIT License (http://www.opensource.org/licenses/mit-license.php)
|
Chris@909
|
17 class Terminal < Encoder
|
Chris@909
|
18
|
Chris@909
|
19 register_for :terminal
|
Chris@909
|
20
|
Chris@909
|
21 TOKEN_COLORS = {
|
Chris@909
|
22 :annotation => '35',
|
Chris@909
|
23 :attribute_name => '33',
|
Chris@909
|
24 :attribute_value => '31',
|
Chris@909
|
25 :binary => '1;35',
|
Chris@909
|
26 :char => {
|
Chris@909
|
27 :self => '36', :delimiter => '34'
|
Chris@909
|
28 },
|
Chris@909
|
29 :class => '1;35',
|
Chris@909
|
30 :class_variable => '36',
|
Chris@909
|
31 :color => '32',
|
Chris@909
|
32 :comment => '37',
|
Chris@909
|
33 :complex => '34',
|
Chris@909
|
34 :constant => ['34', '4'],
|
Chris@909
|
35 :decoration => '35',
|
Chris@909
|
36 :definition => '1;32',
|
Chris@909
|
37 :directive => ['32', '4'],
|
Chris@909
|
38 :doc => '46',
|
Chris@909
|
39 :doctype => '1;30',
|
Chris@909
|
40 :doc_string => ['31', '4'],
|
Chris@909
|
41 :entity => '33',
|
Chris@909
|
42 :error => ['1;33', '41'],
|
Chris@909
|
43 :exception => '1;31',
|
Chris@909
|
44 :float => '1;35',
|
Chris@909
|
45 :function => '1;34',
|
Chris@909
|
46 :global_variable => '42',
|
Chris@909
|
47 :hex => '1;36',
|
Chris@909
|
48 :include => '33',
|
Chris@909
|
49 :integer => '1;34',
|
Chris@909
|
50 :key => '35',
|
Chris@909
|
51 :label => '1;15',
|
Chris@909
|
52 :local_variable => '33',
|
Chris@909
|
53 :octal => '1;35',
|
Chris@909
|
54 :operator_name => '1;29',
|
Chris@909
|
55 :predefined_constant => '1;36',
|
Chris@909
|
56 :predefined_type => '1;30',
|
Chris@909
|
57 :predefined => ['4', '1;34'],
|
Chris@909
|
58 :preprocessor => '36',
|
Chris@909
|
59 :pseudo_class => '34',
|
Chris@909
|
60 :regexp => {
|
Chris@909
|
61 :self => '31',
|
Chris@909
|
62 :content => '31',
|
Chris@909
|
63 :delimiter => '1;29',
|
Chris@909
|
64 :modifier => '35',
|
Chris@909
|
65 :function => '1;29'
|
Chris@909
|
66 },
|
Chris@909
|
67 :reserved => '1;31',
|
Chris@909
|
68 :shell => {
|
Chris@909
|
69 :self => '42',
|
Chris@909
|
70 :content => '1;29',
|
Chris@909
|
71 :delimiter => '37',
|
Chris@909
|
72 },
|
Chris@909
|
73 :string => {
|
Chris@909
|
74 :self => '32',
|
Chris@909
|
75 :modifier => '1;32',
|
Chris@909
|
76 :escape => '1;36',
|
Chris@909
|
77 :delimiter => '1;32',
|
Chris@909
|
78 },
|
Chris@909
|
79 :symbol => '1;32',
|
Chris@909
|
80 :tag => '34',
|
Chris@909
|
81 :type => '1;34',
|
Chris@909
|
82 :value => '36',
|
Chris@909
|
83 :variable => '34',
|
Chris@909
|
84
|
Chris@909
|
85 :insert => '42',
|
Chris@909
|
86 :delete => '41',
|
Chris@909
|
87 :change => '44',
|
Chris@909
|
88 :head => '45'
|
Chris@909
|
89 }
|
Chris@909
|
90 TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved]
|
Chris@909
|
91 TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
|
Chris@909
|
92 TOKEN_COLORS[:imaginary] = TOKEN_COLORS[:complex]
|
Chris@909
|
93 TOKEN_COLORS[:begin_group] = TOKEN_COLORS[:end_group] =
|
Chris@909
|
94 TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
|
Chris@909
|
95
|
Chris@909
|
96 protected
|
Chris@909
|
97
|
Chris@909
|
98 def setup(options)
|
Chris@909
|
99 super
|
Chris@909
|
100 @opened = []
|
Chris@909
|
101 @subcolors = nil
|
Chris@909
|
102 end
|
Chris@909
|
103
|
Chris@909
|
104 public
|
Chris@909
|
105
|
Chris@909
|
106 def text_token text, kind
|
Chris@909
|
107 if color = (@subcolors || TOKEN_COLORS)[kind]
|
Chris@909
|
108 if Hash === color
|
Chris@909
|
109 if color[:self]
|
Chris@909
|
110 color = color[:self]
|
Chris@909
|
111 else
|
Chris@909
|
112 @out << text
|
Chris@909
|
113 return
|
Chris@909
|
114 end
|
Chris@909
|
115 end
|
Chris@909
|
116
|
Chris@909
|
117 @out << ansi_colorize(color)
|
Chris@909
|
118 @out << text.gsub("\n", ansi_clear + "\n" + ansi_colorize(color))
|
Chris@909
|
119 @out << ansi_clear
|
Chris@909
|
120 @out << ansi_colorize(@subcolors[:self]) if @subcolors && @subcolors[:self]
|
Chris@909
|
121 else
|
Chris@909
|
122 @out << text
|
Chris@909
|
123 end
|
Chris@909
|
124 end
|
Chris@909
|
125
|
Chris@909
|
126 def begin_group kind
|
Chris@909
|
127 @opened << kind
|
Chris@909
|
128 @out << open_token(kind)
|
Chris@909
|
129 end
|
Chris@909
|
130 alias begin_line begin_group
|
Chris@909
|
131
|
Chris@909
|
132 def end_group kind
|
Chris@909
|
133 if @opened.empty?
|
Chris@909
|
134 # nothing to close
|
Chris@909
|
135 else
|
Chris@909
|
136 @opened.pop
|
Chris@909
|
137 @out << ansi_clear
|
Chris@909
|
138 @out << open_token(@opened.last)
|
Chris@909
|
139 end
|
Chris@909
|
140 end
|
Chris@909
|
141
|
Chris@909
|
142 def end_line kind
|
Chris@909
|
143 if @opened.empty?
|
Chris@909
|
144 # nothing to close
|
Chris@909
|
145 else
|
Chris@909
|
146 @opened.pop
|
Chris@909
|
147 # whole lines to be highlighted,
|
Chris@909
|
148 # eg. added/modified/deleted lines in a diff
|
Chris@909
|
149 @out << "\t" * 100 + ansi_clear
|
Chris@909
|
150 @out << open_token(@opened.last)
|
Chris@909
|
151 end
|
Chris@909
|
152 end
|
Chris@909
|
153
|
Chris@909
|
154 private
|
Chris@909
|
155
|
Chris@909
|
156 def open_token kind
|
Chris@909
|
157 if color = TOKEN_COLORS[kind]
|
Chris@909
|
158 if Hash === color
|
Chris@909
|
159 @subcolors = color
|
Chris@909
|
160 ansi_colorize(color[:self]) if color[:self]
|
Chris@909
|
161 else
|
Chris@909
|
162 @subcolors = {}
|
Chris@909
|
163 ansi_colorize(color)
|
Chris@909
|
164 end
|
Chris@909
|
165 else
|
Chris@909
|
166 @subcolors = nil
|
Chris@909
|
167 ''
|
Chris@909
|
168 end
|
Chris@909
|
169 end
|
Chris@909
|
170
|
Chris@909
|
171 def ansi_colorize(color)
|
Chris@909
|
172 Array(color).map { |c| "\e[#{c}m" }.join
|
Chris@909
|
173 end
|
Chris@909
|
174 def ansi_clear
|
Chris@909
|
175 ansi_colorize(0)
|
Chris@909
|
176 end
|
Chris@909
|
177 end
|
Chris@909
|
178 end
|
Chris@909
|
179 end |