File Coverage

blib/lib/Log/Report/Translator/Context.pm
Criterion Covered Total %
statement 75 85 88.2
branch 16 28 57.1
condition 14 23 60.8
subroutine 11 11 100.0
pod 5 6 83.3
total 121 153 79.0


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Log-Report-Lexicon version 1.15.
2             # The POD got stripped from this file by OODoc version 3.05.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2007-2025 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11             #oodist: *** DO NOT USE THIS VERSION FOR PRODUCTION ***
12             #oodist: This file contains OODoc-style documentation which will get stripped
13             #oodist: during its release in the distribution. You can use this file for
14             #oodist: testing, however the code of this development version may be broken!
15              
16             package Log::Report::Translator::Context;{
17             our $VERSION = '1.15';
18             }
19              
20              
21 2     2   202515 use warnings;
  2         5  
  2         107  
22 2     2   9 use strict;
  2         3  
  2         40  
23              
24 2     2   5 use Log::Report 'log-report-lexicon';
  2         4  
  2         10  
25              
26             #--------------------
27              
28 1     1 1 198526 sub new(@) { my $class = shift; (bless {}, $class)->init({@_}) }
  1         7  
29             sub init($)
30 1     1 0 4 { my ($self, $args) = @_;
31 1   50     7 $self->{LRTC_rules} = $self->_context_table($args->{rules} || {});
32 1         3 $self;
33             }
34              
35             #--------------------
36              
37 14     14 1 29 sub rules() { $_[0]->{LRTC_rules} }
38              
39             #--------------------
40              
41              
42             sub _strip_ctxt_spec($)
43 14     14   26 { my $msgid = shift;
44 14         20 my @tags;
45 14 100       119 while($msgid =~ s/\{ ([^<}]*) \<(\w+) ([^}]*) \}/ length "$1$3" ? "{$1$3}" : ''/xe)
  16         120  
46 16         62 { push @tags, $2;
47             }
48 14         69 ($msgid, [sort @tags]);
49             }
50              
51             sub ctxtFor($$;$)
52 8     8 1 454 { my ($self, $msg, $lang, $def_context) = @_;
53 8         26 my $rawid = $msg->msgid;
54 8         71 my ($msgid, $tags) = _strip_ctxt_spec $rawid;
55 8 50       20 @$tags or return ($msgid, undef);
56              
57 8         19 my $maps = $self->rules;
58 8         16 $lang =~ s/_.*//;
59              
60 8   50     21 my $msg_context = $self->needDecode($rawid, $msg->context || {});
61 8   50     27 $def_context ||= {};
62             #use Data::Dumper;
63             #warn "context = ", Dumper $msg, $msg_context, $def_context;
64              
65 8         11 my @c;
66 8         18 foreach my $tag (@$tags)
67 9 50       42 { my $map = $maps->{$tag}
68             or error __x"no context definition for `{tag}' in `{msgid}'", tag => $tag, msgid => $rawid;
69              
70 9   66     32 my $set = $map->{$lang} || $map->{default};
71 9 50       24 next if $set eq 'IGNORE';
72              
73 9   33     30 my $v = $msg_context->{$tag} || $def_context->{$tag};
74 9 50       19 unless($v)
75 0         0 { warning __x"no value for tag `{tag}' in the context", tag => $tag;
76 0         0 ($v) = keys %$set;
77             }
78 9 50       20 unless($set->{$v})
79 0         0 { warning __x"unknown alternative `{alt}' for tag `{tag}' in context of `{msgid}'", alt => $v, tag => $tag, msgid => $rawid;
80 0         0 ($v) = keys %$set;
81             }
82              
83 9         31 push @c, "$tag=$set->{$v}";
84             }
85              
86 8         26 my $msgctxt = join ' ', sort @c;
87 8         69 ($msgid, $msgctxt);
88             }
89              
90              
91              
92             sub needDecode($@)
93 8     8 1 58 { my ($thing, $source) = (shift, shift);
94 8 50       18 return +{@_} if @_ > 1;
95 8         83 my $c = shift;
96 8 50 33     311 return $c if !defined $c || ref $c eq 'HASH';
97              
98 0         0 my %c;
99 0 0       0 foreach (ref $c eq 'ARRAY' ? @$c : (split /[\s,]+/, $c))
100 0         0 { my ($kw, $val) = split /\=/, $_, 2;
101 0 0       0 defined $val
102             or error __x"tags value must have form `a=b', found `{this}' in `{source}'", this => $_, source => $source;
103 0         0 $c{$kw} = $val;
104             }
105 0         0 \%c;
106             }
107              
108              
109             sub expand($$@)
110 6     6 1 21 { my ($self, $raw, $lang) = @_;
111 6         33 my ($msgid, $tags) = _strip_ctxt_spec $raw;
112              
113 6         13 $lang =~ s/_.*//;
114              
115 6         42 my $maps = $self->rules;
116 6         13 my @options = [];
117              
118 6         34 foreach my $tag (@$tags)
119 7 50       23 { my $map = $maps->{$tag}
120             or error __x"unknown context tag '{tag}' used in '{msgid}'", tag => $tag, msgid => $msgid;
121 7   66     25 my $set = $map->{$lang} || $map->{default};
122              
123 7         51 my %uniq = map +("$tag=$_" => 1), values %$set;
124 7         18 my @oldopt = @options;
125 7         10 @options = ();
126              
127 7         15 foreach my $alt (keys %uniq)
128 17         58 { push @options, map +[ @$_, $alt ], @oldopt;
129             }
130             }
131              
132 6         84 ($msgid, [sort map join(' ', @$_), @options]);
133             }
134              
135             sub _context_table($)
136 1     1   3 { my ($self, $rules) = @_;
137 1         1 my %rules;
138 1         5 foreach my $tag (keys %$rules)
139 4         5 { my $d = $rules->{$tag};
140 4 100       12 $d = +{ alternatives => $d } if ref $d eq 'ARRAY';
141              
142 4         7 my %simple;
143 4   100     14 my $default = $d->{default} || {}; # default map
144 4 100       9 if(my $alt = $d->{alternatives}) # simpelest map
145 3         14 { $default = +{ map +($_ => $_), @$alt };
146             }
147              
148 4         8 $simple{default} = $default;
149 4         7 foreach my $set (keys %$d)
150 5 100 100     18 { next if $set eq 'default' || $set eq 'alternatives';
151 1         3 my %set = (%$default, %{$d->{$set}});
  1         4  
152 1         6 $simple{$_} = \%set for split /\,/, $set; # table per lang
153             }
154 4         11 $rules{$tag} = \%simple;
155             }
156              
157 1         6 \%rules;
158             }
159              
160             #--------------------
161              
162             1;