From 8c63169607603d16c6de4e526cf62810351eb322 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 6 Jun 2017 16:45:31 +0200 Subject: [PATCH] Support RGB color in thumbnails --- app/decorators/brush_decorator.rb | 22 ++++++- app/decorators/cell_decorator.rb | 1 + app/models/brush.rb | 14 +++-- app/views/asciicasts/_thumbnail.html.slim | 2 +- spec/decorators/brush_decorator_spec.rb | 70 ++++++++++++++++++++++- spec/models/brush_spec.rb | 4 ++ 6 files changed, 104 insertions(+), 9 deletions(-) diff --git a/app/decorators/brush_decorator.rb b/app/decorators/brush_decorator.rb index ebd332f..c30ce24 100644 --- a/app/decorators/brush_decorator.rb +++ b/app/decorators/brush_decorator.rb @@ -9,14 +9,32 @@ class BrushDecorator < ApplicationDecorator end end + def css_style + attrs = {} + + if Brush.rgb_color?(model.fg) + r, g, b = model.fg + attrs['color'] = "rgb(#{r},#{b},#{g})" + end + + if Brush.rgb_color?(model.bg) + r, g, b = model.bg + attrs['background-color'] = "rgb(#{r},#{b},#{g})" + end + + if !attrs.empty? + attrs.reduce("") { |acc, kv| acc + "#{kv[0]}:#{kv[1]};" } + end + end + private def fg_class - "fg-#{model.fg}" if model.fg + "fg-#{model.fg}" if model.fg && !Brush.rgb_color?(model.fg) end def bg_class - "bg-#{model.bg}" if model.bg + "bg-#{model.bg}" if model.bg && !Brush.rgb_color?(model.bg) end def bold_class diff --git a/app/decorators/cell_decorator.rb b/app/decorators/cell_decorator.rb index 8741207..2f21342 100644 --- a/app/decorators/cell_decorator.rb +++ b/app/decorators/cell_decorator.rb @@ -2,6 +2,7 @@ class CellDecorator < ApplicationDecorator delegate_all delegate :css_class, to: :brush + delegate :css_style, to: :brush def brush BrushDecorator.new(model.brush) diff --git a/app/models/brush.rb b/app/models/brush.rb index 9e1edf8..28e156a 100644 --- a/app/models/brush.rb +++ b/app/models/brush.rb @@ -48,6 +48,14 @@ class Brush attributes.slice(*ALLOWED_ATTRIBUTES) end + def self.rgb_color?(col) + col.is_a?(Enumerable) + end + + def self.simple_color?(col) + col.is_a?(Fixnum) + end + protected attr_reader :attributes @@ -65,10 +73,8 @@ class Brush def calculate_code(attr_name, strong) code = attributes[attr_name] - if code - if code < 8 && strong - code += 8 - end + if Brush.simple_color?(code) && code < 8 && strong + code += 8 end code diff --git a/app/views/asciicasts/_thumbnail.html.slim b/app/views/asciicasts/_thumbnail.html.slim index a482496..cffaf34 100644 --- a/app/views/asciicasts/_thumbnail.html.slim +++ b/app/views/asciicasts/_thumbnail.html.slim @@ -2,5 +2,5 @@ pre.asciinema-terminal.font-small - for line in thumbnail.lines span.line - for cell in line - span class=cell.css_class = cell.text + span class=cell.css_class style=cell.css_style = cell.text = "\n" diff --git a/spec/decorators/brush_decorator_spec.rb b/spec/decorators/brush_decorator_spec.rb index 1ad5819..6322ff4 100644 --- a/spec/decorators/brush_decorator_spec.rb +++ b/spec/decorators/brush_decorator_spec.rb @@ -29,7 +29,7 @@ describe BrushDecorator do it { should_not match(/\bfg/) } end - context "when fg is non-default" do + context "when fg is non-default (number)" do before do allow(brush).to receive(:fg) { 1 } end @@ -37,6 +37,14 @@ describe BrushDecorator do it { should match(/\bfg-1\b/) } end + context "when fg is non-default (rgb)" do + before do + allow(brush).to receive(:fg) { [1, 2, 3] } + end + + it { should eq("") } + end + context "when bg is default" do before do allow(brush).to receive(:bg) { nil } @@ -45,7 +53,7 @@ describe BrushDecorator do it { should_not match(/\bbg/) } end - context "when bg is non-default" do + context "when bg is non-default (number)" do before do allow(brush).to receive(:bg) { 2 } end @@ -53,6 +61,14 @@ describe BrushDecorator do it { should match(/\bbg-2\b/) } end + context "when bg is non-default (rgb)" do + before do + allow(brush).to receive(:bg) { [1, 2, 3] } + end + + it { should eq("") } + end + context "when both fg and bg are non-default" do before do allow(brush).to receive(:fg) { 1 } @@ -80,4 +96,54 @@ describe BrushDecorator do end end end + + describe '#css_style' do + subject { decorator.css_style } + + context "when brush is a default one" do + before do + allow(brush).to receive(:default?) { true } + end + + it { should be(nil) } + end + + context "when brush is not a default one" do + before do + allow(brush).to receive(:default?) { false } + end + + context "when fg is non-default (number)" do + before do + allow(brush).to receive(:fg) { 1 } + end + + it { should be(nil) } + end + + context "when fg is non-default (rgb)" do + before do + allow(brush).to receive(:fg) { [229, 222, 19] } + end + + it { should match(/color:rgb\(\d+,\d+,\d+\)/) } + end + + context "when bg is non-default (number)" do + before do + allow(brush).to receive(:bg) { 2 } + end + + it { should be(nil) } + end + + context "when bg is non-default (rgb)" do + before do + allow(brush).to receive(:bg) { [111, 222, 255] } + end + + it { should match(/background-color:rgb\(\d+,\d+,\d+\)/) } + end + end + end end diff --git a/spec/models/brush_spec.rb b/spec/models/brush_spec.rb index 92a5afe..8aad1a1 100644 --- a/spec/models/brush_spec.rb +++ b/spec/models/brush_spec.rb @@ -60,6 +60,10 @@ describe Brush do expect(Brush.new(bg: 0, inverse: true, blink: true).fg).to eq(8) expect(Brush.new(inverse: true, blink: true).fg).to eq(0) end + + it 'supports rgb color' do + expect(Brush.new(fg: [229, 222, 19]).fg).to eq([229, 222, 19]) + end end describe '#bg' do