Commit 29a55fdc authored by Peter Schultz's avatar Peter Schultz
Browse files

rewriting ansi2html

adds support for
- background color (16 and 256 color tables)
- normal and bright color (16 color table)
- bold text
- italic text
- underlined text
- crossed-out text
- concealed text
parent 127e5da4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@import "bootstrap";
@import "font-awesome";
@import "xterm";

$style_color: #289;

+904 −0
Original line number Diff line number Diff line
// color codes are based on http://en.wikipedia.org/wiki/File:Xterm_256color_chart.svg
// see also: https://gist.github.com/jasonm23/2868981

$black: #000000;
$red: #cd0000;
$green: #00cd00;
$yellow: #cdcd00;
$blue: #0000ee;   // according to wikipedia, this is the xterm standard
//$blue: #1e90ff; // this is used by all the terminals I tried (when configured with the xterm color profile)
$magenta: #cd00cd;
$cyan: #00cdcd;
$white: #e5e5e5;
$l-black: #7f7f7f;
$l-red: #ff0000;
$l-green: #00ff00;
$l-yellow: #ffff00;
$l-blue: #5c5cff;
$l-magenta: #ff00ff;
$l-cyan: #00ffff;
$l-white: #ffffff;

.term-bold {
    font-weight: bold;
}
.term-italic {
    font-style: italic;
}
.term-conceal {
    visibility: hidden;
}
.term-underline {
    text-decoration: underline;
}
.term-cross {
    text-decoration: line-through;
}

.term-fg-black {
  color: $black;
}
.term-fg-red {
  color: $red;
}
.term-fg-green {
  color: $green;
}
.term-fg-yellow {
  color: $yellow;
}
.term-fg-blue {
  color: $blue;
}
.term-fg-magenta {
  color: $magenta;
}
.term-fg-cyan {
  color: $cyan;
}
.term-fg-white {
  color: $white;
}
.term-fg-l-black {
  color: $l-black;
}
.term-fg-l-red {
  color: $l-red;
}
.term-fg-l-green {
  color: $l-green;
}
.term-fg-l-yellow {
  color: $l-yellow;
}
.term-fg-l-blue {
  color: $l-blue;
}
.term-fg-l-magenta {
  color: $l-magenta;
}
.term-fg-l-cyan {
  color: $l-cyan;
}
.term-fg-l-white {
  color: $l-white;
}

.term-bg-black {
  background-color: $black;
}
.term-bg-red {
  background-color: $red;
}
.term-bg-green {
  background-color: $green;
}
.term-bg-yellow {
  background-color: $yellow;
}
.term-bg-blue {
  background-color: $blue;
}
.term-bg-magenta {
  background-color: $magenta;
}
.term-bg-cyan {
  background-color: $cyan;
}
.term-bg-white {
  background-color: $white;
}
.term-bg-l-black {
  background-color: $l-black;
}
.term-bg-l-red {
  background-color: $l-red;
}
.term-bg-l-green {
  background-color: $l-green;
}
.term-bg-l-yellow {
  background-color: $l-yellow;
}
.term-bg-l-blue {
  background-color: $l-blue;
}
.term-bg-l-magenta {
  background-color: $l-magenta;
}
.term-bg-l-cyan {
  background-color: $l-cyan;
}
.term-bg-l-white {
  background-color: $l-white;
}


.xterm-fg-0 {
  color: #000000;
}
.xterm-fg-1 {
  color: #800000;
}
.xterm-fg-2 {
  color: #008000;
}
.xterm-fg-3 {
  color: #808000;
}
.xterm-fg-4 {
  color: #000080;
}
.xterm-fg-5 {
  color: #800080;
}
.xterm-fg-6 {
  color: #008080;
}
.xterm-fg-7 {
  color: #c0c0c0;
}
.xterm-fg-8 {
  color: #808080;
}
.xterm-fg-9 {
  color: #ff0000;
}
.xterm-fg-10 {
  color: #00ff00;
}
.xterm-fg-11 {
  color: #ffff00;
}
.xterm-fg-12 {
  color: #0000ff;
}
.xterm-fg-13 {
  color: #ff00ff;
}
.xterm-fg-14 {
  color: #00ffff;
}
.xterm-fg-15 {
  color: #ffffff;
}
.xterm-fg-16 {
  color: #000000;
}
.xterm-fg-17 {
  color: #00005f;
}
.xterm-fg-18 {
  color: #000087;
}
.xterm-fg-19 {
  color: #0000af;
}
.xterm-fg-20 {
  color: #0000d7;
}
.xterm-fg-21 {
  color: #0000ff;
}
.xterm-fg-22 {
  color: #005f00;
}
.xterm-fg-23 {
  color: #005f5f;
}
.xterm-fg-24 {
  color: #005f87;
}
.xterm-fg-25 {
  color: #005faf;
}
.xterm-fg-26 {
  color: #005fd7;
}
.xterm-fg-27 {
  color: #005fff;
}
.xterm-fg-28 {
  color: #008700;
}
.xterm-fg-29 {
  color: #00875f;
}
.xterm-fg-30 {
  color: #008787;
}
.xterm-fg-31 {
  color: #0087af;
}
.xterm-fg-32 {
  color: #0087d7;
}
.xterm-fg-33 {
  color: #0087ff;
}
.xterm-fg-34 {
  color: #00af00;
}
.xterm-fg-35 {
  color: #00af5f;
}
.xterm-fg-36 {
  color: #00af87;
}
.xterm-fg-37 {
  color: #00afaf;
}
.xterm-fg-38 {
  color: #00afd7;
}
.xterm-fg-39 {
  color: #00afff;
}
.xterm-fg-40 {
  color: #00d700;
}
.xterm-fg-41 {
  color: #00d75f;
}
.xterm-fg-42 {
  color: #00d787;
}
.xterm-fg-43 {
  color: #00d7af;
}
.xterm-fg-44 {
  color: #00d7d7;
}
.xterm-fg-45 {
  color: #00d7ff;
}
.xterm-fg-46 {
  color: #00ff00;
}
.xterm-fg-47 {
  color: #00ff5f;
}
.xterm-fg-48 {
  color: #00ff87;
}
.xterm-fg-49 {
  color: #00ffaf;
}
.xterm-fg-50 {
  color: #00ffd7;
}
.xterm-fg-51 {
  color: #00ffff;
}
.xterm-fg-52 {
  color: #5f0000;
}
.xterm-fg-53 {
  color: #5f005f;
}
.xterm-fg-54 {
  color: #5f0087;
}
.xterm-fg-55 {
  color: #5f00af;
}
.xterm-fg-56 {
  color: #5f00d7;
}
.xterm-fg-57 {
  color: #5f00ff;
}
.xterm-fg-58 {
  color: #5f5f00;
}
.xterm-fg-59 {
  color: #5f5f5f;
}
.xterm-fg-60 {
  color: #5f5f87;
}
.xterm-fg-61 {
  color: #5f5faf;
}
.xterm-fg-62 {
  color: #5f5fd7;
}
.xterm-fg-63 {
  color: #5f5fff;
}
.xterm-fg-64 {
  color: #5f8700;
}
.xterm-fg-65 {
  color: #5f875f;
}
.xterm-fg-66 {
  color: #5f8787;
}
.xterm-fg-67 {
  color: #5f87af;
}
.xterm-fg-68 {
  color: #5f87d7;
}
.xterm-fg-69 {
  color: #5f87ff;
}
.xterm-fg-70 {
  color: #5faf00;
}
.xterm-fg-71 {
  color: #5faf5f;
}
.xterm-fg-72 {
  color: #5faf87;
}
.xterm-fg-73 {
  color: #5fafaf;
}
.xterm-fg-74 {
  color: #5fafd7;
}
.xterm-fg-75 {
  color: #5fafff;
}
.xterm-fg-76 {
  color: #5fd700;
}
.xterm-fg-77 {
  color: #5fd75f;
}
.xterm-fg-78 {
  color: #5fd787;
}
.xterm-fg-79 {
  color: #5fd7af;
}
.xterm-fg-80 {
  color: #5fd7d7;
}
.xterm-fg-81 {
  color: #5fd7ff;
}
.xterm-fg-82 {
  color: #5fff00;
}
.xterm-fg-83 {
  color: #5fff5f;
}
.xterm-fg-84 {
  color: #5fff87;
}
.xterm-fg-85 {
  color: #5fffaf;
}
.xterm-fg-86 {
  color: #5fffd7;
}
.xterm-fg-87 {
  color: #5fffff;
}
.xterm-fg-88 {
  color: #870000;
}
.xterm-fg-89 {
  color: #87005f;
}
.xterm-fg-90 {
  color: #870087;
}
.xterm-fg-91 {
  color: #8700af;
}
.xterm-fg-92 {
  color: #8700d7;
}
.xterm-fg-93 {
  color: #8700ff;
}
.xterm-fg-94 {
  color: #875f00;
}
.xterm-fg-95 {
  color: #875f5f;
}
.xterm-fg-96 {
  color: #875f87;
}
.xterm-fg-97 {
  color: #875faf;
}
.xterm-fg-98 {
  color: #875fd7;
}
.xterm-fg-99 {
  color: #875fff;
}
.xterm-fg-100 {
  color: #878700;
}
.xterm-fg-101 {
  color: #87875f;
}
.xterm-fg-102 {
  color: #878787;
}
.xterm-fg-103 {
  color: #8787af;
}
.xterm-fg-104 {
  color: #8787d7;
}
.xterm-fg-105 {
  color: #8787ff;
}
.xterm-fg-106 {
  color: #87af00;
}
.xterm-fg-107 {
  color: #87af5f;
}
.xterm-fg-108 {
  color: #87af87;
}
.xterm-fg-109 {
  color: #87afaf;
}
.xterm-fg-110 {
  color: #87afd7;
}
.xterm-fg-111 {
  color: #87afff;
}
.xterm-fg-112 {
  color: #87d700;
}
.xterm-fg-113 {
  color: #87d75f;
}
.xterm-fg-114 {
  color: #87d787;
}
.xterm-fg-115 {
  color: #87d7af;
}
.xterm-fg-116 {
  color: #87d7d7;
}
.xterm-fg-117 {
  color: #87d7ff;
}
.xterm-fg-118 {
  color: #87ff00;
}
.xterm-fg-119 {
  color: #87ff5f;
}
.xterm-fg-120 {
  color: #87ff87;
}
.xterm-fg-121 {
  color: #87ffaf;
}
.xterm-fg-122 {
  color: #87ffd7;
}
.xterm-fg-123 {
  color: #87ffff;
}
.xterm-fg-124 {
  color: #af0000;
}
.xterm-fg-125 {
  color: #af005f;
}
.xterm-fg-126 {
  color: #af0087;
}
.xterm-fg-127 {
  color: #af00af;
}
.xterm-fg-128 {
  color: #af00d7;
}
.xterm-fg-129 {
  color: #af00ff;
}
.xterm-fg-130 {
  color: #af5f00;
}
.xterm-fg-131 {
  color: #af5f5f;
}
.xterm-fg-132 {
  color: #af5f87;
}
.xterm-fg-133 {
  color: #af5faf;
}
.xterm-fg-134 {
  color: #af5fd7;
}
.xterm-fg-135 {
  color: #af5fff;
}
.xterm-fg-136 {
  color: #af8700;
}
.xterm-fg-137 {
  color: #af875f;
}
.xterm-fg-138 {
  color: #af8787;
}
.xterm-fg-139 {
  color: #af87af;
}
.xterm-fg-140 {
  color: #af87d7;
}
.xterm-fg-141 {
  color: #af87ff;
}
.xterm-fg-142 {
  color: #afaf00;
}
.xterm-fg-143 {
  color: #afaf5f;
}
.xterm-fg-144 {
  color: #afaf87;
}
.xterm-fg-145 {
  color: #afafaf;
}
.xterm-fg-146 {
  color: #afafd7;
}
.xterm-fg-147 {
  color: #afafff;
}
.xterm-fg-148 {
  color: #afd700;
}
.xterm-fg-149 {
  color: #afd75f;
}
.xterm-fg-150 {
  color: #afd787;
}
.xterm-fg-151 {
  color: #afd7af;
}
.xterm-fg-152 {
  color: #afd7d7;
}
.xterm-fg-153 {
  color: #afd7ff;
}
.xterm-fg-154 {
  color: #afff00;
}
.xterm-fg-155 {
  color: #afff5f;
}
.xterm-fg-156 {
  color: #afff87;
}
.xterm-fg-157 {
  color: #afffaf;
}
.xterm-fg-158 {
  color: #afffd7;
}
.xterm-fg-159 {
  color: #afffff;
}
.xterm-fg-160 {
  color: #d70000;
}
.xterm-fg-161 {
  color: #d7005f;
}
.xterm-fg-162 {
  color: #d70087;
}
.xterm-fg-163 {
  color: #d700af;
}
.xterm-fg-164 {
  color: #d700d7;
}
.xterm-fg-165 {
  color: #d700ff;
}
.xterm-fg-166 {
  color: #d75f00;
}
.xterm-fg-167 {
  color: #d75f5f;
}
.xterm-fg-168 {
  color: #d75f87;
}
.xterm-fg-169 {
  color: #d75faf;
}
.xterm-fg-170 {
  color: #d75fd7;
}
.xterm-fg-171 {
  color: #d75fff;
}
.xterm-fg-172 {
  color: #d78700;
}
.xterm-fg-173 {
  color: #d7875f;
}
.xterm-fg-174 {
  color: #d78787;
}
.xterm-fg-175 {
  color: #d787af;
}
.xterm-fg-176 {
  color: #d787d7;
}
.xterm-fg-177 {
  color: #d787ff;
}
.xterm-fg-178 {
  color: #d7af00;
}
.xterm-fg-179 {
  color: #d7af5f;
}
.xterm-fg-180 {
  color: #d7af87;
}
.xterm-fg-181 {
  color: #d7afaf;
}
.xterm-fg-182 {
  color: #d7afd7;
}
.xterm-fg-183 {
  color: #d7afff;
}
.xterm-fg-184 {
  color: #d7d700;
}
.xterm-fg-185 {
  color: #d7d75f;
}
.xterm-fg-186 {
  color: #d7d787;
}
.xterm-fg-187 {
  color: #d7d7af;
}
.xterm-fg-188 {
  color: #d7d7d7;
}
.xterm-fg-189 {
  color: #d7d7ff;
}
.xterm-fg-190 {
  color: #d7ff00;
}
.xterm-fg-191 {
  color: #d7ff5f;
}
.xterm-fg-192 {
  color: #d7ff87;
}
.xterm-fg-193 {
  color: #d7ffaf;
}
.xterm-fg-194 {
  color: #d7ffd7;
}
.xterm-fg-195 {
  color: #d7ffff;
}
.xterm-fg-196 {
  color: #ff0000;
}
.xterm-fg-197 {
  color: #ff005f;
}
.xterm-fg-198 {
  color: #ff0087;
}
.xterm-fg-199 {
  color: #ff00af;
}
.xterm-fg-200 {
  color: #ff00d7;
}
.xterm-fg-201 {
  color: #ff00ff;
}
.xterm-fg-202 {
  color: #ff5f00;
}
.xterm-fg-203 {
  color: #ff5f5f;
}
.xterm-fg-204 {
  color: #ff5f87;
}
.xterm-fg-205 {
  color: #ff5faf;
}
.xterm-fg-206 {
  color: #ff5fd7;
}
.xterm-fg-207 {
  color: #ff5fff;
}
.xterm-fg-208 {
  color: #ff8700;
}
.xterm-fg-209 {
  color: #ff875f;
}
.xterm-fg-210 {
  color: #ff8787;
}
.xterm-fg-211 {
  color: #ff87af;
}
.xterm-fg-212 {
  color: #ff87d7;
}
.xterm-fg-213 {
  color: #ff87ff;
}
.xterm-fg-214 {
  color: #ffaf00;
}
.xterm-fg-215 {
  color: #ffaf5f;
}
.xterm-fg-216 {
  color: #ffaf87;
}
.xterm-fg-217 {
  color: #ffafaf;
}
.xterm-fg-218 {
  color: #ffafd7;
}
.xterm-fg-219 {
  color: #ffafff;
}
.xterm-fg-220 {
  color: #ffd700;
}
.xterm-fg-221 {
  color: #ffd75f;
}
.xterm-fg-222 {
  color: #ffd787;
}
.xterm-fg-223 {
  color: #ffd7af;
}
.xterm-fg-224 {
  color: #ffd7d7;
}
.xterm-fg-225 {
  color: #ffd7ff;
}
.xterm-fg-226 {
  color: #ffff00;
}
.xterm-fg-227 {
  color: #ffff5f;
}
.xterm-fg-228 {
  color: #ffff87;
}
.xterm-fg-229 {
  color: #ffffaf;
}
.xterm-fg-230 {
  color: #ffffd7;
}
.xterm-fg-231 {
  color: #ffffff;
}
.xterm-fg-232 {
  color: #080808;
}
.xterm-fg-233 {
  color: #121212;
}
.xterm-fg-234 {
  color: #1c1c1c;
}
.xterm-fg-235 {
  color: #262626;
}
.xterm-fg-236 {
  color: #303030;
}
.xterm-fg-237 {
  color: #3a3a3a;
}
.xterm-fg-238 {
  color: #444444;
}
.xterm-fg-239 {
  color: #4e4e4e;
}
.xterm-fg-240 {
  color: #585858;
}
.xterm-fg-241 {
  color: #626262;
}
.xterm-fg-242 {
  color: #6c6c6c;
}
.xterm-fg-243 {
  color: #767676;
}
.xterm-fg-244 {
  color: #808080;
}
.xterm-fg-245 {
  color: #8a8a8a;
}
.xterm-fg-246 {
  color: #949494;
}
.xterm-fg-247 {
  color: #9e9e9e;
}
.xterm-fg-248 {
  color: #a8a8a8;
}
.xterm-fg-249 {
  color: #b2b2b2;
}
.xterm-fg-250 {
  color: #bcbcbc;
}
.xterm-fg-251 {
  color: #c6c6c6;
}
.xterm-fg-252 {
  color: #d0d0d0;
}
.xterm-fg-253 {
  color: #dadada;
}
.xterm-fg-254 {
  color: #e4e4e4;
}
.xterm-fg-255 {
  color: #eeeeee;
}
+206 −28
Original line number Diff line number Diff line
# ANSI color library
#
# Implementation per http://en.wikipedia.org/wiki/ANSI_escape_code
module Ansi2html
  # keys represent the trailing digit in color changing command (30-37, 40-47, 90-97. 100-107)
  COLOR = {
    '30' => 'black',
    '31' => 'red',
    '32' => 'green',
    '33' => 'yellow',
    '34' => 'blue',
    '35' => 'magenta',
    '36' => 'cyan',
    '37' => 'white',
    '90' => 'grey'
    0 => 'black', # not that this is gray in the intense color table
    1 => 'red',
    2 => 'green',
    3 => 'yellow',
    4 => 'blue',
    5 => 'magenta',
    6 => 'cyan',
    7 => 'white', # not that this is gray in the dark (aka default) color table
  }

  STYLE_SWITCHES = {
    :bold      => 0x01,
    :italic    => 0x02,
    :underline => 0x04,
    :conceal   => 0x08,
    :cross     => 0x10,
  }

  def self.convert(ansi)
    out = ""
    tag_open = false
    Converter.new().convert(ansi)
  end

  class Converter
    def on_0(s) reset()                            end
    def on_1(s) enable(STYLE_SWITCHES[:bold])      end
    def on_3(s) enable(STYLE_SWITCHES[:italic])    end
    def on_4(s) enable(STYLE_SWITCHES[:underline]) end
    def on_8(s) enable(STYLE_SWITCHES[:conceal])   end
    def on_9(s) enable(STYLE_SWITCHES[:cross])     end

    def on_21(s) disable(STYLE_SWITCHES[:bold])      end
    def on_22(s) disable(STYLE_SWITCHES[:bold])      end
    def on_23(s) disable(STYLE_SWITCHES[:italic])    end
    def on_24(s) disable(STYLE_SWITCHES[:underline]) end
    def on_28(s) disable(STYLE_SWITCHES[:conceal])   end
    def on_29(s) disable(STYLE_SWITCHES[:cross])     end

    def on_30(s) set_fg_color(0) end
    def on_31(s) set_fg_color(1) end
    def on_32(s) set_fg_color(2) end
    def on_33(s) set_fg_color(3) end
    def on_34(s) set_fg_color(4) end
    def on_35(s) set_fg_color(5) end
    def on_36(s) set_fg_color(6) end
    def on_37(s) set_fg_color(7) end
    def on_38(s) set_fg_color_256(s) end
    def on_39(s) set_fg_color(9) end

    def on_40(s) set_bg_color(0) end
    def on_41(s) set_bg_color(1) end
    def on_42(s) set_bg_color(2) end
    def on_43(s) set_bg_color(3) end
    def on_44(s) set_bg_color(4) end
    def on_45(s) set_bg_color(5) end
    def on_46(s) set_bg_color(6) end
    def on_47(s) set_bg_color(7) end
    def on_48(s) set_bg_color_256(s) end
    def on_49(s) set_bg_color(9) end

    def on_90(s) set_fg_color(0, 'l') end
    def on_91(s) set_fg_color(1, 'l') end
    def on_92(s) set_fg_color(2, 'l') end
    def on_93(s) set_fg_color(3, 'l') end
    def on_94(s) set_fg_color(4, 'l') end
    def on_95(s) set_fg_color(5, 'l') end
    def on_96(s) set_fg_color(6, 'l') end
    def on_97(s) set_fg_color(7, 'l') end
    def on_99(s) set_fg_color(9, 'l') end

    def on_100(s) set_bg_color(0, 'l') end
    def on_101(s) set_bg_color(1, 'l') end
    def on_102(s) set_bg_color(2, 'l') end
    def on_103(s) set_bg_color(3, 'l') end
    def on_104(s) set_bg_color(4, 'l') end
    def on_105(s) set_bg_color(5, 'l') end
    def on_106(s) set_bg_color(6, 'l') end
    def on_107(s) set_bg_color(7, 'l') end
    def on_109(s) set_bg_color(9, 'l') end

    def convert(ansi)
      @out = ""
      @n_open_tags = 0
      reset()

      s = StringScanner.new(ansi.gsub("<", "&lt;"))
      while(!s.eos?)
      if s.scan(/\e\[(3[0-7]|90)m/) || s.scan(/\e\[1;(3[0-7])m/)
        if tag_open
          out << %{</span>}
        end
        out << %{<span class="#{COLOR[s[1]]}">}
        tag_open = true
      elsif s.scan(/\e\[1m/)
        # Just ignore bold style
        if s.scan(/\e([@-_])(.*?)([@-~])/)
          handle_sequence(s)
        else
        if s.scan(/\e\[0m/)
          if tag_open
            out << %{</span>}
          @out << s.scan(/./m)
        end
          tag_open = false
        else
          out << s.scan(/./m)
      end

      close_open_tags()
      @out
    end

    def handle_sequence(s)
      indicator = s[1]
      commands = s[2].split ';'
      terminator = s[3]

      # We are only interested in color and text style changes - triggered by
      # sequences starting with '\e[' and ending with 'm'. Any other control
      # sequence gets stripped (including stuff like "delete last line")
      return unless indicator == '[' and terminator == 'm'

      close_open_tags()

      if commands.empty?()
        reset()
        return
      end

      evaluate_command_stack(commands)

      css_classes = []

      unless @fg_color.nil?
        fg_color = @fg_color
        # Most terminals show bold colored text in the light color variant
        # Let's mimic that here
        if @style_mask & STYLE_SWITCHES[:bold] != 0
          fg_color.sub!(/fg-(\w{2,}+)/, 'fg-l-\1')
        end
        css_classes << fg_color
      end
    if tag_open
      out << %{</span>}
      css_classes << @bg_color unless @bg_color.nil?

      STYLE_SWITCHES.each do |css_class, flag|
        css_classes << "term-#{css_class}" if @style_mask & flag != 0
      end

      open_new_tag(css_classes) if css_classes.length > 0
    end

    def evaluate_command_stack(stack)
      return unless command = stack.shift()

      if self.respond_to?("on_#{command}", true)
        self.send("on_#{command}", stack)
      end

      evaluate_command_stack(stack)
    end

    def open_new_tag(css_classes)
      @out << %{<span class="#{css_classes.join(' ')}">}
      @n_open_tags += 1
    end

    def close_open_tags
      while @n_open_tags > 0
        @out << %{</span>}
        @n_open_tags -= 1
      end
    end

    def reset
      @fg_color = nil
      @bg_color = nil
      @style_mask = 0
    end

    def enable(flag)
      @style_mask |= flag
    end

    def disable(flag)
      @style_mask &= ~flag
    end

    def set_fg_color(color_index, prefix = nil)
      @fg_color = get_term_color_class(color_index, ["fg", prefix])
    end

    def set_bg_color(color_index, prefix = nil)
      @bg_color = get_term_color_class(color_index, ["bg", prefix])
    end

    def get_term_color_class(color_index, prefix)
      color_name = COLOR[color_index]
      return nil if color_name.nil?

      return get_color_class(["term", prefix, color_name])
    end

    def set_fg_color_256(command_stack)
      css_class = get_xterm_color_class(command_stack, "fg")
      @fg_color = css_class unless css_class.nil?
    end

    def set_bg_color_256(command_stack)
      css_class = get_xterm_color_class(command_stack, "bg")
      @bg_color = css_class unless css_class.nil?
    end

    def get_xterm_color_class(command_stack, prefix)
      # the 38 and 48 commands have to be followed by "5" and the color index
      return unless command_stack.length >= 2
      return unless command_stack[0] == "5"

      command_stack.shift() # ignore the "5" command
      color_index = command_stack.shift().to_i

      return unless color_index >= 0
      return unless color_index <= 255

      return get_color_class(["xterm", prefix, color_index])
    end

    def get_color_class(segments)
      return [segments].flatten.compact.join('-')
    end
    out
  end
end
+110 −12

File changed.

Preview size limit exceeded, changes collapsed.