Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Ruby将文本输出着色到终端?_Ruby_Colors_Console Application - Fatal编程技术网

如何使用Ruby将文本输出着色到终端?

如何使用Ruby将文本输出着色到终端?,ruby,colors,console-application,Ruby,Colors,Console Application,使用Ruby,如何对终端中的输出执行背景和前景文本着色 我记得,在编写Pascal程序时,我们都会编写自己的textcolor(…)程序,使我们的小型教育程序看起来更美观、更具代表性 我将如何在Ruby中编写一个类似的代码?核心库中是否有任何内置支持可用于此目的?如果没有,用什么惯用方法添加它?这可能会对您有所帮助:您可以在控制台中使用ANSI转义序列来执行此操作。我知道这可以在Linux和MacOSX上使用,但我不确定Windows控制台(cmd)是否支持ANSI 我是用Java做的,但是想法

使用Ruby,如何对终端中的输出执行背景和前景文本着色

我记得,在编写Pascal程序时,我们都会编写自己的
textcolor(…)
程序,使我们的小型教育程序看起来更美观、更具代表性


我将如何在Ruby中编写一个类似的代码?核心库中是否有任何内置支持可用于此目的?如果没有,用什么惯用方法添加它?

这可能会对您有所帮助:

您可以在控制台中使用ANSI转义序列来执行此操作。我知道这可以在Linux和MacOSX上使用,但我不确定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";}

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

请查看:

安装:

gem install colorize
用法:

require 'colorize'

puts "I am now red".red
puts "I am now blue".blue
puts "Testing".yellow
我发现了一些:

示例:

puts ANSI.color(:red) { "hello there" }
puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color
print red, bold, "red bold", reset, "\n"
print red(bold("red bold")), "\n"
print red { bold { "red bold" } }, "\n"

示例:

puts ANSI.color(:red) { "hello there" }
puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color
print red, bold, "red bold", reset, "\n"
print red(bold("red bold")), "\n"
print red { bold { "red bold" } }, "\n"

例如:

puts "this is red".foreground(:red) + " and " + "this on yellow bg".background(:yellow) + " and " + "even bright underlined!".underline.bright
如果您在Windows上,则可能需要执行“gem安装win32console”以启用对颜色的支持


如果您需要创建自己的gem,本文也很有用。它解释了如何为字符串添加ANSI颜色。您可以使用这些知识将其封装到扩展字符串或其他内容的类中。

结合上述答案,您可以实现类似gem colorize的功能,而不需要其他依赖项

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

以下是我在不需要任何宝石的情况下所做的工作:

def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end
puts red("hello world")
然后,只有引号中的文本是彩色的,您将返回到定期计划的程序。

作为字符串类方法(仅限Unix):

类字符串
def黑色;“\e[30m{self}\e[0m”结束
def red;“\e[31m{self}\e[0m”结束
def绿色;“\e[32m{self}\e[0m”结束
def brown;“\e[33m{self}\e[0m”结束
def蓝色;“\e[34m{self}\e[0m”结束
def洋红色;“\e[35m{self}\e[0m”结束
def青色;“\e[36m{self}\e[0m”结束
def gray;“\e[37m{self}\e[0m”结束
def bg#U黑色;“\e[40m{self}\e[0m”结束
def bg_red;“\e[41m{self}\e[0m”结束
def bg#u green;“\e[42m{self}\e[0m”结束
def bg#u brown;“\e[43m{self}\e[0m”结束
def bg#u blue;“\e[44m{self}\e[0m”结束
def bg#u洋红色;“\e[45m{self}\e[0m”结束
def bg#U青色;“\e[46m{self}\e[0m”结束
def bg#u gray;“\e[47m{self}\e[0m”结束
def bold;“\e[1m{self}\e[22m”结束
def italic;“\e[3m{self}\e[23m”结束
def underline;“\e[4m{self}\e[24m”结束
def闪烁;“\e[5m{self}\e[25m”结束
def reverse_color;“\e[7m{self}\e[27m”结束
结束
使用方法:

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无颜色
self.gsub/\e\[\d+m/,“”
结束
删除格式化字符


我根据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
示例输出:

我发现前面的答案很有用。但是,如果我想在不使用任何第三方库的情况下对日志输出之类的内容进行着色,这些答案就不合适了。下面为我解决了这个问题:

red=31
绿色=32
蓝色=34
def颜色(颜色=蓝色)
printf“\033[#{color}m”;
产量
printf“\033[0m”
结束
颜色{显示“这是蓝色”}
颜色(红色){logger.info“这是红色”}

我用这个方法可能会有所帮助。这没什么大不了的,但它很有效:

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”

我用
put
print
和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

虽然其他答案对大多数人来说都很好,但“正确的”应该提到Unix的实现方法。由于所有类型的文本终端都不支持这些序列,因此您可以查询terminfo数据库,这是对各种文本终端功能的抽象。这似乎是历史上最感兴趣的事情——今天使用的软件终端通常支持ANSI序列——但它确实支持ANSI序列ve(至少)一个实际效果:有时可以将环境变量
TERM
设置为
dumb
以避免所有此类样式设置,例如在将输出保存到文本文件时。此外,正确操作感觉很好。:-)

你可以使用gem。它需要一些C编译才能安装;我可以在我的Ubuntu 14.10系统下安装它,使用:

$sudo apt get安装libncurse5 dev
$gem安装ruby terminfo--用户安装
然后可以像这样查询数据库(有关可用代码的列表,请参阅):

需要“terminfo”
终端控制(“粗体”)
放置“粗体文本”
终端控制(“sgr0”)
使“恢复正常”
将“和现在的一些”+TermInfo.control_字符串(“setaf”,1)+
“红色”+TermInfo.control_字符串(“sgr0”)+“文本。”
这里有一个小包装器类,我把它放在一起,使它更易于使用

需要“terminfo”
班级风格
def self.style()
@@singleton | |=Style.new
结束
颜色=%w{黑-红-绿-黄-蓝-品红-青色-白}
颜色。每个带有|索引的|颜色,索引|
定义方法(颜色){get(“setaf”,index)}
定义_方法(“bg_”+