source: main/trunk/greenstone2/perllib/gsprintf.pm@ 31208

Last change on this file since 31208 was 27306, checked in by jmt12, 11 years ago

Moving the critical file-related functions (copy, rm, etc) out of util.pm into their own proper class FileUtils. Use of the old functions in util.pm will prompt deprecated warning messages. There may be further functions that could be moved across in the future, but these are the critical ones when considering supporting other filesystems (HTTP, HDFS, WebDav, etc). Updated some key files to use the new functions so now deprecated messages thrown when importing/building demo collection 'out of the box'

  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1###########################################################################
2#
3# gsprintf.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25use strict;
26no strict 'refs';
27
28package gsprintf;
29require Exporter;
30@gsprintf::ISA=qw(Exporter);
31
32use unicode;
33use util;
34use FileUtils;
35
36@gsprintf::EXPORT_OK = qw(gsprintf); # functions we can export into namespace
37
38
39# Language-specific resource bundle
40my %specialresourcebundle = ();
41our $specialoutputencoding; # our, so that it can be changed outside.
42
43# Default resource bundle
44my %defaultresourcebundle;
45my $defaultoutputencoding;
46
47# English resource bundle
48my %englishresourcebundle;
49my $englishoutputencoding;
50
51# Ignore the OutputEncoding strings in the resource bundles and output all text in UTF-8
52my $outputstringsinUTF8 = 0;
53my $freetext_xml_mode = 0;
54
55
56sub make_freetext_xml_safe
57{
58 my ($text) = @_;
59
60 $text =~ s/\&/&/g;
61 $text =~ s/\"/"/g;
62 $text =~ s/\</&lt;/g;
63 $text =~ s/\>/&gt;/g;
64
65 return $text;
66}
67
68
69sub gsprintf
70{
71 my ($handle, $text_string, @text_arguments) = @_;
72
73 # Return unless the required arguments were supplied
74 return unless (defined($handle) && defined($text_string));
75
76 # Look up all the strings in the dictionary
77 $text_string =~ s/(\{[^\}]+\})/&lookup_string($1)/eg;
78
79 # Resolve the string arguments using sprintf, then write out to the handle
80 my $text_string_resolved = sprintf($text_string, @text_arguments);
81
82 if ($freetext_xml_mode) {
83 $text_string_resolved = make_freetext_xml_safe($text_string_resolved);
84 }
85
86 print $handle $text_string_resolved;
87}
88
89
90sub lookup_string
91{
92 my ($stringkey) = @_;
93 return "" unless defined $stringkey;
94 # Try the language-specific resource bundle first
95 my $utf8string = $specialresourcebundle{$stringkey};
96 my $outputencoding = $specialoutputencoding;
97
98 # Try the default resource bundle next
99 if (!defined($utf8string)) {
100 # Load the default resource bundle if it is not already loaded
101 &load_default_resource_bundle() if (!%defaultresourcebundle);
102
103 $utf8string = $defaultresourcebundle{$stringkey};
104 $outputencoding = $defaultoutputencoding;
105 }
106
107 # Try the English resource bundle last
108 if (!defined($utf8string)) {
109 # Load the English resource bundle if it is not already loaded
110 &load_english_resource_bundle() if (!%englishresourcebundle);
111
112 $utf8string = $englishresourcebundle{$stringkey};
113 $outputencoding = $englishoutputencoding;
114 }
115
116 # No matching string was found, so just return the key
117 if (!defined($utf8string)) {
118 return $stringkey;
119 }
120
121 # Return the string matching the key
122 return $utf8string if (!defined($outputencoding) || $outputstringsinUTF8
123 || $outputencoding eq "utf8");
124
125 # If an 8-bit output encoding has been defined, encode the string appropriately
126 my $encoded=unicode::unicode2singlebyte(&unicode::utf82unicode($utf8string), $outputencoding);
127
128 # If we successfully encoded it, return it
129 if ($encoded) { return $encoded }
130
131 # Otherwise, we can't convert to the requested encoding. return the utf8?
132 $specialoutputencoding='utf8';
133 return $utf8string;
134}
135
136
137sub load_language_specific_resource_bundle
138{
139 my $language = shift(@_);
140
141 # Read the specified resource bundle
142 my $resourcebundlename = "strings_" . $language . ".properties";
143
144 %specialresourcebundle
145 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
146 return if (!%specialresourcebundle);
147
148 # Read the output encoding to use from the resource bundle
149 if ($ENV{'GSDLOS'} =~ /windows/) {
150 $specialoutputencoding = $specialresourcebundle{"{OutputEncoding.windows}"};
151 }
152 else {
153 # see if there is an encoding set in the appropriate locale env var
154
155 foreach my $envvar ('LC_ALL', 'LANG') {
156 if (!exists $ENV{$envvar}) { next }
157 my $locale=$ENV{$envvar};
158 if ($locale !~ /^\w+\.(.+)$/) { next }
159 my $enc=lc($1);
160 $enc =~ s/-/_/g;
161 if ($enc eq 'utf_8') { $enc='utf8' } # normalise to this name
162 $specialoutputencoding = $enc;
163 return;
164 }
165 $specialoutputencoding = $specialresourcebundle{"{OutputEncoding.unix}"};
166 }
167}
168
169
170sub load_default_resource_bundle
171{
172 # Read the default resource bundle
173 my $resourcebundlename = "strings.properties";
174
175 %defaultresourcebundle
176 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
177 if (!%defaultresourcebundle) {
178 # $! will still have the error value for the last failed syscall
179
180 my $error_message = "$! $resourcebundlename\n";
181
182 if ($freetext_xml_mode) {
183 $error_message = make_freetext_xml_safe($error_message);
184 }
185
186 print STDERR $error_message;
187
188 # set something so we don't bother trying to load it again
189 $defaultresourcebundle{0}=undef;
190 return;
191 }
192
193 # Read the output encoding to use from the resource bundle
194 if ($ENV{'GSDLOS'} =~ /windows/) {
195 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.windows}"};
196 }
197 else {
198 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.unix}"};
199 }
200}
201
202
203sub load_english_resource_bundle
204{
205 # Ensure the English resource bundle hasn't already been loaded
206 if (%specialresourcebundle && $specialresourcebundle{"{Language.code}"} eq "en") {
207 %englishresourcebundle = %specialresourcebundle;
208 $englishoutputencoding = $specialoutputencoding;
209 }
210
211 if ($defaultresourcebundle{"{Language.code}"} &&
212 $defaultresourcebundle{"{Language.code}"} eq "en") {
213 %englishresourcebundle = %defaultresourcebundle;
214 $englishoutputencoding = $defaultoutputencoding;
215 }
216
217 # Read the English resource bundle
218 my $resourcebundlename = "strings_en.properties";
219
220 %englishresourcebundle
221 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
222 return if (!%englishresourcebundle);
223
224 # Read the output encoding to use from the resource bundle
225 if ($ENV{'GSDLOS'} =~ /windows/) {
226 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.windows}"};
227 }
228 else {
229 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.unix}"};
230 }
231}
232
233
234sub read_resource_bundle_and_extensions
235{
236 my ($bundle_base,$primary_dir,$resourcename) = @_;
237
238 my $primary_resourcebundlefile
239 = &FileUtils::filenameConcatenate($bundle_base,$primary_dir,$resourcename);
240
241 my $resourcebundle = read_resource_bundle($primary_resourcebundlefile);
242 return if (!defined $resourcebundle);
243
244 if (defined $ENV{'GSDLEXTS'}) {
245 my @extensions = split(/:/,$ENV{'GSDLEXTS'});
246 foreach my $e (@extensions) {
247 my $ext_base
248 = &FileUtils::filenameConcatenate($bundle_base,"ext",$e);
249
250 my $ext_resourcebundlefile
251 = &FileUtils::filenameConcatenate($ext_base,$primary_dir,$resourcename);
252
253 # can ignore return value (will be same reference to $resourcebundle)
254 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
255 }
256 }
257 if (defined $ENV{'GSDL3EXTS'}) {
258 my @extensions = split(/:/,$ENV{'GSDL3EXTS'});
259 foreach my $e (@extensions) {
260 my $ext_base
261 = &FileUtils::filenameConcatenate($ENV{'GSDL3SRCHOME'},"ext",$e);
262
263 my $ext_resourcebundlefile
264 = &FileUtils::filenameConcatenate($ext_base,$primary_dir,$resourcename);
265
266 # can ignore return value (will be same reference to $resourcebundle)
267 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
268 }
269 }
270
271 return %$resourcebundle;
272}
273
274
275sub read_resource_bundle
276{
277 my ($resourcebundlefilepath,$resourcebundle) = @_;
278
279 if (!open(RESOURCE_BUNDLE, "<$resourcebundlefilepath")) {
280 # When called for the first time (primary resource), $resourcebundle
281 # is not defined (=undef). If the file does not exist, then we return
282 # this 'undef' to signal it was not found
283 # For an extension resource bundle, if it does not exist this
284 # is not so serious (in fact quite likely) => return what we
285 # have built up so far
286
287 return $resourcebundle;
288 }
289
290 if (!defined $resourcebundle) {
291 # resource files exists, so exect some content to be stored
292 $resourcebundle = {};
293 }
294
295 # Load this resource bundle
296 my @resourcebundlelines = <RESOURCE_BUNDLE>;
297 close(RESOURCE_BUNDLE);
298
299 # Parse the resource bundle
300
301 foreach my $line (@resourcebundlelines) {
302 # Remove any trailing whitespace
303 $line =~ s/(\s*)$//;
304
305 # Ignore comments and empty lines
306 if ($line !~ /^\#/ && $line ne "") {
307 # Parse key (everything up to the first colon)
308 if ($line =~ m/^([^:]+):(.+)$/) {
309 my $linekey = "{" . $1 . "}";
310 my $linetext = $2;
311 $linetext =~ s/(\s*)\#\s+Updated\s+(\d?\d-\D\D\D-\d\d\d\d).*$//i;
312
313 # Map key to text
314 $resourcebundle->{$linekey} = $linetext;
315 }
316 }
317 }
318
319 return $resourcebundle;
320}
321
322
323sub set_print_freetext_for_xml
324{
325 $freetext_xml_mode = 1;
326}
327
328sub set_print_xml_tags
329{
330 $freetext_xml_mode = 0;
331}
332
333sub output_strings_in_UTF8
334{
335 $outputstringsinUTF8 = 1;
336}
337
338
339sub debug_unicode_string
340{
341 join("",
342 map { $_ > 255 ? # if wide character...
343 sprintf("\\x{%04X}", $_) : # \x{...}
344 chr($_)
345 } unpack("U*", $_[0])); # unpack Unicode characters
346}
347
348
3491;
Note: See TracBrowser for help on using the repository browser.