File Coverage

lib/Log/Report/Template/Textdomain.pm
Criterion Covered Total %
statement 59 76 77.6
branch 17 40 42.5
condition 7 20 35.0
subroutine 18 21 85.7
pod 8 10 80.0
total 109 167 65.2


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Log-Report-Template version 1.04.
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) 2017-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::Template::Textdomain;{
17             our $VERSION = '1.04';
18             }
19              
20 8     8   52 use base 'Log::Report::Domain';
  8         48  
  8         1019  
21              
22 8     8   50 use warnings;
  8         16  
  8         373  
23 8     8   42 use strict;
  8         33  
  8         282  
24              
25 8     8   44 use Log::Report 'log-report-template';
  8         15  
  8         84  
26              
27 8     8   2536 use Log::Report::Message ();
  8         21  
  8         297  
28              
29 8     8   45 use Scalar::Util qw/weaken/;
  8         16  
  8         13505  
30              
31             #--------------------
32              
33             sub init($)
34 7     7 0 84 { my ($self, $args) = @_;
35 7         52 $self->SUPER::init($args)->_initMe($args);
36             }
37              
38             sub _initMe($)
39 7     7   139 { my ($self, $args) = @_;
40              
41 7 100       42 if(my $only = $args->{only_in_directory})
42 2 50       13 { my @only = ref $only eq 'ARRAY' ? @$only : $only;
43 2         11 my $dirs = join '|', map "\Q$_\E", @only;
44 2         46 $self->{LRTT_only_in} = qr!^(?:$dirs)(?:$|/)!;
45             }
46              
47 7   100     40 $self->{LRTT_function} = $args->{translation_function} || 'loc';
48 7         19 $self->{LRTT_lexicon} = $args->{lexicon};
49 7         15 $self->{LRTT_lang} = $args->{lang};
50              
51 7 50       45 $self->{LRTT_templ} = $args->{templater} or panic "Requires templater";
52 7         15 weaken $self->{LRTT_templ};
53              
54 7         34 $self;
55             }
56              
57              
58              
59             sub upgrade($%)
60 1     1 1 16 { my ($class, $domain, %args) = @_;
61              
62 1 50       5 ref $domain eq 'Log::Report::Domain'
63             or error __x"extension to domain '{name}' already exists", name => $domain->name;
64              
65 0         0 (bless $domain, $class)->_initMe(\%args);
66             }
67              
68             #--------------------
69              
70 0     0 1 0 sub templater() { $_[0]->{LRTT_templ} }
71              
72              
73 14     14 1 871 sub function() { $_[0]->{LRTT_function} }
74              
75              
76 2     2 1 33 sub lexicon() { $_[0]->{LRTT_lexicon} }
77              
78              
79             sub expectedIn($)
80 3     3 1 8 { my ($self, $fn) = @_;
81 3 100       11 my $only = $self->{LRTT_only_in} or return 1;
82 2         14 $fn =~ $only;
83             }
84              
85              
86 4     4 1 214 sub lang() { $_[0]->{LRTT_lang} }
87              
88             #--------------------
89              
90             sub translateTo($)
91 0     0 1 0 { my ($self, $lang) = @_;
92 0         0 $self->{LRTT_lang} = $lang;
93             }
94              
95              
96              
97             sub translationFunction($)
98 6     6 1 49 { my ($self, $service) = @_;
99 6         28 my $context = $service->context;
100              
101             # Prepare as much and fast as possible, because it gets called often!
102             sub { # called with ($msgid, @positionals, [\%params])
103 4     4   55216 my $msgid = shift;
104 4 100 66     29 my $params = @_ && ref $_[-1] eq 'HASH' ? pop @_ : {};
105 4 50       41 my $plural = $msgid =~ s/\|(.*)// ? $1 : undef;
106 4 50 33     16 if(defined $plural && ! defined $params->{_count})
107 0 0       0 { @_ or error __x"no counting positional for '{msgid}'", msgid => $msgid;
108 0         0 $params->{_count} = shift;
109             }
110 4 50       10 @_ and error __x"superfluous positional parameters for '{msgid}'", msgid => $msgid;
111              
112             Log::Report::Message->new(
113             _msgid => $msgid, _plural => $plural, _domain => $self,
114 4         37 %$params, _stash => $context->{STASH}, _expand => 1,
115             )->toString($self->lang);
116 6         103 };
117             }
118              
119             # Larger HTML blocks are fragile in blanks. We remove all superfluous blanks from the
120             # msgid, which will break translation of
 blocks :-) 
121             sub _normalized_ws($) # Code shared with ::Extract
122 8 100   8   30 { defined $_[0] or return undef;
123 4         66 $_[0] =~ s/[ \t]+/ /gr # remove blank repetition
124             =~ s/^ //gmr # no blanks in the beginning of the line
125             =~ s/\A\n+//r # no leading blank lines
126             =~ s/\n+\z/\n/r; # no trailing blank lines;
127             }
128              
129             sub translationFilter()
130 6     6 0 41 { my $self = shift;
131              
132             # Prepare as much and fast as possible, because it gets called often!
133             # A TT filter can be either static or dynamic. Dynamic filters need to
134             # implement a "a factory for static filters": a sub which produces a
135             # sub which does the real work.
136             sub {
137 0     0   0 my $context = shift;
138 0 0 0     0 my $params = @_ && ref $_[-1] eq 'HASH' ? pop @_ : {};
139 0 0       0 $params->{_count} = shift if @_;
140 0 0       0 $params->{_error} = 'too many' if @_; # don't know msgid yet
141              
142             sub { # called with $msgid (template container content) only, the
143             # parameters are caught when the factory produces this sub.
144 0         0 my $msgid = shift;
145 0 0       0 my $plural = $msgid =~ s/\|(.*)// ? $1 : undef;
146             defined $plural || ! defined $params->{_count}
147 0 0 0     0 or error __x"message does not contain counting alternatives in '{msgid}'", msgid => $msgid;
148              
149             ! defined $plural || defined $params->{_count}
150 0 0 0     0 or error __x"no counting positional for '{msgid}'", msgid => $msgid;
151              
152             ! $params->{_error}
153 0 0       0 or error __x"superfluous positional parameters for '{msgid}'", msgid => $msgid;
154              
155             Log::Report::Message->new(_msgid => _normalized_ws($msgid), _plural => _normalized_ws($plural), _domain => $self,
156 0         0 %$params, _stash => $context->{STASH}, _expand => 1,
157             )->toString($self->lang);
158             }
159 6         43 };
  0         0  
160             }
161              
162             sub _reportMissingKey($$)
163 2     2   336 { my ($self, $sp, $key, $args) = @_;
164              
165             # Try to grab the value from the stash. That's a major advantange
166             # of TT over plain Perl: we have access to the variable namespace.
167              
168 2         7 my $stash = $args->{_stash};
169 2 50       11 if($stash)
170 2         19 { my $value = $stash->get($key);
171 2 100 66     49 return $value if defined $value && length $value;
172             }
173              
174             warning __x"Missing key '{key}' in format '{format}', in {use //template}",
175 1         9 key => $key, format => $args->{_format}, use => $stash->{template}{name};
176              
177 1         385 undef;
178             }
179              
180             1;