Terminale renklendirilmiş Ruby çıkışı [kapalı]


273

Ruby'yi kullanarak terminaldeki çıktı için arka plan ve ön plan metin renklendirmesini nasıl yapabilirim?

Pascal'ı programlarken hepimiz textcolor(…)küçük eğitim programlarımızın daha güzel ve sunumsal görünmesini sağlamak için kendi prosedürlerimizi yazardık.

Ruby'de buna eşdeğer bir kodlama nasıl yapılır?


Örnek için "turuncu" renk elde etmek imkansız mı?
Matris

Yanıtlar:


379

Renklendirme benim en sevdiğim mücevher! :-)

Bunu kontrol et:

https://github.com/fazibear/colorize

Kurulum:

gem install colorize

Kullanımı:

require 'colorize'

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

2
Birisi bana Colorize'in Cygwin Terminalinde çalışıp çalışmadığını söyleyebilir mi? Cygwin yukarıdaki kodu çalıştırmayı denedim ama renkler olmadan çıkıyor ..
jj_

5
Gem'i yüklerseniz win32consoleve require 'win32console'sonrasında bir Windows Komut İstemi'nde bu iyi çalışır colorize.
Ben

2
@Ben ben şahsen denemedim, ama Ruby 2.0'dan beri artık geme ihtiyacınız yok win32console. github.com/luislavena/win32console/issues/…
Dennis

1
Sumblime Metin konsolu ile çalışmanın herhangi bir yolu var mı?
nipponese

6
Bu mücevher GPL altında lisanslanmıştır, bu yüzden (sanırım) tescilli yazılımda kullanılamaz. jonathannen.com/2013/07/07/license-your-gems.html
Andrei Botalov

249

Yukarıdaki cevapları birleştirerek, başka bir bağımlılığa ihtiyaç duymadan mücevher rengi gibi çalışan bir şey uygulayabilirsiniz.

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, nice düzenlemek Nick. Evet elbette ki kendinden geçmeye gerek yok. Bunu yazarken çok yoruldum :)
Erik Skoglund

bu pencerelerde de çalışacak mı?
Alp

Kullandığınız eğer pencereler çalışır ConEmu
Mike Glenn

1
Bunu sadece ön plan rengini değiştirdiği için renklendirmekten daha çok seviyorum. colorize her zaman arka plan rengini değiştiriyor gibi görünüyor.
jlyonsmith

1
Partiye geç kaldığımı biliyorum, ama burada bir kapak kullanmak daha iyi olmaz mıydı?

215

String sınıfı yöntemleri olarak (yalnızca 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

ve kullanım:

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

konsolumda:

resim açıklamasını buraya girin

ek:

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

karakterleri biçimlendirmeyi kaldırır

Not

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

Cesur, 21 değil kaçış kodunu 22 kullanmalıdır:def bold; "\e[1m#{self}\e[22m" end
Kanat Bolazar

@KanatBolazar, Bazı sistemler 21'i destekliyor . Ama yetenek için 22 olarak değiştiriyorum. Teşekkürler.
Ivan Black

1
Bu harika, Rails uygulamamda bir başlatıcıya koydum. Tıkır tıkır çalışıyor!

Harika ipuçları. Çok kolay ve bağımlılık yok. Çok çok iyi!
mraxus

1
Windows 10'da cmd.exe, puts "\e[0"formatı temizlemek için çalışmaz; puts "\e[0m"kullanılmalıdır
Nnnes

41

Erik Skoglund ve diğerlerinin cevaplarına dayanarak temel renk modlarını test etmek için küçük bir yöntem yazdım.

#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

örnek çıktı: yakut renk testi


37

Konsolda bunu yapmak için ANSI kaçış dizileri kullanabilirsiniz. Bunun Linux ve OSX üzerinde çalıştığını biliyorum, Windows konsolunun (cmd) ANSI'yi destekleyip desteklemediğinden emin değilim.

Java ile yaptım, ama fikirler aynı.

//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
Bu işe yarar ve bazı insanları rahatsız edebilecek bir mücevher gerektirmeme avantajına sahiptir.
ThomasW

3
Windows konsolu gerçekten ANSI kodlarını destekliyor.
Ben

16

Diğer cevaplar çoğu insan için işi iyi yapsa da, bunu yapmanın "doğru" Unix yolundan bahsedilmelidir. Her tür metin terminali bu dizileri desteklemediğinden , çeşitli metin terminallerinin kapasiteleri üzerinde bir soyutlama olan terminfo veritabanını sorgulayabilirsiniz . Bugün genel olarak ANSI dizileri destekleyen kullanılan yazılım terminalleri - - Bu, çoğunlukla tarihsel ilgi ait görünebilir ama (en azından) var bir pratik etkisi: Bu ortam değişkeni ayarlamak için muktedir bazen faydalıdır TERMiçin dumbbu tür tüm stil kaçınmak için, örneğin çıktıyı bir metin dosyasına kaydederken. Ayrıca, işleri doğru yapmak iyi hissettiriyor . :-)

Sen kullanabilirsiniz yakut-terminfo mücevher. Yüklemek için bir miktar C derlemesi gerekir; Ben ile Ubuntu 14.10 sistemimin altına yüklemek mümkün:

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

Daha sonra veritabanını böyle sorgulayabilirsiniz (hangi kodların mevcut olduğunu görmek için terminfo man sayfasına bakın):

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

İşte işleri biraz daha basit hale getirmek için bir araya getirdiğim küçük bir sarmalayıcı sınıfı.

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

Kullanımı:

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

Yukarıdaki Ruby betiğinin çıktısı

Son olarak, bir mücevher istemiyorsanız, burada açıklandığı gibitput programa güvenebilirsiniz - Ruby örneği:

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

4
Binbaşı, binbaşı + 1 tput. Beni ne kadar saç dökülmesinden tputkurtardığını bile söyleyemem .
Pierce

14

Yardımcı olabilecek bu yöntemi yaptım. Önemli değil ama işe yarıyor:

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

Bunu nasıl kullanacağınız aşağıda açıklanmıştır:

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

Olası iyileştirmeler şunlar olabilir:

  • colorsve bgColorsyöntem her çağrıldığında tanımlanıyor ve değişmiyor.
  • Diğer seçenekler ekleyin gibi bold, underline, dimvb

Bu yöntem için çalışmaz pgibi pbir does inspectonun argüman için. Örneğin:

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

"\ e [0; 38mMerhaba Dünya \ e [0m" gösterecektir

Ben bunu test puts, printve Kaydedici mücevher ve para cezası çalışır.


Bunu geliştirdim ve bir sınıf yaptım colorsve bgColorssınıf sabitleri vecolorize bir sınıf yöntemidir:

DÜZENLEME: Daha iyi kod stili, sınıf değişkenleri yerine tanımlı sabitler, dize yerine semboller kullanarak, kalın, italik vb. Gibi daha fazla seçenek eklendi.

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

Aşağıdakileri yaparak kullanabilirsiniz:

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

İşte herhangi bir mücevher gerekmeden çalışması için yaptım:

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

Sonra sadece tırnak içindeki metin renklidir ve düzenli olarak programlanan programınıza geri dönersiniz.


3
Benim için çalışmıyor. Anlıyorum:e[32mSOMETEXT
Oscar Godson

ilk kaçış karakterinde bir yazım hatası vardı: "\e(...)"yerine olmalı"e\(...)"
artthropod

12

Birkaç tane buldum:

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

Örnekler:

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

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

Örnekler:

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

http://github.com/sickill/rainbow

Misal:

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

Windows'taysanız, renk desteğini etkinleştirmek için bir "gem install win32console" yapmanız gerekebilir.

Ayrıca kendi geminizi oluşturmanız gerekiyorsa Renklendirme konsolu Ruby-script çıktısı yararlıdır. Dizelere ANSI renklendirmenin nasıl ekleneceğini açıklar. Bu bilgiyi, dizeyi veya başka bir şeyi genişleten bir sınıfa sarmak için kullanabilirsiniz.



3

Ben günlük çıkışı gibi bir şey renklendirmek istiyorsa yukarıdaki cevapları Ancak tasarı sığmadı yararlı olduğu tespit etmeden herhangi bir üçüncü taraf kütüphanelerini kullanarak. Aşağıdakiler benim için sorunu çözdü:

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

Umut ediyorum bu yardım eder!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.