Salida rubí coloreada [cerrada]


¿Hay una gema para realizar la coloración de texto de fondo y primer plano para la salida en terminal?

Recuerdo que cuando programábamos Pascal todos solíamos jugar con textcolor(...) procedimientos para hacer que nuestros pequeños programas educativos se vieran más bonitos y presentacionales.

¿Hay algo similar en Ruby?

Author: gmile, 2009-09-29

11 answers

Colorear es mi joya favorita! :-)

Compruébalo:

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
 346
Author: jaredmdobson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-30 17:12:04

Combinando las respuestas anteriores, puede implementar algo que funcione como la gema colorize 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
 213
Author: Erik Skoglund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-08 00:51:27

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

introduzca la descripción de la imagen aquí

Adicional:

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

Elimina los caracteres de formato

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
 171
Author: Ivan Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 02:56:30

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";}
 36
Author: Ryan Michela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 20:35:18

Escribí un pequeño método para probar los modos de color básicos, basado en 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

 36
Author: icy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-16 18:46:16

Mientras que las otras respuestas harán el trabajo bien para la mayoría de la gente, la forma "correcta" de Unix de hacer esto debe ser mencionada. 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 puede parecer sobre todo de interés histórico-los terminales de software en uso hoy en día generalmente soportan las secuencias ANSI - pero tiene (al menos) un efecto práctico: a veces es útil para poder establecer la variable de entorno TERM en dumb para evitar todo este estilo, por ejemplo al guardar la salida en un archivo de texto. Además, se siente bien hacer las cosas bien. :-)

Puedes usar la gema ruby-terminfo. Necesita un poco de compilación de C para instalarlo; pude instalarlo bajo 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 (vea la página de manual de terminfo para una lista de qué códigos son disponible):

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 envoltura que armé para hacer las cosas un poco más fáciles 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 del script Ruby anterior

(editar) Finalmente, si prefiere no requerir una gema, puede confiar en el programa tput, como se describe aquí – ejemplo de Ruby:

puts "Hi! " + `tput setaf 1` + "This is red!" + `tput sgr0`
 14
Author: skagedal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 12:36:31

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 deba hacer un "gem install win32console" para habilitar el soporte para colores.

También el artículo Colorizing console Ruby-script output es útil si necesita para crear tu propia joya. Explica cómo agregar color ANSI a las cadenas. Puedes usar este conocimiento para envolverlo en alguna clase que extienda string o algo así.

 12
Author: Petros,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 20:44:01

Esto es lo que hice para que funcionara sin necesidad de gemas:

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

Entonces solo el texto en las comillas allí es de color, y se le devuelve a su programa programado regularmente.

 12
Author: suzyQ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 10:56:36

Hice este método que podría ayudar. No es un gran problema, 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 definen cada vez que se llama al método y no cambian.
  • Añadir otras opciones como bold, underline, dim, etc.

Este método no funciona para p, con p hace un inspect a su argumento. Por ejemplo:

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

Mostrará "\e [0; 38mHello World\e [0m "

Lo probé con puts, print, y la gema del Leñador, y funciona bien.


Mejoré esto e hice una clase así que colors y bgColors son constantes de clase y colorize es un método de clase:

EDIT: Mejor estilo de código, constantes definidas en lugar de variables de clase, uso de 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
 12
Author: Redithion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 13:38:25

Esto puede ayudarte: Salida rubí coloreada

 7
Author: ennuikiller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 20:29:50

Encontré que las respuestas anteriores eran útiles, sin embargo, no se ajustaban a la factura si quería colorear algo como la salida de registro sin utilizando bibliotecas de terceros. Lo siguiente resolvió el problema para mí:

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!

 3
Author: pmyjavec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-13 10:31:11