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

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

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


当前回答

我发现了一些:

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着色。你可以用这个知识把它包装在一些类中,这些类扩展了字符串或其他东西。

其他回答

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`

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

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

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

根据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

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