使用Ruby,我如何在终端中为输出执行背景和前景文本着色?

我记得,在编程Pascal时,我们都习惯编写自己的textcolor(…)程序,以使我们的小教育程序看起来更漂亮、更有表现力。

我该如何在Ruby中编写类似的代码呢?核心库中是否有任何内置的支持来实现这一点?如果不是,什么是添加它的惯用方式?


当前回答

我发明了这个方法。这不是什么大事,但很有效:

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

其他回答

我发现了一些:

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”来启用对颜色的支持。

另外,如果您需要创建自己的gem,为控制台Ruby-script输出着色这篇文章也很有用。它解释了如何向字符串添加ANSI着色。你可以用这个知识把它包装在一些类中,这些类扩展了字符串或其他东西。

您可以在控制台中使用ANSI转义序列来完成此操作。我知道这适用于Linux和Mac OS X,但我不确定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 characters
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";}

这可能会帮助你:彩色红宝石输出

以下是我不需要任何宝石就能让它工作的方法:

def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end
puts red("hello world")

然后,只有引号中的文本是有颜色的,您将返回到定期安排的节目。

着色是我最喜欢的宝石!: -)

看看吧:

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