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