lib/MGH_Biostat/TravEpi/SimpleRulesBase/Translator.pm
package MGH_Biostat::TravEpi::SimpleRulesBase::Translator;
use Modern::Perl '2012';
use experimental 'switch';
use Carp;
use Set::Tiny qw(set);
use Unicode::Collate::Locale;
use MGH_Biostat::Locale::POCatalog;
use MGH_Biostat::Locale::Locale;
use MGH_Biostat::TravEpi::SimpleRulesBase::HTMLParser;
use MGH_Biostat::TravEpi::SimpleRulesBase::Countries;
sub new {
my $class = shift;
my $params = {@_};
my @catalog_params = ();
if ( exists( $params->{'dir'} ) ) { @catalog_params = ( 'dir' => $params->{'dir'} ); }
my $self = bless {
'catalog' => MGH_Biostat::Locale::POCatalog->new(@catalog_params),
'locales' => {},
'country_sort_cache' => {},
}, $class;
foreach my $lang ( $self->{'catalog'}->langs->members() ) {
$self->{'locales'}{$lang} = MGH_Biostat::Locale::Locale->new($lang);
$self->{'country_sort_cache'}{$lang} = {};
my $collator = Unicode::Collate::Locale->new( locale => $lang );
foreach my $country ( MGH_Biostat::TravEpi::SimpleRulesBase::Countries::valid_countries->elements ) {
$self->{'country_sort_cache'}{$lang}{$country} =
$collator->getSortKey( $self->{'catalog'}->lookup( $lang, $country, 'Menu' )->msgstr );
}
}
return $self;
}
# return a locale for a language
sub get_locale {
my $self = shift;
my ($lang) = @_;
return $self->{'locales'}{$lang};
}
# get a list of valid languages
sub valid_languages {
my $self = shift;
return $self->{'catalog'}->langs;
}
# test to see if a language is valid
sub is_valid_language {
my $self = shift;
my ($lang) = @_;
return $self->valid_languages()->member($lang);
}
# get the default language
sub default_language {
my $self = shift;
return $self->{'catalog'}->default_lang;
}
# get an ordered list of the valid languages
sub ordered_languages {
my $self = shift;
return $self->{'catalog'}->langs_order;
}
# get back the "in <language>" form for a given language
sub get_inlanguage {
my $self = shift;
my ($lang) = @_;
return $self->{'catalog'}->lookup( $lang, 'in language' )->msgstr;
}
# take the 'base' template and return a version specialized to a specific language
sub translate_template {
my $self = shift;
my ( $lang, $template ) = @_;
my ( $langlong, $langshort ) = ( $lang =~ m/(([^-]+)(?:-.+)?)/ );
my $replaces = {
'langshort' => $langshort,
'langlong' => $langlong,
'langdir' => 'ltr',
'countries' => $self->countries_menu($lang),
};
if ( $self->{'locales'}{$lang}->get_character_orientation_from_code() eq 'right-to-left' ) {
$replaces->{'langdir'} = 'rtl';
}
foreach my $replace ( keys %$replaces ) {
$template =~ s/!!\$$replace/$replaces->{$replace}/g;
}
$template = MGH_Biostat::TravEpi::SimpleRulesBase::HTMLParser::translate_template( $template, $self->{'catalog'}, $lang );
return $template;
}
sub countries_menu {
my $self = shift;
my ($lang) = @_;
if ( !$self->is_valid_language($lang) ) {
carp("Countries menu requested for unknown language ('$lang'). Using default language.\n");
return $self->countries_menu( $self->default_language() );
}
my $ret = '';
my $c = $self->{'country_sort_cache'}{$lang};
foreach my $k ( sort { $c->{$a} cmp $c->{$b} } keys %$c ) {
$ret .= '<option value="' . $k . '">' . $self->{'catalog'}->lookup( $lang, $k, 'Menu' )->msgstr . '</option>';
}
return $ret;
}
sub translate_dynamic_text {
my $self = shift;
my ( $dt, $lang ) = @_;
my $locale = $self->{'locales'}{$lang};
given ( $dt->{'type'} ) {
when ('age') {
return $self->{'catalog'}->lookup( $lang, '%s year old' )->msgstr_n_apply( $dt->{'value'} );
}
when ('countries') {
my $context = $dt->{'context'};
my $po_context = $context->{'po-context'} // 'List';
my $template = $context->{'template'} // '[%val%]';
my $csc = $self->{'country_sort_cache'}{$lang};
my @countries =
map { $template =~ s/\[%(\w+)%\]/$_->{$1}/ger; }
map { { 'key' => $_, 'val' => $self->{'catalog'}->lookup( $lang, $_, $po_context )->msgstr } }
sort { $csc->{$a} cmp $csc->{$b} }
$dt->{'value'}->members();
return $locale->get_list_and(@countries);
}
when ('destlinks') {
my $context = $dt->{'context'};
my $po_context = $context->{'po-context'} // 'List';
my $hash = $context->{'hash'} // 'unknown';
my $csc = $self->{'country_sort_cache'}{$lang};
return [
map { { 'dest_link' => "cdc-redirect/$_?$hash", 'dest_link_name' => $self->{'catalog'}->lookup( $lang, $_, $po_context )->msgstr } }
sort { $csc->{$a} cmp $csc->{$b} }
$dt->{'value'}->members()
];
}
}
carp "Unknown dynamic text type $dt->{'type'}";
return 'not yet implemented';
}
1;