File Coverage

blib/lib/Log/Report/Translator/Context.pm
Criterion Covered Total %
statement 78 88 88.6
branch 16 28 57.1
condition 14 23 60.8
subroutine 12 12 100.0
pod 5 6 83.3
total 125 157 79.6


line stmt bran cond sub pod time code
1             # Copyrights 2007-2018 by [Mark Overmeer ].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5             # This code is part of distribution Log-Report-Lexicon. Meta-POD processed
6             # with OODoc into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package Log::Report::Translator::Context;
10 2     2   154386 use vars '$VERSION';
  2         9  
  2         142  
11             $VERSION = '1.11';
12              
13              
14 2     2   13 use warnings;
  2         5  
  2         58  
15 2     2   11 use strict;
  2         4  
  2         45  
16              
17 2     2   11 use Log::Report 'log-report-lexicon';
  2         3  
  2         36  
18              
19              
20 1     1 1 84 sub new(@) { my $class = shift; (bless {}, $class)->init({@_}) }
  1         5  
21             sub init($)
22 1     1 0 2 { my ($self, $args) = @_;
23 1   50     5 $self->{LRTC_rules} = $self->_context_table($args->{rules} || {});
24 1         9 $self;
25             }
26              
27             #-------
28              
29 14     14 1 20 sub rules() {shift->{LRTC_rules}}
30              
31             #-------
32              
33             sub _strip_ctxt_spec($)
34 14     14   22 { my $msgid = shift;
35 14         14 my @tags;
36 14         72 while($msgid =~ s/\{ ([^<}]*) \<(\w+) ([^}]*) \}/
37 16 100       76 length "$1$3" ? "{$1$3}" : ''/xe)
38 16         52 { push @tags, $2;
39             }
40 14         50 ($msgid, [sort @tags]);
41             }
42              
43             sub ctxtFor($$;$)
44 8     8 1 255 { my ($self, $msg, $lang, $def_context) = @_;
45 8         14 my $rawid = $msg->msgid;
46 8         53 my ($msgid, $tags) = _strip_ctxt_spec $rawid;
47 8 50       18 @$tags or return ($msgid, undef);
48              
49 8         15 my $maps = $self->rules;
50 8         10 $lang =~ s/_.*//;
51              
52 8   50     19 my $msg_context = $self->needDecode($rawid, $msg->context || {});
53 8   50     16 $def_context ||= {};
54             #use Data::Dumper;
55             #warn "context = ", Dumper $msg, $msg_context, $def_context;
56              
57 8         9 my @c;
58 8         9 foreach my $tag (@$tags)
59 9 50       17 { my $map = $maps->{$tag}
60             or error __x"no context definition for `{tag}' in `{msgid}'"
61             , tag => $tag, msgid => $rawid;
62              
63 9   66     23 my $set = $map->{$lang} || $map->{default};
64 9 50       20 next if $set eq 'IGNORE';
65              
66 9   33     21 my $v = $msg_context->{$tag} || $def_context->{$tag};
67 9 50       13 unless($v)
68 0         0 { warning __x"no value for tag `{tag}' in the context", tag => $tag;
69 0         0 ($v) = keys %$set;
70             }
71 9 50       15 unless($set->{$v})
72 0         0 { warning __x"unknown alternative `{alt}' for tag `{tag}' in context of `{msgid}'"
73             , alt => $v, tag => $tag, msgid => $rawid;
74 0         0 ($v) = keys %$set;
75             }
76              
77 9         22 push @c, "$tag=$set->{$v}";
78             }
79              
80 8         18 my $msgctxt = join ' ', sort @c;
81 8         49 ($msgid, $msgctxt);
82             }
83              
84              
85             sub needDecode($@)
86 8     8 1 45 { my ($thing, $source) = (shift, shift);
87 8 50       15 return +{@_} if @_ > 1;
88 8         9 my $c = shift;
89 8 50 33     38 return $c if !defined $c || ref $c eq 'HASH';
90              
91 0         0 my %c;
92 0 0       0 foreach (ref $c eq 'ARRAY' ? @$c : (split /[\s,]+/, $c))
93 0         0 { my ($kw, $val) = split /\=/, $_, 2;
94 0 0       0 defined $val
95             or error __x"tags value must have form `a=b', found `{this}' in `{source}'"
96             , this => $_, source => $source;
97 0         0 $c{$kw} = $val;
98             }
99 0         0 \%c;
100             }
101              
102              
103             sub expand($$@)
104 6     6 1 20 { my ($self, $raw, $lang) = @_;
105 6         15 my ($msgid, $tags) = _strip_ctxt_spec $raw;
106              
107 6         11 $lang =~ s/_.*//;
108              
109 6         11 my $maps = $self->rules;
110 6         9 my @options = [];
111              
112 6         11 foreach my $tag (@$tags)
113 7 50       16 { my $map = $maps->{$tag}
114             or error __x"unknown context tag '{tag}' used in '{msgid}'"
115             , tag => $tag, msgid => $msgid;
116 7   66     19 my $set = $map->{$lang} || $map->{default};
117              
118 7         40 my %uniq = map +("$tag=$_" => 1), values %$set;
119 7         11 my @oldopt = @options;
120 7         9 @options = ();
121              
122 7         13 foreach my $alt (keys %uniq)
123 17         42 { push @options, map +[ @$_, $alt ], @oldopt;
124             }
125             }
126              
127 6         72 ($msgid, [sort map join(' ', @$_), @options]);
128             }
129              
130             sub _context_table($)
131 1     1   3 { my ($self, $rules) = @_;
132 1         1 my %rules;
133 1         4 foreach my $tag (keys %$rules)
134 4         6 { my $d = $rules->{$tag};
135 4 100       10 $d = +{ alternatives => $d } if ref $d eq 'ARRAY';
136 4         3 my %simple;
137 4   100     10 my $default = $d->{default} || {}; # default map
138 4 100       8 if(my $alt = $d->{alternatives}) # simpelest map
139 3         10 { $default = +{ map +($_ => $_), @$alt };
140             }
141 4         7 $simple{default} = $default;
142 4         7 foreach my $set (keys %$d)
143 5 100 100     16 { next if $set eq 'default' || $set eq 'alternatives';
144 1         3 my %set = (%$default, %{$d->{$set}});
  1         3  
145 1         6 $simple{$_} = \%set for split /\,/, $set; # table per lang
146             }
147 4         9 $rules{$tag} = \%simple;
148             }
149              
150 1         4 \%rules;
151             }
152              
153             #------------
154              
155             1;