Existe-t-il un joyau pour effectuer la colorisation du texte d’arrière-plan et de premier plan dans le terminal?
Je me souviens, lorsque nous programmions Pascal, nous jouions tous avec les procédures textcolor(...)
pour rendre nos petits programmes éducatifs plus jolis et plus présentés.
Y a-t-il quelque chose de similaire dans Ruby?
Colorize est mon bijou préféré! :-)
Vérifiez-le:
https://github.com/fazibear/colorize
Installation:
gem install colorize
Usage:
require 'colorize'
puts "I am now red".red
puts "I am now blue".blue
puts "Testing".yellow
En combinant les réponses ci-dessus, vous pouvez implémenter quelque chose qui fonctionne comme la gemme coloriser sans avoir besoin d'une autre dépendance.
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
Méthodes de classe As String (Unix uniquement):
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
et utilisation:
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
sur ma console:
def no_colors
self.gsub /\e\[\d+m/, ""
end
supprime les caractères de formatage
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
J'ai écrit une petite méthode pour tester les modes de couleurs de base, basée sur les réponses d'Erik Skoglund et d'autres.
#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
exemple de sortie:
Vous pouvez utiliser des séquences d'échappement ANSI pour ce faire sur la console. Je sais que cela fonctionne sous Linux et OSX. Je ne sais pas si la console Windows (cmd) prend en charge la norme ANSI.
Je l'ai fait en Java, mais les idées sont les mêmes.
//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";}
Alors que les autres réponses feront l'affaire pour la plupart des gens, il convient de mentionner la "bonne" méthode Unix. Étant donné que tous les types de terminaux texte ne prennent pas en charge ces séquences, vous pouvez interroger la base de données terminfo , une abstraction des capacités de divers terminaux texte. Cela peut sembler plutôt d’intérêt historique - les terminaux logiciels utilisés de nos jours supportent généralement les séquences ANSI - mais cela a (au moins) un effet pratique: il est parfois utile de pouvoir définir la variable d’environnement TERM
à dumb
pour éviter tout style, par exemple lors de l’enregistrement de la sortie dans un fichier texte. Aussi, ça fait du bien de faire les choses à droite . :-)
Vous pouvez utiliser le Ruby-terminfo gem. Il a besoin de compiler C pour l’installer; J'ai pu l'installer sous mon système Ubuntu 14.10 avec:
$ Sudo apt-get install libncurses5-dev
$ gem install Ruby-terminfo --user-install
Vous pouvez ensuite interroger la base de données de la manière suivante (voir le page de manuel de terminfo pour obtenir la liste des codes 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."
Voici un petit cours sur l'emballage que j'ai mis en place pour rendre les choses un peu plus simples à utiliser.
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
Usage:
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}"
(edit) Enfin, si vous préférez ne pas avoir besoin de gemme, vous pouvez vous fier au programme tput
, comme décrit ici - Ruby exemple:
puts "Hi! " + `tput setaf 1` + "This is red!" + `tput sgr0`
J'ai fait cette méthode qui pourrait aider. Ce n'est pas grave, mais ça marche:
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
Voici comment l'utiliser:
puts "#{colorize("Hello World")}"
puts "#{colorize("Hello World", "yellow")}"
puts "#{colorize("Hello World", "white","light red")}"
Les améliorations possibles pourraient être:
colors
et bgColors
sont définis chaque fois que la méthode est appelée et ne changent pas.bold
, underline
, dim
, etc.Cette méthode ne fonctionne pas pour p
, car p
effectue un inspect
sur son argument. Par exemple:
p "#{colorize("Hello World")}"
affichera "\ e [0; 38mHello World\e [0m"
Je l'ai testé avec puts
, print
et la gemme de l'enregistreur, et tout fonctionne correctement.
J'ai amélioré ceci et créé une classe pour que colors
et bgColors
soient des constantes de classe et que colorize
soit une méthode de classe:
EDIT: meilleur style de code, constantes définies au lieu de variables de classe, utilisation de symboles au lieu de chaînes, ajout d'options supplémentaires telles que gras, italique, 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
Vous pouvez l'utiliser en faisant:
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
J'ai trouvé quelques-uns:
http://github.com/ssoroka/ansi/tree/master
Exemples:
puts ANSI.color(:red) { "hello there" }
puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color
http://flori.github.com/term-ansicolor/
Exemples:
print red, bold, "red bold", reset, "\n"
print red(bold("red bold")), "\n"
print red { bold { "red bold" } }, "\n"
http://github.com/sickill/Rainbow
Exemple:
puts "this is red".foreground(:red) + " and " + "this on yellow bg".background(:yellow) + " and " + "even bright underlined!".underline.bright
Si vous êtes sous Windows, vous devrez peut-être effectuer un "Gem install win32console" pour activer la prise en charge des couleurs.
De plus, l'article sortie Ruby-script de la console Colorizing est utile si vous devez créer votre propre bijou. Il explique comment ajouter de la couleur ANSI aux chaînes. Vous pouvez utiliser cette connaissance pour l'envelopper dans une classe qui étend une chaîne ou quelque chose.
Voici ce que j'ai fait pour que cela fonctionne sans avoir besoin de gemmes:
def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end
puts red("hello world")
Ensuite, seul le texte entre guillemets est coloré et vous revenez à votre programme régulier.
Cela peut vous aider: Colorized Ruby output
J'ai trouvé les réponses ci-dessus utiles mais je ne trouvais pas la solution si je voulais coloriser quelque chose comme une sortie de journal sans en utilisant des bibliothèques tierces. Ce qui suit a résolu le problème pour moi:
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" }
J'espère que ça aide!