From c84f0464d2a85c987e3dd54e4731589559933471 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Tue, 9 Sep 2014 11:28:43 -0400 Subject: [PATCH 1/3] ColorCodes: simplify and comment a bit. - Simplify logic and increase explanation to make it easier for the casual reader. - Remove the undocumented, untested and not-clearly-working "percentage" support. - Replace `eval` with `try`, as is my wont. Addresses #620. --- lib/DDG/Goodie/ColorCodes.pm | 91 ++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/lib/DDG/Goodie/ColorCodes.pm b/lib/DDG/Goodie/ColorCodes.pm index f46f960fe..21fa806f9 100644 --- a/lib/DDG/Goodie/ColorCodes.pm +++ b/lib/DDG/Goodie/ColorCodes.pm @@ -8,6 +8,7 @@ use Convert::Color; use Convert::Color::Library; use Convert::Color::RGB8; use Math::Round; +use Try::Tiny; my %types = ( # hash of keyword => Convert::Color prefix rgb => 'rgb8', @@ -63,69 +64,69 @@ sub percentify { } my %trigger_invert = map { $_ => 1 } (qw( inverse negative opposite )); -my %trigger_ignore = map { $_ => 1 } (qw( code )); +my %trigger_filler = map { $_ => 1 } (qw( code )); handle matches => sub { - my $type; + my $color; my $inverse; - for (@_) { - next unless defined $_; - my $q = lc; - $type = $types{$q} if exists $types{$q}; - if ($trigger_invert{$q}) { - $inverse = 1; - } elsif (!$trigger_ignore{$q}) { - $color = $q unless defined $type && exists $types{$q}; + my $type = 'rgb8'; # Default type, can be overridden below. + my @matches = @_; + + foreach my $q (map { lc $_ } grep { defined $_ } @matches) { + # $q now contains the defined normalized matches which can be: + if (exists $types{$q}) { + $type = $types{$q}; # - One of our types. + } elsif ($trigger_invert{$q}) { + $inverse = 1; # - An inversion trigger + } elsif (!$trigger_filler{$q}) { # - A filler word for more natural querying + $color = $q; # - A presumed color } } - $type //= 'rgb8'; - my @colorin = split /(?:,\s*|\s+)/, $color; - my @colorout; + return unless $color; # Need a color to continue! - for (@colorin) { - # handle percents - if (/(\d+(?:\.\d+)?)%$/) { - my $num = $1; - $num =~ s/\.//; - my $len = length($num); - return unless $len > 0 && $len <= 3; - push @colorout, "0.0$num" if $len == 1; - push @colorout, "0.$num" if $len == 2; - push @colorout, "$num" if $len == 3; - $type = 'rgb' if $type eq 'rgb8'; - } - else { push @colorout, $_; } - } - $color = join ',', @colorout; + $color =~ s/(,\s*|\s+)/,/g; # Spaces to commas for things like "hsl 194 0.53 0.79" - if ($color =~ /^([0-9a-f]{3,6})$/) { - if(length($color) == 3) { - $color = ''; - $color .= $_.$_ for split '', $1; - } + if ($color =~ /^[0-9a-f]{3,6}$/) { # Color looks like a hex code + $color = join('', map { $_ . $_ } (split '', $color)) if (length($color) == 3); # Make three char hex into six chars by repeating each in turn $type = 'rgb8'; + } else { + try { + # See if we can find the color in one of our dictionaries. + $color = join(',', Convert::Color::Library->new($color_dictionaries . '/' . $color)->as_rgb8->hex); + $type = 'rgb8'; # We asked for rgb8 from our dictionary, so make sure our type matches. + }; } - return unless $type && $color; + my $col = try { Convert::Color->new("$type:$color") }; # Everything should be ready for conversion now. + return unless $col; # Guess not. - eval { $color = join(',',Convert::Color::Library->new($color_dictionaries.'/'.$color)->as_rgb8->hex); $type = 'rgb8'; }; - - my $col; - eval { $col = Convert::Color->new("$type:$color"); }; - return if $@; - - if ($inverse) { - my $rgb = $col->as_rgb8; - $col = Convert::Color::RGB8->new(255 - $rgb->red, 255 - $rgb->green, 255 - $rgb->blue); + if ($inverse) { # We triggered on the inverse, so do the flip. + my $orig_rgb = $col->as_rgb8; + $col = Convert::Color::RGB8->new(255 - $orig_rgb->red, 255 - $orig_rgb->green, 255 - $orig_rgb->blue); } my $rgb = $col->as_rgb8; my $hsl = $col->as_hsl; - my $text = sprintf("Hex: %s ~ rgb(%d, %d, %d) ~ rgb(%s, %s, %s) ~ hsl(%d, %s, %s) ~ cmyb(%s, %s, %s, %s)", '#'.$rgb->hex, $col->as_rgb8->rgb8, percentify($col->as_rgb->rgb), round($hsl->hue), percentify($hsl->saturation, $hsl->lightness, $col->as_cmyk->cmyk)); - return $text, html => '
'.$text." [Images] [Info]"; + + # Create the output! + my $text = sprintf( + "Hex: %s ~ rgb(%d, %d, %d) ~ rgb(%s, %s, %s) ~ hsl(%d, %s, %s) ~ cmyb(%s, %s, %s, %s)", + '#' . $rgb->hex, + $col->as_rgb8->rgb8, percentify($col->as_rgb->rgb), + round($hsl->hue), percentify($hsl->saturation, $hsl->lightness, $col->as_cmyk->cmyk)); + return $text, + html => '
' + . $text + . " [Images] [Info]"; }; 1; From ce92e69d7d1106660e1f3ea46eeee358228251ac Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Tue, 9 Sep 2014 18:23:13 -0400 Subject: [PATCH 2/3] ColorCodes: allow for rgb #123456-style queries --- lib/DDG/Goodie/ColorCodes.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/DDG/Goodie/ColorCodes.pm b/lib/DDG/Goodie/ColorCodes.pm index 21fa806f9..b72a5f91f 100644 --- a/lib/DDG/Goodie/ColorCodes.pm +++ b/lib/DDG/Goodie/ColorCodes.pm @@ -89,7 +89,7 @@ handle matches => sub { $color =~ s/(,\s*|\s+)/,/g; # Spaces to commas for things like "hsl 194 0.53 0.79" - if ($color =~ /^[0-9a-f]{3,6}$/) { # Color looks like a hex code + if ($color =~ s/#?([0-9a-f]{3,6})$/$1/) { # Color looks like a hex code, strip the leading # $color = join('', map { $_ . $_ } (split '', $color)) if (length($color) == 3); # Make three char hex into six chars by repeating each in turn $type = 'rgb8'; } else { From 7ace24facb6d2bb997792c6614d1c6dffe9e9388 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Tue, 9 Sep 2014 18:51:52 -0400 Subject: [PATCH 3/3] ColorCodes: rough in a different HTML template. Real templates are coming, but this is a step. --- lib/DDG/Goodie/ColorCodes.pm | 11 +++++++---- t/ColorCodes.t | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/DDG/Goodie/ColorCodes.pm b/lib/DDG/Goodie/ColorCodes.pm index b72a5f91f..cf1d7fbfa 100644 --- a/lib/DDG/Goodie/ColorCodes.pm +++ b/lib/DDG/Goodie/ColorCodes.pm @@ -111,17 +111,20 @@ handle matches => sub { my $rgb = $col->as_rgb8; my $hsl = $col->as_hsl; - # Create the output! - my $text = sprintf( - "Hex: %s ~ rgb(%d, %d, %d) ~ rgb(%s, %s, %s) ~ hsl(%d, %s, %s) ~ cmyb(%s, %s, %s, %s)", + my @color_template_data = ( '#' . $rgb->hex, $col->as_rgb8->rgb8, percentify($col->as_rgb->rgb), round($hsl->hue), percentify($hsl->saturation, $hsl->lightness, $col->as_cmyk->cmyk)); + + # Create the output! + my $text = sprintf("Hex: %s ~ rgb(%d, %d, %d) ~ rgb(%s, %s, %s) ~ hsl(%d, %s, %s) ~ cmyb(%s, %s, %s, %s)", @color_template_data); + my $html_text = sprintf("Hex: %s · rgb(%d, %d, %d) · rgb(%s, %s, %s)
hsl(%d, %s, %s) · cmyb(%s, %s, %s, %s) ·", + @color_template_data); return $text, html => '
' - . $text + . $html_text . " [Images] [ test_zci( 'Hex: #00ffff ~ rgb(0, 255, 255) ~ rgb(0%, 100%, 100%) ~ hsl(180, 100%, 50%) ~ cmyb(100%, 0%, 0%, 0%)', - html => qq(
Hex: #00ffff ~ rgb(0, 255, 255) ~ rgb(0%, 100%, 100%) ~ hsl(180, 100%, 50%) ~ cmyb(100%, 0%, 0%, 0%) [
Images] [Info]) + html => qq(
Hex: #00ffff · rgb(0, 255, 255) · rgb(0%, 100%, 100%)
hsl(180, 100%, 50%) · cmyb(100%, 0%, 0%, 0%) · [Images] [Info]) ), 'rgb(173,216,230)' => test_zci( 'Hex: #add8e6 ~ rgb(173, 216, 230) ~ rgb(68%, 85%, 90%) ~ hsl(195, 53%, 79%) ~ cmyb(25%, 6%, 0%, 10%)', - html => qq(
Hex: #add8e6 ~ rgb(173, 216, 230) ~ rgb(68%, 85%, 90%) ~ hsl(195, 53%, 79%) ~ cmyb(25%, 6%, 0%, 10%) [Images] [Info]) + html => qq(
Hex: #add8e6 · rgb(173, 216, 230) · rgb(68%, 85%, 90%)
hsl(195, 53%, 79%) · cmyb(25%, 6%, 0%, 10%) · [Images] [Info]) ), 'hsl 194 0.53 0.79' => test_zci( 'Hex: #add8e5 ~ rgb(173, 216, 229) ~ rgb(68%, 85%, 90%) ~ hsl(194, 53%, 79%) ~ cmyb(25%, 6%, 0%, 10%)', - html => qq(
Hex: #add8e5 ~ rgb(173, 216, 229) ~ rgb(68%, 85%, 90%) ~ hsl(194, 53%, 79%) ~ cmyb(25%, 6%, 0%, 10%) [Images] [Info]) + html => qq(
Hex: #add8e5 · rgb(173, 216, 229) · rgb(68%, 85%, 90%)
hsl(194, 53%, 79%) · cmyb(25%, 6%, 0%, 10%) · [Images] [Info]) ), 'cmyk(0.12, 0, 0, 0)' => test_zci( 'Hex: #e0ffff ~ rgb(224, 255, 255) ~ rgb(88%, 100%, 100%) ~ hsl(180, 100%, 94%) ~ cmyb(12%, 0%, 0%, 0%)', - html => qq(
Hex: #e0ffff ~ rgb(224, 255, 255) ~ rgb(88%, 100%, 100%) ~ hsl(180, 100%, 94%) ~ cmyb(12%, 0%, 0%, 0%) [Images] [Info]) + html => qq(
Hex: #e0ffff · rgb(224, 255, 255) · rgb(88%, 100%, 100%)
hsl(180, 100%, 94%) · cmyb(12%, 0%, 0%, 0%) · [Images] [Info]) ), '#00ff00' => test_zci( 'Hex: #00ff00 ~ rgb(0, 255, 0) ~ rgb(0%, 100%, 0%) ~ hsl(120, 100%, 50%) ~ cmyb(100%, 0%, 100%, 0%)', - html => qq(
Hex: #00ff00 ~ rgb(0, 255, 0) ~ rgb(0%, 100%, 0%) ~ hsl(120, 100%, 50%) ~ cmyb(100%, 0%, 100%, 0%) [Images] [Info]) + html => qq(
Hex: #00ff00 · rgb(0, 255, 0) · rgb(0%, 100%, 0%)
hsl(120, 100%, 50%) · cmyb(100%, 0%, 100%, 0%) · [Images] [Info]) ), '#0f0' => test_zci( 'Hex: #00ff00 ~ rgb(0, 255, 0) ~ rgb(0%, 100%, 0%) ~ hsl(120, 100%, 50%) ~ cmyb(100%, 0%, 100%, 0%)', - html => qq(
Hex: #00ff00 ~ rgb(0, 255, 0) ~ rgb(0%, 100%, 0%) ~ hsl(120, 100%, 50%) ~ cmyb(100%, 0%, 100%, 0%) [Images] [Info]) + html => qq(
Hex: #00ff00 · rgb(0, 255, 0) · rgb(0%, 100%, 0%)
hsl(120, 100%, 50%) · cmyb(100%, 0%, 100%, 0%) · [Images] [Info]) ), 'inverse of the color red' => test_zci( 'Hex: #00ffff ~ rgb(0, 255, 255) ~ rgb(0%, 100%, 100%) ~ hsl(180, 100%, 50%) ~ cmyb(100%, 0%, 0%, 0%)', - html => qq(
Hex: #00ffff ~ rgb(0, 255, 255) ~ rgb(0%, 100%, 100%) ~ hsl(180, 100%, 50%) ~ cmyb(100%, 0%, 0%, 0%) [Images] [Info]), + html => qq(
Hex: #00ffff · rgb(0, 255, 255) · rgb(0%, 100%, 100%)
hsl(180, 100%, 50%) · cmyb(100%, 0%, 0%, 0%) · [Images] [Info]), ), 'rgb(0 255 0)\'s inverse' => test_zci( 'Hex: #ff00ff ~ rgb(255, 0, 255) ~ rgb(100%, 0%, 100%) ~ hsl(300, 100%, 50%) ~ cmyb(0%, 100%, 0%, 0%)', - html => qq(
Hex: #ff00ff ~ rgb(255, 0, 255) ~ rgb(100%, 0%, 100%) ~ hsl(300, 100%, 50%) ~ cmyb(0%, 100%, 0%, 0%) [Images] [Info]), + html => qq(
Hex: #ff00ff · rgb(255, 0, 255) · rgb(100%, 0%, 100%)
hsl(300, 100%, 50%) · cmyb(0%, 100%, 0%, 0%) · [Images] [Info]), ), 'html bluishblack' => test_zci( 'Hex: #202428 ~ rgb(32, 36, 40) ~ rgb(13%, 14%, 16%) ~ hsl(210, 11%, 14%) ~ cmyb(20%, 10%, 0%, 84%)', - html => qq(
Hex: #202428 ~ rgb(32, 36, 40) ~ rgb(13%, 14%, 16%) ~ hsl(210, 11%, 14%) ~ cmyb(20%, 10%, 0%, 84%) [Images] [Info]), + html => qq(
Hex: #202428 · rgb(32, 36, 40) · rgb(13%, 14%, 16%)
hsl(210, 11%, 14%) · cmyb(20%, 10%, 0%, 84%) · [Images] [Info]), ), 'red html code' => test_zci( 'Hex: #ff0000 ~ rgb(255, 0, 0) ~ rgb(100%, 0%, 0%) ~ hsl(0, 100%, 50%) ~ cmyb(0%, 100%, 100%, 0%)', - html => qq(
Hex: #ff0000 ~ rgb(255, 0, 0) ~ rgb(100%, 0%, 0%) ~ hsl(0, 100%, 50%) ~ cmyb(0%, 100%, 100%, 0%) [Images] [Info]), + html => qq(
Hex: #ff0000 · rgb(255, 0, 0) · rgb(100%, 0%, 0%)
hsl(0, 100%, 50%) · cmyb(0%, 100%, 100%, 0%) · [Images] [Info]), ), 'bluishblack html' => undef, 'HTML email' => undef,