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