Last active
September 6, 2015 16:06
-
-
Save daphee/90f4276fa5c0826167af to your computer and use it in GitHub Desktop.
Carc.in: http://carc.in/#/r/dxv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "colorize" | |
# I think a pure regex solution isn't possible unfortunately | |
# This regex is still reall handy becomes you can | |
# go from escape code group to escape code and get the text in between | |
FORMAT_GROUPS_REG = /(?:\e\[(?:(?:[0-9]{1,3});)*(?:[0-9]{1,3})m)+([^\e]+)/ | |
# Procues something like #<MatchData "\e[33;1m\e[99mT" 1:"T"> | |
# This now exctracts the styles from the groups of escape codes | |
# This is a number either followed by a 'm' or a ';' | |
FORMAT_REG = /([0-9]{1,3})[;m]/ | |
# To figure out if e.g. the number 33 'overwrites' a current active number of '93' | |
# We have to know wether both are of the same type (fg, bg or text style) | |
FG_COLORS = [] of Int32 | |
{% for name in Colorize::Object::COLORS %} | |
FG_COLORS << Colorize::Object::FORE_{{name.upcase.id}}.to_i | |
{% end %} | |
BG_COLORS = [] of Int32 | |
{% for name in Colorize::Object::COLORS %} | |
BG_COLORS << Colorize::Object::BACK_{{name.upcase.id}}.to_i | |
{% end %} | |
TEXT_STYLES = [1, 4] | |
def optimize input | |
output = "" | |
current_format = { | |
:fg => -1, | |
:bg => -1, | |
:style => -1 | |
} | |
s = "Splitted:\n" | |
input.scan(FORMAT_GROUPS_REG).each do |match| | |
if match | |
text = match[1] || "" | |
styles = match[0].scan(FORMAT_REG).map {|match| match[1].to_s.to_i} | |
s += "\t'#{text}' #{styles}" # debug only | |
this_format = {} of Symbol => Int32 | |
styles.each do |style| | |
# This could be done in a less readable way | |
# By iterating over an array [:fg, :bg, :style] | |
if FG_COLORS.includes? style | |
this_format[:fg] = style | |
elsif BG_COLORS.includes? style | |
this_format[:bg] = style | |
elsif TEXT_STYLES.includes? style | |
this_format[:style] = style | |
elsif style == 0 | |
# Just set every value to 0 | |
# This could be done in a less readable way by | |
# Including 0 in the fg_color, BG_COLORS, TEXT_STYLES array. | |
this_format[:fg] = this_format[:bg] = this_format[:style] = 0 | |
else | |
raise Exception.new "Don't know what to do with style code '#{style}'" | |
end | |
end | |
s += " => #{this_format.values}" | |
s_helper = [] of Colorize::Object(Int32) | |
changed_styles = [] of Int32 | |
this_format.each_with_index do |format_type, value| | |
# If has changed, update current_format and save to write to output string later | |
if current_format[format_type] != value | |
current_format[format_type] = value | |
changed_styles << value | |
s_helper << value.colorize.green | |
else | |
s_helper << value.colorize.red | |
end | |
end | |
# \e[0m is translated to :fg, :bg, :style => 0 | |
# And we don't want multiple zeroes | |
changed_styles.uniq! | |
s += " => #{s_helper}\n" | |
# Write changed style to output string | |
output += "\e[#{changed_styles.join(";")}m" if changed_styles.length > 0 | |
output += text | |
end | |
end | |
puts s,"" | |
puts "Input: #{input.inspect}\n" | |
puts "Output: #{output.inspect}\n" | |
puts "Input: #{input}\e[0m\n" | |
puts "Output: #{output}\e[0m\n" | |
output | |
end | |
input = "\e[33;1m\e[95mT\e[33;1me\e[33;4ms\e[33mt \e[4mTest \e[0m\e[34mTest \e[33m Test" | |
optimize(input) | |
puts | |
optimize("\e[44m \e[44m \e[44m \e[44m \e[44m \e[44m \e[44m \e[44m \e[44m \e[44m \e[44m ") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment