彩色ruby输出
是否有一个gem执行背景和前景文本着色terminal输出?
我记得,在编程Pascal时,我们都习惯使用textcolor(...)
程序来使我们的小型教育程序看起来更漂亮,更具有performance力。
Ruby中有类似的东西吗?
着色是我最喜欢的gem! 🙂
一探究竟:
https://github.com/fazibear/colorize
安装:
gem install colorize
用法:
require 'colorize' puts "I am now red".red puts "I am now blue".blue puts "Testing".yellow
结合上面的答案,你可以实现一些像gem着色一样的工作,而不需要另外的依赖。
class String # colorization def colorize(color_code) "\e[#{color_code}m#{self}\e[0m" end def red colorize(31) end def green colorize(32) end def yellow colorize(33) end def blue colorize(34) end def pink colorize(35) end def light_blue colorize(36) end end
作为String类方法(仅限于unix):
class String def black; "\e[30m#{self}\e[0m" end def red; "\e[31m#{self}\e[0m" end def green; "\e[32m#{self}\e[0m" end def brown; "\e[33m#{self}\e[0m" end def blue; "\e[34m#{self}\e[0m" end def magenta; "\e[35m#{self}\e[0m" end def cyan; "\e[36m#{self}\e[0m" end def gray; "\e[37m#{self}\e[0m" end def bg_black; "\e[40m#{self}\e[0m" end def bg_red; "\e[41m#{self}\e[0m" end def bg_green; "\e[42m#{self}\e[0m" end def bg_brown; "\e[43m#{self}\e[0m" end def bg_blue; "\e[44m#{self}\e[0m" end def bg_magenta; "\e[45m#{self}\e[0m" end def bg_cyan; "\e[46m#{self}\e[0m" end def bg_gray; "\e[47m#{self}\e[0m" end def bold; "\e[1m#{self}\e[22m" end def italic; "\e[3m#{self}\e[23m" end def underline; "\e[4m#{self}\e[24m" end def blink; "\e[5m#{self}\e[25m" end def reverse_color; "\e[7m#{self}\e[27m" end end
和用法:
puts "I'm back green".bg_green puts "I'm red and back cyan".red.bg_cyan puts "I'm bold and green and backround red".bold.green.bg_red
在我的控制台上:
额外:
def no_colors self.gsub /\e\[\d+m/, "" end
删除格式化字符
注意
puts "\e[31m" # set format (red foreground) puts "\e[0" # clear format puts "green-#{"red".red}-green".green # will be green-red-normal, because of \e[0
您可以使用ANSI转义序列在控制台上执行此操作。 我知道这适用于Linux和OSX,我不确定Windows控制台(cmd)是否支持ANSI。
我是用Java做的,但是想法是一样的。
//foreground color public static final String BLACK_TEXT() { return "\033[30m";} public static final String RED_TEXT() { return "\033[31m";} public static final String GREEN_TEXT() { return "\033[32m";} public static final String BROWN_TEXT() { return "\033[33m";} public static final String BLUE_TEXT() { return "\033[34m";} public static final String MAGENTA_TEXT() { return "\033[35m";} public static final String CYAN_TEXT() { return "\033[36m";} public static final String GRAY_TEXT() { return "\033[37m";} //background color public static final String BLACK_BACK() { return "\033[40m";} public static final String RED_BACK() { return "\033[41m";} public static final String GREEN_BACK() { return "\033[42m";} public static final String BROWN_BACK() { return "\033[43m";} public static final String BLUE_BACK() { return "\033[44m";} public static final String MAGENTA_BACK() { return "\033[45m";} public static final String CYAN_BACK() { return "\033[46m";} public static final String WHITE_BACK() { return "\033[47m";} //ANSI control chars public static final String RESET_COLORS() { return "\033[0m";} public static final String BOLD_ON() { return "\033[1m";} public static final String BLINK_ON() { return "\033[5m";} public static final String REVERSE_ON() { return "\033[7m";} public static final String BOLD_OFF() { return "\033[22m";} public static final String BLINK_OFF() { return "\033[25m";} public static final String REVERSE_OFF() { return "\033[27m";}
根据Erik Skoglund和其他人的回答,我写了一些方法来testing基本的色彩模式。
#outputs color table to console, regular and bold modes def colortable names = %w(black red green yellow blue pink cyan white default) fgcodes = (30..39).to_a - [38] s = '' reg = "\e[%d;%dm%s\e[0m" bold = "\e[1;%d;%dm%s\e[0m" puts ' color table with these background codes:' puts ' 40 41 42 43 44 45 46 47 49' names.zip(fgcodes).each {|name,fg| s = "#{fg}" puts "%7s "%name + "#{reg} #{bold} "*9 % [fg,40,s,fg,40,s, fg,41,s,fg,41,s, fg,42,s,fg,42,s, fg,43,s,fg,43,s, fg,44,s,fg,44,s, fg,45,s,fg,45,s, fg,46,s,fg,46,s, fg,47,s,fg,47,s, fg,49,s,fg,49,s ] } end
示例输出:
虽然其他的答案会为大多数人做好工作,但应该提到“正确”的Unix方法。 由于所有types的文本terminal都不支持这些序列,因此可以查询terminfo数据库,这是对各种文本terminalfunction的抽象。 这似乎主要是有历史意义的 – 目前使用的软件terminal通常支持ANSI序列 – 但它确实具有(至less)一个实际效果:有时能够将环境variablesTERM
设置为dumb
variables来避免所有这些样式,例如将输出保存到文本文件时。 此外,做正确的事情感觉很好。 🙂
你可以使用ruby-terminfo的gem。 它需要一些C编译来安装; 我能够在我的Ubuntu 14.10系统下安装它:
$ sudo apt-get install libncurses5-dev $ gem install ruby-terminfo --user-install
然后你可以像这样查询数据库(参见terminfo手册页 ,获取可用的代码列表):
require 'terminfo' TermInfo.control("bold") puts "Bold text" TermInfo.control("sgr0") puts "Back to normal." puts "And now some " + TermInfo.control_string("setaf", 1) + "red" + TermInfo.control_string("sgr0") + " text."
这里有一个小包装类,我把它放在一起,使事情变得更简单。
require 'terminfo' class Style def self.style() @@singleton ||= Style.new end colors = %w{black red green yellow blue magenta cyan white} colors.each_with_index do |color, index| define_method(color) { get("setaf", index) } define_method("bg_" + color) { get("setab", index) } end def bold() get("bold") end def under() get("smul") end def dim() get("dim") end def clear() get("sgr0") end def get(*args) begin TermInfo.control_string(*args) rescue TermInfo::TermInfoError "" end end end
用法:
c = Style.style C = c.clear puts "#{c.red}Warning:#{C} this is #{c.bold}way#{C} #{c.bg_red}too much #{c.cyan + c.under}styling#{C}!" puts "#{c.dim}(Don't you think?)#{C}"
(编辑)最后,如果你不想要一个gem,你可以依靠tput
程序, 如下所述 – Ruby示例:
puts "Hi! " + `tput setaf 1` + "This is red!" + `tput sgr0`
我发现了几个:
http://github.com/ssoroka/ansi/tree/master
例子:
puts ANSI.color(:red) { "hello there" } puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color
http://flori.github.com/term-ansicolor/
例子:
print red, bold, "red bold", reset, "\n" print red(bold("red bold")), "\n" print red { bold { "red bold" } }, "\n"
http://github.com/sickill/rainbow
例:
puts "this is red".foreground(:red) + " and " + "this on yellow bg".background(:yellow) + " and " + "even bright underlined!".underline.bright
如果您在Windows上,则可能需要执行“gem install win32console”来启用对颜色的支持。
另外,如果您需要创build自己的gem, Colorizing console Ruby脚本输出也很有用。 它解释了如何将ANSI着色添加到string。 你可以用这个知识把它包装在一些扩展string的类中。
以下是我所做的工作,无需任何gem:
def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end puts red("hello world")
那么只有报价单中的文字有颜色,而且你会回到你定期安排的节目。
我做了这个方法可以帮助。 这不是一个大问题,但它的工作原理:
def colorize(text, color = "default", bgColor = "default") colors = {"default" => "38","black" => "30","red" => "31","green" => "32","brown" => "33", "blue" => "34", "purple" => "35", "cyan" => "36", "gray" => "37", "dark gray" => "1;30", "light red" => "1;31", "light green" => "1;32", "yellow" => "1;33", "light blue" => "1;34", "light purple" => "1;35", "light cyan" => "1;36", "white" => "1;37"} bgColors = {"default" => "0", "black" => "40", "red" => "41", "green" => "42", "brown" => "43", "blue" => "44", "purple" => "45", "cyan" => "46", "gray" => "47", "dark gray" => "100", "light red" => "101", "light green" => "102", "yellow" => "103", "light blue" => "104", "light purple" => "105", "light cyan" => "106", "white" => "107"} color_code = colors[color] bgColor_code = bgColors[bgColor] return "\033[#{bgColor_code};#{color_code}m#{text}\033[0m" end
以下是如何使用它:
puts "#{colorize("Hello World")}" puts "#{colorize("Hello World", "yellow")}" puts "#{colorize("Hello World", "white","light red")}"
可能的改进可能是:
-
colors
和bgColors
正在被定义每次调用方法,他们不会改变。 - 添加其他选项,如
bold
,underline
,dim
等
这个方法不适用于p
,因为p
inspect
了它的论点。 例如:
p "#{colorize("Hello World")}"
将显示“\ e [0; 38mHello World \ e [0m”
我用puts
, print
和logging器gem进行了testing,它工作正常。
我改进了这一点,并做了一个类,所以colors
和bgColors
是类variables和colorize
是一个类的方法:
class Colorizator @@colors = {"default" => "38","black" => "30","red" => "31","green" => "32","brown" => "33", "blue" => "34", "purple" => "35", "cyan" => "36", "gray" => "37", "dark gray" => "1;30", "light red" => "1;31", "light green" => "1;32", "yellow" => "1;33", "light blue" => "1;34", "light purple" => "1;35", "light cyan" => "1;36", "white" => "1;37"} @@bgColors = {"default" => "0", "black" => "40", "red" => "41", "green" => "42", "brown" => "43", "blue" => "44", "purple" => "45", "cyan" => "46", "gray" => "47", "dark gray" => "100", "light red" => "101", "light green" => "102", "yellow" => "103", "light blue" => "104", "light purple" => "105", "light cyan" => "106", "white" => "107"} def self.colorize(text, colour = "default", bgColour = "default") color_code = @@colors[colour] bgColor_code = @@bgColors[bgColour] return "\033[#{bgColor_code};#{color_code}m#{text}\033[0m" end end
你可以使用它做:
Colorizator.colorize("Hello World", "gray", "white")
这可能会帮助你: 彩色ruby输出
我发现上面的答案是有用的,但是如果我不想使用任何第三方库对日志输出进行着色,就不适合这个账单。 以下解决了我的问题:
red = 31 green = 32 blue = 34 def color (color=blue) printf "\033[#{color}m"; yield printf "\033[0m" end color { puts "this is blue" } color(red) { logger.info "and this is red" }
我希望它有帮助!