Gibt es einen Edelstein, um Hintergrund- und Vordergrundtext für die Ausgabe im Terminal einzufärben?
Ich erinnere mich, dass wir beim Programmieren von Pascal alle mit textcolor(...)
-Prozeduren gespielt haben, um unsere kleinen Bildungsprogramme hübscher und präsentativer zu machen.
Gibt es etwas Ähnliches in Ruby?
Kolorieren ist mein Lieblingsjuwel! :-)
Hör zu:
https://github.com/fazibear/colorize
Installation:
gem install colorize
Verwendung:
require 'colorize'
puts "I am now red".red
puts "I am now blue".blue
puts "Testing".yellow
Wenn Sie die obigen Antworten kombinieren, können Sie etwas implementieren, das wie das Färben von Edelsteinen funktioniert, ohne dass eine weitere Abhängigkeit erforderlich ist.
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
Als String-Klassenmethoden (nur 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
und Nutzung:
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
auf meiner Konsole:
def no_colors
self.gsub /\e\[\d+m/, ""
end
entfernt Formatierungszeichen
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
Ich habe eine kleine Methode geschrieben, um die grundlegenden Farbmodi zu testen, basierend auf den Antworten von Erik Skoglund und anderen.
#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
beispielausgabe:
Sie können ANSI-Escape-Sequenzen verwenden, um dies auf der Konsole zu tun. Ich weiß, dass dies unter Linux und OSX funktioniert. Ich bin nicht sicher, ob die Windows-Konsole (cmd) ANSI unterstützt.
Ich habe es in Java gemacht, aber die Ideen sind die gleichen.
//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";}
Während die anderen Antworten den Job für die meisten Leute gut machen, sollte die "richtige" Unix-Methode dafür erwähnt werden. Da diese Sequenzen nicht von allen Textterminaltypen unterstützt werden, können Sie die Datenbank terminfo abfragen, eine Abstraktion über die Funktionen verschiedener Textterminals. Dies mag vor allem von historischem Interesse sein - heutzutage verwendete Software-Terminals unterstützen im Allgemeinen die ANSI-Sequenzen -, aber es hat (mindestens) einen praktischen Effekt: Es ist manchmal nützlich, die Umgebungsvariable TERM
auf setzen zu können dumb
, um solche Stile zu vermeiden, beispielsweise beim Speichern der Ausgabe in einer Textdatei. Es fühlt sich auch gut an, Dinge richtig zu machen . :-)
Sie können den Ruby-terminfo Edelstein verwenden. Für die Installation ist eine C-Kompilierung erforderlich. Ich konnte es unter meinem Ubuntu 14.10 System installieren mit:
$ Sudo apt-get install libncurses5-dev
$ gem install Ruby-terminfo --user-install
Dann können Sie die Datenbank wie folgt abfragen (eine Liste der verfügbaren Codes finden Sie in der terminfo man page ):
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."
Hier ist eine kleine Wrapper-Klasse, die ich zusammengestellt habe, um die Bedienung zu vereinfachen.
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
Verwendung:
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}"
(Bearbeiten) Wenn Sie keinen Edelstein benötigen, können Sie sich auf das Programm tput
verlassen, wie hier beschrieben - Ruby Beispiel :
puts "Hi! " + `tput setaf 1` + "This is red!" + `tput sgr0`
Ich habe diese Methode gemacht, die helfen könnte. Es ist keine große Sache, aber es funktioniert:
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
So verwenden Sie es:
puts "#{colorize("Hello World")}"
puts "#{colorize("Hello World", "yellow")}"
puts "#{colorize("Hello World", "white","light red")}"
Mögliche Verbesserungen könnten sein:
colors
und bgColors
werden bei jedem Aufruf der Methode definiert und ändern sich nicht.bold
, underline
, dim
usw. hinzu.Diese Methode funktioniert nicht für p
, da p
ein inspect
zu seinem Argument ausführt. Beispielsweise:
p "#{colorize("Hello World")}"
zeigt "\ e [0; 38mHallo Welt\e [0m"
Ich habe es mit puts
, print
und dem Logger-Juwel getestet, und es funktioniert einwandfrei.
Ich habe dies verbessert und eine Klasse erstellt, sodass colors
und bgColors
Klassenkonstanten sind und colorize
eine Klassenmethode ist:
BEARBEITEN: Besserer Codestil, definierte Konstanten anstelle von Klassenvariablen, Verwenden von Symbolen anstelle von Zeichenfolgen, Hinzufügen weiterer Optionen wie Fett, Kursiv usw.
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
Sie können es verwenden, indem Sie Folgendes tun:
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
Ich habe ein paar gefunden:
http://github.com/ssoroka/ansi/tree/master
Beispiele:
puts ANSI.color(:red) { "hello there" }
puts ANSI.color(:green) + "Everything is green now" + ANSI.no_color
http://flori.github.com/term-ansicolor/
Beispiele:
print red, bold, "red bold", reset, "\n"
print red(bold("red bold")), "\n"
print red { bold { "red bold" } }, "\n"
http://github.com/sickill/Rainbow
Beispiel:
puts "this is red".foreground(:red) + " and " + "this on yellow bg".background(:yellow) + " and " + "even bright underlined!".underline.bright
Wenn Sie unter Windows arbeiten, müssen Sie möglicherweise eine "gem install win32console" ausführen, um die Unterstützung für Farben zu aktivieren.
Auch der Artikel Ausgabe von Ruby-Skripten in der Colorizing-Konsole ist nützlich, wenn Sie Ihr eigenes Juwel erstellen müssen. Hier erfahren Sie, wie Sie Zeichenfolgen ANSI-Farben hinzufügen. Sie können dieses Wissen verwenden, um es in eine Klasse einzufügen, die Zeichenfolgen oder ähnliches erweitert.
Folgendes habe ich getan, damit es funktioniert, ohne dass Edelsteine benötigt werden:
def red(mytext) ; "\e[31m#{mytext}\e[0m" ; end
puts red("hello world")
Dann wird nur der Text in den Anführungszeichen farbig dargestellt und Sie kehren zu Ihrem regulären Programm zurück.
Dies kann Ihnen helfen: Colorized Ruby Ausgabe
Ich fand die obigen Antworten nützlich, passte aber nicht in die Rechnung, wenn ich etwas wie die Protokollausgabe einfärben wollte ohne unter Verwendung von Bibliotheken von Drittanbietern. Folgendes hat das Problem für mich gelöst:
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" }
Ich hoffe, es hilft!