使用Ruby,我如何在终端中为输出执行背景和前景文本着色?
我记得,在编程Pascal时,我们都习惯编写自己的textcolor(…)程序,以使我们的小教育程序看起来更漂亮、更有表现力。
我该如何在Ruby中编写类似的代码呢?核心库中是否有任何内置的支持来实现这一点?如果不是,什么是添加它的惯用方式?
使用Ruby,我如何在终端中为输出执行背景和前景文本着色?
我记得,在编程Pascal时,我们都习惯编写自己的textcolor(…)程序,以使我们的小教育程序看起来更漂亮、更有表现力。
我该如何在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" }
这可能会帮助你:彩色红宝石输出
根据Erik Skoglund和其他人的回答,我写了一个小方法来测试基本的颜色模式。
#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
示例输出:
作为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
删除格式化字符。
Note
puts "\e[31m" # set format (red foreground)
puts "\e[0m" # clear format
puts "green-#{"red".red}-green".green # will be green-red-normal, because of \e[0
While the other answers will do the job fine for most people, the "correct" Unix way of doing this should be mentioned. Since all types of text terminals do not support these sequences, you can query the terminfo database, an abstraction over the capabilites of various text terminals. This might seem mostly of historical interest – software terminals in use today generally support the ANSI sequences – but it does have (at least) one practical effect: it is sometimes useful to be able to set the environment variable TERM to dumb to avoid all such styling, for example when saving the output to a text file. Also, it feels good to do things right. :-)
你可以使用红宝石终端宝石。它需要一些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`