1# Locale::Po4a::Common -- Common parts of the po4a scripts and utils
2#
3# Copyright © 2005 Jordi Vilalta <jvprat@gmail.com>
4#
5# This program is free software; you may redistribute it and/or modify it
6# under the terms of GPL (see COPYING).
7#
8# This module has common utilities for the various scripts of po4a
9
10=encoding UTF-8
11
12=head1 NAME
13
14Locale::Po4a::Common - common parts of the po4a scripts and utils
15
16=head1 DESCRIPTION
17
18Locale::Po4a::Common contains common parts of the po4a scripts and some useful
19functions used along the other modules.
20
21If needed, you can disable the use of Text::WrapI18N as such:
22
23    use Locale::Po4a::Common qw(nowrapi18n);
24    use Locale::Po4a::Text;
25
26instead of:
27
28    use Locale::Po4a::Text;
29
30The ordering is important here: as most Locale::Po4a modules load themselves
31Locale::Po4a::Common, the first time this module is loaded determines whether Text::WrapI18N is used.
32
33=cut
34
35package Locale::Po4a::Common;
36
37require Exporter;
38use vars qw(@ISA @EXPORT);
39@ISA    = qw(Exporter);
40@EXPORT = qw(wrap_msg wrap_mod wrap_ref_mod textdomain gettext dgettext);
41
42use 5.006;
43use strict;
44use warnings;
45
46sub import {
47    my $class = shift;
48
49    my $wrapi18n = 1;
50    if ( exists $_[0] && defined $_[0] && $_[0] eq 'nowrapi18n' ) {
51        shift;
52        $wrapi18n = 0;
53    }
54    $class->export_to_level( 1, $class, @_ );
55
56    return if defined &wrapi18n;
57
58    if ( $wrapi18n && -t STDERR && -t STDOUT && eval { require Text::WrapI18N } ) {
59
60        # Don't bother determining the wrap column if we cannot wrap.
61        my $col = $ENV{COLUMNS};
62        if ( !defined $col ) {
63            my @term = eval "use Term::ReadKey; Term::ReadKey::GetTerminalSize()";
64            $col = $term[0] if ( !$@ );
65
66            # If GetTerminalSize() failed we will fallback to a safe default.
67            # This can happen if Term::ReadKey is not available
68            # or this is a terminal-less build or such strange condition.
69        }
70        $col=76 if (!defined $col || $col <= 0);
71
72        eval ' use Text::WrapI18N qw($columns);
73               $columns = $col;
74             ';
75
76        eval ' sub wrapi18n($$$) { Text::WrapI18N::wrap($_[0],$_[1],$_[2]) } ';
77    } else {
78
79        # If we cannot wrap, well, that's too bad. Survive anyway.
80        eval ' sub wrapi18n($$$) { $_[0].$_[2] } ';
81    }
82}
83
84sub min($$) {
85    return $_[0] < $_[1] ? $_[0] : $_[1];
86}
87
88=head1 FUNCTIONS
89
90=head2 Showing output messages
91
92=over
93
94=item
95
96show_version($)
97
98Shows the current version of the script, and a short copyright message. It
99takes the name of the script as an argument.
100
101=cut
102
103sub show_version {
104    my $name = shift;
105
106    print sprintf(
107        gettext(
108                "%s version %s.\n"
109              . "Written by Martin Quinson and Denis Barbier.\n\n"
110              . "Copyright © 2002-2021 Software in the Public Interest, Inc.\n"
111              . "This is free software; see source code for copying\n"
112              . "conditions. There is NO warranty; not even for\n"
113              . "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
114        ),
115        $name,
116        $Locale::Po4a::TransTractor::VERSION
117    ) . "\n";
118}
119
120=item
121
122wrap_msg($@)
123
124This function displays a message the same way as sprintf() does, but wraps
125the result so that they look nice on the terminal.
126
127=cut
128
129sub wrap_msg($@) {
130    my $msg  = shift;
131    my @args = @_;
132
133    #    print "'$msg' ; ".(scalar @args)." $args[0] $args[1]\n";
134    return wrapi18n( "", "", sprintf( $msg, @args ) ) . "\n";
135}
136
137=item
138
139wrap_mod($$@)
140
141This function works like wrap_msg(), but it takes a module name as the first
142argument, and leaves a space at the left of the message.
143
144=cut
145
146sub wrap_mod($$@) {
147    my ( $mod, $msg ) = ( shift, shift );
148    my @args = @_;
149
150    $mod .= ": ";
151    my $spaces = " " x min( length($mod), 15 );
152    return wrapi18n( $mod, $spaces, sprintf( $msg, @args ) ) . "\n";
153}
154
155=item
156
157wrap_ref_mod($$$@)
158
159This function works like wrap_msg(), but it takes a file:line reference as the
160first argument, a module name as the second one, and leaves a space at the left
161of the message.
162
163=back
164
165=cut
166
167sub wrap_ref_mod($$$@) {
168    my ( $ref, $mod, $msg ) = ( shift, shift, shift );
169    my @args = @_;
170
171    if ( !$mod ) {
172
173        # If we don't get a module name, show the message like wrap_mod does
174        return wrap_mod( $ref, $msg, @args );
175    } else {
176        $ref .= ": ";
177        my $spaces = " " x min( length($ref), 15 );
178        $msg = "$ref($mod)\n$msg";
179        return wrapi18n( "", $spaces, sprintf( $msg, @args ) ) . "\n";
180    }
181}
182
183=head2 Wrappers for other modules
184
185=over
186
187=item
188
189Locale::Gettext
190
191When the Locale::Gettext module cannot be loaded, this module provide dummy
192(empty) implementation of the following functions. In that case, po4a
193messages won't get translated but the program will continue to work.
194
195If Locale::gettext is present, this wrapper also calls
196setlocale(LC_MESSAGES, "") so callers don't depend on the POSIX module
197either.
198
199=over
200
201=item
202
203bindtextdomain($$)
204
205=item
206
207textdomain($)
208
209=item
210
211gettext($)
212
213=item
214
215dgettext($$)
216
217=back
218
219=back
220
221=cut
222
223BEGIN {
224    if ( eval { require Locale::gettext } ) {
225        import Locale::gettext;
226        require POSIX;
227        POSIX::setlocale( &POSIX::LC_MESSAGES, '' );
228    } else {
229        eval '
230           sub bindtextdomain($$) { }
231           sub textdomain($) { }
232           sub gettext($) { shift }
233           sub dgettext($$) { return $_[1] }
234       '
235    }
236}
237
2381;
239__END__
240
241=head1 AUTHORS
242
243 Jordi Vilalta <jvprat@gmail.com>
244
245=head1 COPYRIGHT AND LICENSE
246
247Copyright © 2005 SPI, Inc.
248
249This program is free software; you may redistribute it and/or modify it
250under the terms of GPL (see the COPYING file).
251
252=cut
253