使用Ruby,我如何在终端中为输出执行背景和前景文本着色?
我记得,在编程Pascal时,我们都习惯编写自己的textcolor(…)程序,以使我们的小教育程序看起来更漂亮、更有表现力。
我该如何在Ruby中编写类似的代码呢?核心库中是否有任何内置的支持来实现这一点?如果不是,什么是添加它的惯用方式?
使用Ruby,我如何在终端中为输出执行背景和前景文本着色?
我记得,在编程Pascal时,我们都习惯编写自己的textcolor(…)程序,以使我们的小教育程序看起来更漂亮、更有表现力。
我该如何在Ruby中编写类似的代码呢?核心库中是否有任何内置的支持来实现这一点?如果不是,什么是添加它的惯用方式?
当前回答
着色是我最喜欢的宝石!: -)
看看吧:
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
其他回答
我发明了这个方法。这不是什么大事,但很有效:
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在每次调用该方法时都被定义,并且它们不会改变。 添加其他选项,如粗体,下划线,暗等。
这个方法对p无效,因为p会检查它的参数。例如:
p "#{colorize("Hello World")}"
将显示“\e[0;38mHello World\e[0m”
我用看跌、打印和Logger gem对它进行了测试,它工作得很好。
我对此进行了改进,并创建了一个类,因此colors和bgColors是类常量,colorize是类方法:
编辑:更好的代码风格,定义常量而不是类变量,使用符号而不是字符串,增加了更多的选项,如粗体,斜体等。
class Colorizator
COLOURS = { 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' }.freeze
BG_COLOURS = { 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' }.freeze
FONT_OPTIONS = { bold: '1', dim: '2', italic: '3', underline: '4', reverse: '7', hidden: '8' }.freeze
def self.colorize(text, colour = :default, bg_colour = :default, **options)
colour_code = COLOURS[colour]
bg_colour_code = BG_COLOURS[bg_colour]
font_options = options.select { |k, v| v && FONT_OPTIONS.key?(k) }.keys
font_options = font_options.map { |e| FONT_OPTIONS[e] }.join(';').squeeze
return "\e[#{bg_colour_code};#{font_options};#{colour_code}m#{text}\e[0m".squeeze(';')
end
end
你可以这样使用它:
Colorizator.colorize "Hello World", :gray, :white
Colorizator.colorize "Hello World", :light_blue, bold: true
Colorizator.colorize "Hello World", :light_blue, :white, bold: true, underline: true
这可能会帮助你:彩色红宝石输出
作为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
以下是我不需要任何宝石就能让它工作的方法:
def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end
puts red("hello world")
然后,只有引号中的文本是有颜色的,您将返回到定期安排的节目。
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`