Kolorierte Ruby-Ausgabe an das Terminal [geschlossen]


273

Wie kann ich mit Ruby Hintergrund- und Vordergrundtext für die Ausgabe im Terminal einfärben?

Ich erinnere mich, als wir Pascal programmierten, haben wir alle unsere eigenen textcolor(…)Prozeduren geschrieben, damit unsere kleinen Bildungsprogramme hübscher und präsentativer aussehen.

Wie würde ich vorgehen, um ein Äquivalent davon in Ruby zu codieren?


Es ist also unmöglich, zum Beispiel eine "orange" Farbe zu bekommen?
Matrix

Antworten:


379

Kolorieren ist mein Lieblingsjuwel! :-)

Hör zu:

https://github.com/fazibear/colorize

Installation:

gem install colorize

Verwendungszweck:

require 'colorize'

puts "I am now red".red
puts "I am now blue".blue
puts "Testing".yellow

2
Könnte mir jemand sagen, ob Colorize im Cygwin Terminal funktioniert? Ich habe versucht, den obigen Code in Cygwin auszuführen, aber er kommt ohne Farben heraus.
jj_

5
Dies funktioniert in einer Windows-Eingabeaufforderung einwandfrei, wenn Sie das win32consoleGem und require 'win32console'danach installieren colorize.
Ben

2
@ Ben Ich habe es nicht persönlich ausprobiert, aber seit Ruby 2.0 solltest du das win32consoleJuwel nicht mehr brauchen . github.com/luislavena/win32console/issues/…
Dennis

1
Wie kann dies mit der Sumblime Text-Konsole funktionieren?
Nipponese

6
Dieses Juwel ist unter der GPL lizenziert und kann (glaube ich) nicht in proprietärer Software verwendet werden. jonathannen.com/2013/07/07/license-your-gems.html
Andrei Botalov

249

Wenn Sie die obigen Antworten kombinieren, können Sie etwas implementieren, das wie das Kolorieren des Edelsteins 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

Ah, schön, Nick zu bearbeiten. Ja, natürlich besteht keine Notwendigkeit, sich selbst weiterzugeben. Ich war müde, als ich das schrieb :)
Erik Skoglund

Funktioniert das auch in Windows?
Alp

Es funktioniert in Windows, wenn Sie ConEmu
Mike Glenn

1
Ich mag das besser als kolorieren, da dies nur die Vordergrundfarbe ändert. kolorieren scheint immer die Hintergrundfarbe zu ändern.
Jlyonsmith

1
Ich weiß, dass ich zu spät zur Party komme, aber wäre es nicht besser, hier einen Verschluss zu verwenden?

215

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 Verwendung:

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:

Geben Sie hier die Bildbeschreibung ein

zusätzlich:

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

Entfernt Formatierungszeichen

Hinweis

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

Fett def bold; "\e[1m#{self}\e[22m" end
gedruckt sollte Fluchtcode

@KanatBolazar, Einige Systeme unterstützen 21 . Aber ich ändere es für die Fähigkeit auf 22. Vielen Dank.
Ivan Black

1
Das ist großartig, ich habe es in einen Initialisierer in meiner Rails-Anwendung eingefügt. Klappt wunderbar!

Fantastische Tipps. So einfach und ohne Abhängigkeiten. Sehr sehr gut gemacht!
Mraxus

1
In Windows 10 cmd.exe, puts "\e[0"funktioniert nicht auf klares Format; puts "\e[0m"muss verwendet werden
Nnnes

41

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: rubinrot


37

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

7
Dies funktioniert und hat den Vorteil, dass kein Edelstein benötigt wird, was manche Leute nerven könnte.
ThomasW

3
Die Windows-Konsole unterstützt tatsächlich ANSI-Codes.
Ben

16

Während die anderen Antworten für die meisten Menschen gut funktionieren, sollte die "richtige" Unix-Methode erwähnt werden. Da alle Arten von Textterminals diese Sequenzen nicht unterstützen, können Sie die terminfo- Datenbank abfragen , eine Abstraktion über die Funktionen verschiedener Textterminals. Dies scheint größtenteils von historischem Interesse zu sein - heute verwendete Software-Terminals unterstützen im Allgemeinen die ANSI-Sequenzen -, hat jedoch (mindestens) einen praktischen Effekt: Manchmal ist es nützlich, die Umgebungsvariable so einstellen TERMzu können dumb, dass ein derartiges Styling vermieden wird. Zum Beispiel beim Speichern der Ausgabe in einer Textdatei. Es fühlt sich auch gut an, die Dinge richtig zu machen . :-)

Sie können den Rubin-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

Anschließend können Sie die Datenbank wie folgt abfragen ( eine Liste der verfügbaren Codes finden Sie auf der Terminfo-Manpage ):

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 Verwendung 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

Verwendungszweck:

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

Ausgabe des obigen Ruby-Skripts

(Bearbeiten) Wenn Sie lieber keinen Edelstein benötigen, können Sie sich wie hier beschrieben auf das tputProgramm verlassen - Ruby-Beispiel:

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

4
Major, Major +1 für die Verwendung von tput. Ich kann nicht einmal artikulieren, wie viel Haarausfall tputmich gerettet hat.
Pierce

14

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:

  • colorsund bgColorswerden jedes Mal definiert, wenn die Methode aufgerufen wird, und sie ändern sich nicht.
  • Fügen Sie andere Optionen wie bold, underline, dimusw.

Diese Methode funktioniert nicht für p, ebenso pwie ein inspectArgument. Zum Beispiel:

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

zeigt "\ e [0; 38mHallo World \ e [0m"

Ich habe es mit puts, printund dem Logger-Juwel getestet , und es funktioniert gut.


Ich habe dies verbessert und eine Klasse so erstellt colorsund bin bgColorsKlassenkonstanten und colorizeist eine Klassenmethode:

BEARBEITEN: Besserer Codestil, definierte Konstanten anstelle von Klassenvariablen, Verwendung von Symbolen anstelle von Zeichenfolgen, Hinzufügen weiterer Optionen wie Fettdruck, Kursivschrift 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:

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

13

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 angezeigt, und Sie kehren zu Ihrem regulären Programm zurück.


3
Funktioniert bei mir nicht Ich verstehe genau:e[32mSOMETEXT
Oscar Godson

Es gab einen Tippfehler in der ersten Fluchtfigur: sollte "\e(...)"anstelle von"e\(...)"
Arthropod

12

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 Colorizing Console Ruby-Script-Ausgabe ist nützlich, wenn Sie Ihr eigenes Juwel erstellen müssen. Es wird erklärt, wie Sie Zeichenfolgen ANSI-Farben hinzufügen. Sie können dieses Wissen verwenden, um es in eine Klasse zu verpacken, die eine Zeichenfolge oder etwas erweitert.


8

Dies kann Ihnen helfen: Kolorierte Rubinausgabe


1
Wenn Sie das Beispiel für diesen Link verbessern, können Sie die String-Klasse erweitern, um die Verwendung zu vereinfachen ("Hello" .red):class String; def red; colorize(self, "\033[31m"); end; end
Adriano P

3

Ich fand die obigen Antworten nützlich, passte jedoch nicht zur Rechnung, wenn ich so etwas wie eine Protokollausgabe einfärben wollte, ohne Bibliotheken von Drittanbietern zu verwenden. 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!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.