Skip to content
This repository has been archived by the owner on Oct 15, 2022. It is now read-only.

Commit

Permalink
Roman numerals (#4413)
Browse files Browse the repository at this point in the history
* First shot at improving roman numeral IA.

Added a new converter.
Added new default settings.
Added some tests.

* Added un upper bound on arabic numbers.

* Remove some typo…

* Added some new triggers.
Allowed uncorrect roman number to load the UI anyway.
Fixed a test.

* Added new triggers.
Fixed regular expressions involved in the UI configuration.
Added new tests.

* Renamed file.

* Variables defined outside the handle function.

* Modified template.

* Init logic now runs only once.

* Added a prefix to ensure there are no collisions.

* Fixed tests.

* Added more agressive validation on user inputs.

* Fixed a test case for aggressive validation.  The ia doesn't trigger is
the input is invalid with respect to roman numeral system.

* Removed forEach operation (replaced with a for loop).

Removed firstLetterUpperCase in favor of DDG util capitalize.

* Fixed design on narrow screens.

* Added a new test (roman man => undef).

* Fixed regular expressions to avoid displaying if roman or arabic is used
without numbers.

* Added warnings when inputs are out of range.

* Added a state variable for warnings.

* Empty if removed.

* Fixed regexps.

* Fixed subtitle.

* Css fixed. Both for mobile and desktop.

* Fixed tests.

* Use horizontal layout on desktop, vertical on mobile
  • Loading branch information
gargaml authored and moollaza committed Sep 19, 2017
1 parent 2287be9 commit 549ee53
Show file tree
Hide file tree
Showing 5 changed files with 480 additions and 33 deletions.
77 changes: 61 additions & 16 deletions lib/DDG/Goodie/Roman.pm
Expand Up @@ -5,35 +5,80 @@ use strict;
use DDG::Goodie;

use Roman;
use List::Util qw/any/;
use utf8;

triggers any => "roman", "arabic";
triggers startend => "roman", "roman numeral", "roman numerals", "roman number",
"arabic", "arabic numeral", "arabic numerals", "arabic number";

zci is_cached => 1;
zci answer_type => "roman_numeral_conversion";

handle remainder => sub {
my $in = uc shift;
$in =~ s/(?:\s*|in|to|numerals?|number)//gi;
# These two lists are used to load the converter without any answer.
my @roman_to_arabic = (
qr/^convert\s+(?:into|to)\s+arabic\s*(numerals?)?$/i
);
my @arabic_to_roman = (
qr/^convert\s+(?:into|to)\s+roman\s*(numerals?)?$/i
);

# These two lists are used to load the converter with an answer.
my @roman_number_to_arabic = (
qr/^convert\s+(\D+)\s+(?:into|in|to)\s*arabic\s*(numerals?)?$/i,
qr/^roman\s+(?:numerals?)?\s*(\D+)$/i,
qr/^arabic\s+(?:numerals?)?\s*(\D+)$/i,
qr/^([ivxlcdm]+)\s+(?:into|in|to)?\s+arabic\s*(numerals?)?$/i
);
my @arabic_number_to_roman = (
qr/^convert\s+(\d+)\s+(?:into|in|to)\s*roman\s*(numerals?)?$/i,
qr/^roman\s+(?:numerals?)?\s*(\d+)$/i,
qr/^arabic\s+(?:numerals?)?\s*(\d+)$/i,
qr/^(\d+)\s+(?:into|in|to)?\s+roman\s*(numerals?)?$/i
);

return unless $in;
handle query => sub {
my ($query) = @_;

my $out;
if ($in =~ /^\d+$/) {
$out = uc(roman($in));
} elsif ($in =~ /^[mdclxvi]+$/i) {
$in = uc($in);
$out = arabic($in);
# By default, we convert from roman to arabic.
my $input = 'roman';
my $input_value = '';
my $output = 'arabic';
my $output_value = '';

if (any { $query =~ $_ } @arabic_to_roman) {
$input = 'arabic';
$output = 'roman';
} elsif (any { ($input_value) = $query =~ $_ } @roman_number_to_arabic) {
if (isroman $input_value) {
$input_value = uc $input_value;
$output_value = arabic $input_value;
} else {
# Malformed input (not a roman number), we don't trigger the ia.
return;
}
} elsif (any { ($input_value) = $query =~ $_ } @arabic_number_to_roman) {
$input = 'arabic';
$output = 'roman';
$input_value = $input_value;
$output_value = Roman $input_value;
} else {
$input_value = ''; # because of previous assignments with undef.
return unless any { $query =~ $_ } @roman_to_arabic;
}
return unless $out;

return $out . ' (roman numeral conversion)', structured_answer => {
return 'roman numeral converter', structured_answer => {
data => {
title => $out,
subtitle => "Roman numeral conversion: $in"
subtitle => 'Accepts inputs from 1 - 3999, I - MMMCMXCIX',
input => $input,
input_value => $input_value,
output => $output,
output_value => $output_value
},
templates => {
group => 'text'
group => 'text',
options => {
title_content => 'DDH.roman.content',
}
}
};
};
Expand Down
10 changes: 10 additions & 0 deletions share/goodie/roman/content.handlebars
@@ -0,0 +1,10 @@
<form class="converter">
<div class="converter__input">
<label class="converter__input__label">Roman</label>
<input type="text" class="converter__input__field" />
</div>
<div class="converter__output">
<label class="converter__output__label">Arabic</label>
<input type="text" class="converter__output__field" />
</div>
</form>
43 changes: 43 additions & 0 deletions share/goodie/roman/roman.css
@@ -0,0 +1,43 @@
.zci--roman .converter {
width: 100%;
}

.zci--roman .converter__input,
.zci--roman .converter__output {
display: inline-block;
margin-bottom: 1em;
width: 45%;
}

.zci--roman .converter__input {
margin-right: 1em;
}

.zci--roman .converter__input__label,
.zci--roman .converter__output__label {
display: block;
text-align: left;
font-size: 1.5em;
}

.zci--roman .converter__input__field,
.zci--roman .converter__output__field {
width: 100%;
text-align: center;
font-size: 2em;
}

.is-mobile .zci--roman .converter__input,
.is-mobile .zci--roman .converter__output {
display: block;
width: 100%;
}

/* Mobile UI */
.is-mobile .zci--roman .converter__input {
margin-right: 0em;
}

.is-mobile .zci--roman .converter__output {
margin-top: 1em;
}

0 comments on commit 549ee53

Please sign in to comment.