Salida de Ruby coloreada

¿Hay alguna gem para realizar colorización de fondo y color de primer plano para la salida en la terminal?

Recuerdo que, al progtwigr Pascal, todos textcolor(...) con textcolor(...) para hacer que nuestros pequeños progtwigs educativos se vieran más bonitos y presentativos.

¿Hay algo similar en Ruby?

Colorize es mi joya favorita 🙂

Echale un vistazo:

https://github.com/fazibear/colorize

Instalación:

 gem install colorize 

Uso:

 require 'colorize' puts "I am now red".red puts "I am now blue".blue puts "Testing".yellow 

Combinando las respuestas anteriores, puede implementar algo que funciona como el color de gem sin necesidad de otra dependencia.

 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 

Como métodos de clase String (solo para 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 

y uso:

 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 

en mi consola:

enter image description here

adicional:

 def no_colors self.gsub /\e\[\d+m/, "" end 

elimina caracteres de formateo

Nota

 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 

Puede usar secuencias de escape ANSI para hacer esto en la consola. Sé que esto funciona en Linux y OSX, no estoy seguro de si la consola de Windows (cmd) es compatible con ANSI.

Lo hice en Java, pero las ideas son las mismas.

 //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 chars 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";} 

Escribí un pequeño método para probar los modos de color básicos, basado en las respuestas de Erik Skoglund y otros.

 #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 

ejemplo de salida: rubí colortest

Mientras que las otras respuestas harán bien el trabajo para la mayoría de las personas, se debe mencionar la forma “correcta” de hacer esto de Unix. Dado que todos los tipos de terminales de texto no admiten estas secuencias, puede consultar la base de datos terminfo , una abstracción sobre las capacidades de varios terminales de texto. Esto podría parecer mayormente de interés histórico, los terminales de software actualmente en uso soportan las secuencias ANSI, pero tiene (al menos) un efecto práctico: a veces es útil poder establecer la variable de entorno TERM a dumb para evitar todo estilo, por ejemplo al guardar la salida en un archivo de texto. Además, se siente bien hacer las cosas bien . 🙂

Puedes usar la gem ruby-terminfo . Necesita algo de comstackción de C para instalar; Pude instalarlo en mi sistema Ubuntu 14.10 con:

 $ sudo apt-get install libncurses5-dev $ gem install ruby-terminfo --user-install 

Luego puede consultar la base de datos de esta manera (consulte la página man de terminfo para obtener una lista de los códigos disponibles):

 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." 

Aquí hay una pequeña clase de envoltorio que reuní para hacer las cosas un poco más simples de usar.

 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 

Uso:

 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}" 

Salida de la secuencia de comandos de Ruby anterior

(edit) Finalmente, si prefieres no requerir una gem, puedes confiar en el progtwig tput , como se describe aquí – Ejemplo de Ruby:

 puts "Hi! " + `tput setaf 1` + "This is red!" + `tput sgr0` 

Encontré algunos:

http://github.com/ssoroka/ansi/tree/master

Ejemplos:

 puts ANSI.color(:red) { "hello there" } puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color 

http://flori.github.com/term-ansicolor/

Ejemplos:

 print red, bold, "red bold", reset, "\n" print red(bold("red bold")), "\n" print red { bold { "red bold" } }, "\n" 

http://github.com/sickill/rainbow

Ejemplo:

 puts "this is red".foreground(:red) + " and " + "this on yellow bg".background(:yellow) + " and " + "even bright underlined!".underline.bright 

Si está en Windows, es posible que necesite hacer una “joya instalar win32console” para habilitar el soporte de colores.

También el artículo Colourizing console Ruby-script output es útil si necesitas crear tu propia joya. Explica cómo agregar colores ANSI a cadenas. Puede usar este conocimiento para envolverlo en alguna clase que extienda una cadena o algo.

Esto es lo que hice para que funcione sin necesidad de gems:

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

Entonces, solo el texto de las comillas se colorea, y usted regresa a su progtwig progtwigdo regularmente.

Hice este método que podría ayudar. No es gran cosa, pero funciona:

 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 

He aquí cómo usarlo:

 puts "#{colorize("Hello World")}" puts "#{colorize("Hello World", "yellow")}" puts "#{colorize("Hello World", "white","light red")}" 

Las posibles mejoras podrían ser:

  • colors y bgColors se están definiendo cada vez que se llama al método y no cambian.
  • Agregue otras opciones como bold , underline , dim , etc.

Este método no funciona para p , ya que p inspect su argumento. Por ejemplo:

 p "#{colorize("Hello World")}" 

mostrará “\ e [0; 38mHello World \ e [0m”]

Lo probé con puts , print y la gem Logger, y funciona bien.


bgColors esto e hice una clase para que los colors y bgColors sean constantes de clase y colorize es un método de clase:

EDITAR: Mejor estilo de código, constantes definidas en lugar de variables de clase, utilizando símbolos en lugar de cadenas, se agregaron más opciones como, negrita, cursiva, etc.

 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 

Puedes usarlo haciendo:

 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 

Esto puede ayudarte: salida Ruby coloreada

Sin embargo, encontré las respuestas anteriores útiles pero no encajaban en la factura si quería colorear algo como la salida de registro sin usar ninguna biblioteca de terceros. Lo siguiente me solucionó el problema:

 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" } 

¡Espero que ayude!