2014-11-27 23:02:08 -08:00
|
|
|
|
package DDG::Goodie::PeriodicTable;
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# ABSTRACT: Chemical symbols, atomic masses and numbers for chemical elements
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
2015-02-22 12:09:29 -08:00
|
|
|
|
use strict;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
use DDG::Goodie;
|
2015-05-29 15:18:03 -07:00
|
|
|
|
use YAML::XS 'LoadFile';
|
2015-01-03 20:59:13 -08:00
|
|
|
|
use List::Util qw(first);
|
2015-03-15 17:33:39 -07:00
|
|
|
|
use Text::Trim;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
zci answer_type => 'periodic_table';
|
|
|
|
|
zci is_cached => 1;
|
|
|
|
|
|
2016-02-23 08:20:37 -08:00
|
|
|
|
my @elements = @{ LoadFile(share('elements.yml')) };
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
# Triggers
|
2015-04-23 06:59:01 -07:00
|
|
|
|
my @element_triggers = [map { lc($_->[2]) } @elements];
|
|
|
|
|
triggers start => $element_triggers[0];
|
2015-12-27 21:13:24 -08:00
|
|
|
|
triggers any => 'atomic mass', 'atomic weight', 'atomic number', 'proton number', 'chemical symbol', 'chemical name';
|
2015-04-23 06:59:01 -07:00
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
# Handle statement
|
|
|
|
|
handle query_lc => sub {
|
|
|
|
|
|
|
|
|
|
my $query = $_;
|
|
|
|
|
|
2015-12-27 21:13:24 -08:00
|
|
|
|
# Determine if this is a query for atomic mass or chemical name
|
2014-11-27 23:02:08 -08:00
|
|
|
|
my $is_mass_query = $query =~ /atomic mass|atomic weight/;
|
2016-01-14 22:50:05 -08:00
|
|
|
|
my $is_number_query = $query =~ /atomic number|proton number/;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
# Strip out irrelevant words in the query
|
2015-04-24 02:45:45 -07:00
|
|
|
|
$query =~ s/(?:atomic (?:mass|weight|number)|proton number|of|the|for|element|elemental|chemical symbol|what is|chemical name)//g;
|
2015-03-15 17:33:39 -07:00
|
|
|
|
$query = trim $query;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
return unless $query;
|
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# Look for a matching element or symbol in the table
|
2015-01-03 20:59:13 -08:00
|
|
|
|
my $match = first { lc $_->[2] eq $query || lc $_->[3] eq $query } @elements or return;
|
2015-04-23 06:59:01 -07:00
|
|
|
|
my ( $atomic_number, $atomic_mass, $element_name, $element_symbol, $element_type ) = @{$match};
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
2015-12-27 21:13:24 -08:00
|
|
|
|
# Default display
|
2016-01-14 22:50:05 -08:00
|
|
|
|
my $title = "$element_name";
|
2015-12-27 21:13:24 -08:00
|
|
|
|
my $raw = "$element_name ($element_symbol), atomic number $atomic_number, atomic mass $atomic_mass u";
|
2015-04-23 06:59:01 -07:00
|
|
|
|
|
2015-04-30 03:17:03 -07:00
|
|
|
|
# The text size of the icon needs to change depending on the length of the chemical symbol.
|
|
|
|
|
my $badge_class = "";
|
|
|
|
|
my $symbol_length = length($element_symbol);
|
|
|
|
|
if ($symbol_length == 1) { $badge_class = "tx--25" }
|
|
|
|
|
elsif ($symbol_length == 3) { $badge_class = "tx--14" }
|
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
return $raw,
|
|
|
|
|
structured_answer => {
|
|
|
|
|
data => {
|
|
|
|
|
badge => $element_symbol,
|
|
|
|
|
title => $title,
|
2016-01-14 22:50:05 -08:00
|
|
|
|
subtitle => 'Chemical Element',
|
|
|
|
|
atomic_number => $atomic_number,
|
|
|
|
|
atomic_mass => $atomic_mass,
|
|
|
|
|
element_type => $element_type,
|
|
|
|
|
is_mass_query => $is_mass_query,
|
|
|
|
|
is_number_query => $is_number_query,
|
2015-05-15 04:27:37 -07:00
|
|
|
|
url => "https://en.wikipedia.org/wiki/$element_name",
|
2015-04-23 06:59:01 -07:00
|
|
|
|
},
|
2015-04-24 02:45:45 -07:00
|
|
|
|
meta => {
|
|
|
|
|
sourceName => "Wikipedia",
|
|
|
|
|
sourceUrl => "https://en.wikipedia.org/wiki/$element_name"
|
|
|
|
|
},
|
2015-04-23 06:59:01 -07:00
|
|
|
|
templates => {
|
|
|
|
|
group => "icon",
|
|
|
|
|
elClass => {
|
|
|
|
|
bgColor => get_badge_color($element_type),
|
2015-04-30 03:17:03 -07:00
|
|
|
|
iconBadge => "tx-clr-white $badge_class",
|
|
|
|
|
iconTitle => "tx--19",
|
|
|
|
|
tileSubtitle => "tx--14"
|
2015-04-23 06:59:01 -07:00
|
|
|
|
},
|
|
|
|
|
variants => {
|
|
|
|
|
iconBadge => "medium"
|
2015-04-24 02:45:45 -07:00
|
|
|
|
},
|
2015-04-23 06:59:01 -07:00
|
|
|
|
options => {
|
2016-01-14 22:50:05 -08:00
|
|
|
|
content => 'DDH.periodic_table.content',
|
2015-04-24 02:45:45 -07:00
|
|
|
|
moreAt => 1
|
2015-04-23 06:59:01 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
};
|
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# Decide on a color to use when displaying the element badge based on its group.
|
|
|
|
|
sub get_badge_color {
|
|
|
|
|
my ($element_type) = @_;
|
|
|
|
|
|
|
|
|
|
# metmetal–metalloid–nonmetal etc is currently split into only 5 color groups.
|
|
|
|
|
# https://github.com/duckduckgo/zeroclickinfo-goodies/issues/927
|
|
|
|
|
my $badge_color = "bg-clr--red";
|
|
|
|
|
if ($element_type eq "Alkali metal") { $badge_color = "bg-clr--gold" }
|
|
|
|
|
elsif ($element_type eq "Alkaline earth metal") { $badge_color = "bg-clr--gold" }
|
|
|
|
|
elsif ($element_type eq "Lanthanide") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Actinide") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Transition metal") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Post-transition metal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Metalloid") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Polyatomic nonmetal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Diatomic nonmetal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Noble gas") { $badge_color = "bg-clr--blue-light" }
|
|
|
|
|
elsif ($element_type eq "Unknown") { $badge_color = "bg-clr--red" }
|
|
|
|
|
|
|
|
|
|
return $badge_color;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
1;
|