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

Last change on this file since 27505 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
RevLine 
[5613]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###########################################################################
[7828]25use strict;
26no strict 'refs';
[5613]27
28package gsprintf;
[7828]29require Exporter;
30@gsprintf::ISA=qw(Exporter);
[5613]31
[6934]32use unicode;
[5613]33use util;
[27306]34use FileUtils;
[5613]35
[15007]36@gsprintf::EXPORT_OK = qw(gsprintf); # functions we can export into namespace
[5613]37
[7828]38
[6945]39# Language-specific resource bundle
40my %specialresourcebundle = ();
[6993]41our $specialoutputencoding; # our, so that it can be changed outside.
[6925]42
[6945]43# Default resource bundle
44my %defaultresourcebundle;
45my $defaultoutputencoding;
[6925]46
[6945]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;
[25499]53my $freetext_xml_mode = 0;
[6945]54
55
[25499]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
[5613]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));
[18981]75
[5613]76 # Look up all the strings in the dictionary
[6925]77 $text_string =~ s/(\{[^\}]+\})/&lookup_string($1)/eg;
[5613]78
79 # Resolve the string arguments using sprintf, then write out to the handle
[25499]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;
[5613]87}
88
89
[6920]90sub lookup_string
[5613]91{
[6934]92 my ($stringkey) = @_;
[10228]93 return "" unless defined $stringkey;
[6945]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)) {
[18981]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;
[6925]105 }
[18981]106
[6945]107 # Try the English resource bundle last
108 if (!defined($utf8string)) {
[18981]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;
[6945]114 }
[18981]115
[6945]116 # No matching string was found, so just return the key
117 if (!defined($utf8string)) {
[18981]118 return $stringkey;
[6945]119 }
[18981]120
[6945]121 # Return the string matching the key
[6993]122 return $utf8string if (!defined($outputencoding) || $outputstringsinUTF8
[18981]123 || $outputencoding eq "utf8");
124
[6934]125 # If an 8-bit output encoding has been defined, encode the string appropriately
[9969]126 my $encoded=unicode::unicode2singlebyte(&unicode::utf82unicode($utf8string), $outputencoding);
127
128 # If we successfully encoded it, return it
129 if ($encoded) { return $encoded }
[18981]130
[9969]131 # Otherwise, we can't convert to the requested encoding. return the utf8?
132 $specialoutputencoding='utf8';
133 return $utf8string;
[5613]134}
135
136
[6945]137sub load_language_specific_resource_bundle
[5613]138{
[6934]139 my $language = shift(@_);
[18981]140
[6945]141 # Read the specified resource bundle
[11632]142 my $resourcebundlename = "strings_" . $language . ".properties";
[18981]143
144 %specialresourcebundle
145 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
[6945]146 return if (!%specialresourcebundle);
[18981]147
[6945]148 # Read the output encoding to use from the resource bundle
149 if ($ENV{'GSDLOS'} =~ /windows/) {
[18981]150 $specialoutputencoding = $specialresourcebundle{"{OutputEncoding.windows}"};
[5613]151 }
[6945]152 else {
[18981]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}"};
[6945]166 }
167}
[5613]168
[6945]169
170sub load_default_resource_bundle
171{
172 # Read the default resource bundle
[11632]173 my $resourcebundlename = "strings.properties";
[5613]174
[18981]175 %defaultresourcebundle
176 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
[10982]177 if (!%defaultresourcebundle) {
178 # $! will still have the error value for the last failed syscall
[25499]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
[18981]188 # set something so we don't bother trying to load it again
189 $defaultresourcebundle{0}=undef;
[10982]190 return;
191 }
[18981]192
[6945]193 # Read the output encoding to use from the resource bundle
194 if ($ENV{'GSDLOS'} =~ /windows/) {
[18981]195 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.windows}"};
[5613]196 }
[6945]197 else {
[18981]198 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.unix}"};
[6945]199 }
200}
[5613]201
[6945]202
203sub load_english_resource_bundle
204{
205 # Ensure the English resource bundle hasn't already been loaded
[9362]206 if (%specialresourcebundle && $specialresourcebundle{"{Language.code}"} eq "en") {
[18981]207 %englishresourcebundle = %specialresourcebundle;
208 $englishoutputencoding = $specialoutputencoding;
[6945]209 }
[10982]210
211 if ($defaultresourcebundle{"{Language.code}"} &&
[17533]212 $defaultresourcebundle{"{Language.code}"} eq "en") {
[18981]213 %englishresourcebundle = %defaultresourcebundle;
214 $englishoutputencoding = $defaultoutputencoding;
[6945]215 }
[18981]216
[6945]217 # Read the English resource bundle
[11632]218 my $resourcebundlename = "strings_en.properties";
[6945]219
[18981]220 %englishresourcebundle
221 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
[6945]222 return if (!%englishresourcebundle);
[18981]223
[6945]224 # Read the output encoding to use from the resource bundle
225 if ($ENV{'GSDLOS'} =~ /windows/) {
[18981]226 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.windows}"};
[6945]227 }
228 else {
[18981]229 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.unix}"};
[6945]230 }
231}
232
233
[18981]234sub read_resource_bundle_and_extensions
235{
236 my ($bundle_base,$primary_dir,$resourcename) = @_;
237
238 my $primary_resourcebundlefile
[27306]239 = &FileUtils::filenameConcatenate($bundle_base,$primary_dir,$resourcename);
[18981]240
241 my $resourcebundle = read_resource_bundle($primary_resourcebundlefile);
242 return if (!defined $resourcebundle);
243
[19026]244 if (defined $ENV{'GSDLEXTS'}) {
245 my @extensions = split(/:/,$ENV{'GSDLEXTS'});
246 foreach my $e (@extensions) {
247 my $ext_base
[27306]248 = &FileUtils::filenameConcatenate($bundle_base,"ext",$e);
[19026]249
250 my $ext_resourcebundlefile
[27306]251 = &FileUtils::filenameConcatenate($ext_base,$primary_dir,$resourcename);
[19026]252
253 # can ignore return value (will be same reference to $resourcebundle)
254 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
255 }
[18981]256 }
[21289]257 if (defined $ENV{'GSDL3EXTS'}) {
258 my @extensions = split(/:/,$ENV{'GSDL3EXTS'});
259 foreach my $e (@extensions) {
260 my $ext_base
[27306]261 = &FileUtils::filenameConcatenate($ENV{'GSDL3SRCHOME'},"ext",$e);
[21289]262
263 my $ext_resourcebundlefile
[27306]264 = &FileUtils::filenameConcatenate($ext_base,$primary_dir,$resourcename);
[21289]265
266 # can ignore return value (will be same reference to $resourcebundle)
267 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
268 }
269 }
[18981]270
271 return %$resourcebundle;
272}
273
274
[6945]275sub read_resource_bundle
276{
[18981]277 my ($resourcebundlefilepath,$resourcebundle) = @_;
[6945]278
[18981]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 }
[6945]289
[18981]290 if (!defined $resourcebundle) {
291 # resource files exists, so exect some content to be stored
292 $resourcebundle = {};
293 }
294
[6945]295 # Load this resource bundle
[6934]296 my @resourcebundlelines = <RESOURCE_BUNDLE>;
[5613]297 close(RESOURCE_BUNDLE);
298
[6945]299 # Parse the resource bundle
[18981]300
[7828]301 foreach my $line (@resourcebundlelines) {
[17533]302 # Remove any trailing whitespace
303 $line =~ s/(\s*)$//;
[5613]304
[17533]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;
[5613]312
[17533]313 # Map key to text
[18981]314 $resourcebundle->{$linekey} = $linetext;
[17533]315 }
316 }
[5613]317 }
[6934]318
[18981]319 return $resourcebundle;
[5613]320}
321
322
[25499]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
[6945]333sub output_strings_in_UTF8
[6934]334{
[6945]335 $outputstringsinUTF8 = 1;
[6934]336}
337
338
[15007]339sub debug_unicode_string
340{
341 join("",
[17533]342 map { $_ > 255 ? # if wide character...
343 sprintf("\\x{%04X}", $_) : # \x{...}
344 chr($_)
345 } unpack("U*", $_[0])); # unpack Unicode characters
[15007]346}
347
348
[5613]3491;
Note: See TracBrowser for help on using the repository browser.