📄 intltool-merge.in
字号:
#!@INTLTOOL_PERL@ -w
# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# The Intltool Message Merger
#
# Copyright (C) 2000, 2003 Free Software Foundation.
# Copyright (C) 2000, 2001 Eazel, Inc
#
# Intltool is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 published by the Free Software Foundation.
#
# Intltool is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
#
# Authors: Maciej Stachowiak <mjs@noisehavoc.org>
# Kenneth Christiansen <kenneth@gnu.org>
# Darin Adler <darin@bentspoon.com>
#
# Proper XML UTF-8'ification written by Cyrille Chepelov <chepelov@calixo.net>
#
## Release information
my $PROGRAM = "intltool-merge";
my $PACKAGE = "intltool";
my $VERSION = "0.33";
## Loaded modules
use strict;
use Getopt::Long;
use Text::Wrap;
use File::Basename;
my $must_end_tag = -1;
my $last_depth = -1;
my $translation_depth = -1;
my @tag_stack = ();
my @entered_tag = ();
my @translation_strings = ();
my $leading_space = "";
## Scalars used by the option stuff
my $HELP_ARG = 0;
my $VERSION_ARG = 0;
my $BA_STYLE_ARG = 0;
my $XML_STYLE_ARG = 0;
my $KEYS_STYLE_ARG = 0;
my $DESKTOP_STYLE_ARG = 0;
my $SCHEMAS_STYLE_ARG = 0;
my $RFC822DEB_STYLE_ARG = 0;
my $QUIET_ARG = 0;
my $PASS_THROUGH_ARG = 0;
my $UTF8_ARG = 0;
my $MULTIPLE_OUTPUT = 0;
my $cache_file;
## Handle options
GetOptions
(
"help" => \$HELP_ARG,
"version" => \$VERSION_ARG,
"quiet|q" => \$QUIET_ARG,
"oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility
"ba-style|b" => \$BA_STYLE_ARG,
"xml-style|x" => \$XML_STYLE_ARG,
"keys-style|k" => \$KEYS_STYLE_ARG,
"desktop-style|d" => \$DESKTOP_STYLE_ARG,
"schemas-style|s" => \$SCHEMAS_STYLE_ARG,
"rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG,
"pass-through|p" => \$PASS_THROUGH_ARG,
"utf8|u" => \$UTF8_ARG,
"multiple-output|m" => \$MULTIPLE_OUTPUT,
"cache|c=s" => \$cache_file
) or &error;
my $PO_DIR;
my $FILE;
my $OUTFILE;
my %po_files_by_lang = ();
my %translations = ();
my $iconv = $ENV{"ICONV"} || $ENV{"INTLTOOL_ICONV"} || "/usr/bin/iconv";
# Use this instead of \w for XML files to handle more possible characters.
my $w = "[-A-Za-z0-9._:]";
# XML quoted string contents
my $q = "[^\\\"]*";
## Check for options.
if ($VERSION_ARG)
{
&print_version;
}
elsif ($HELP_ARG)
{
&print_help;
}
elsif ($BA_STYLE_ARG && @ARGV > 2)
{
&utf8_sanity_check;
&preparation;
&print_message;
&ba_merge_translations;
&finalize;
}
elsif ($XML_STYLE_ARG && @ARGV > 2)
{
&utf8_sanity_check;
&preparation;
&print_message;
&xml_merge_output;
&finalize;
}
elsif ($KEYS_STYLE_ARG && @ARGV > 2)
{
&utf8_sanity_check;
&preparation;
&print_message;
&keys_merge_translations;
&finalize;
}
elsif ($DESKTOP_STYLE_ARG && @ARGV > 2)
{
&utf8_sanity_check;
&preparation;
&print_message;
&desktop_merge_translations;
&finalize;
}
elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2)
{
&utf8_sanity_check;
&preparation;
&print_message;
&schemas_merge_translations;
&finalize;
}
elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2)
{
&preparation;
&print_message;
&rfc822deb_merge_translations;
&finalize;
}
else
{
&print_help;
}
exit;
## Sub for printing release information
sub print_version
{
print <<_EOF_;
${PROGRAM} (${PACKAGE}) ${VERSION}
Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.
Copyright (C) 2000-2003 Free Software Foundation, Inc.
Copyright (C) 2000-2001 Eazel, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
_EOF_
exit;
}
## Sub for printing usage information
sub print_help
{
print <<_EOF_;
Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE
Generates an output file that includes some localized attributes from an
untranslated source file.
Mandatory options: (exactly one must be specified)
-b, --ba-style includes translations in the bonobo-activation style
-d, --desktop-style includes translations in the desktop style
-k, --keys-style includes translations in the keys style
-s, --schemas-style includes translations in the schemas style
-r, --rfc822deb-style includes translations in the RFC822 style
-x, --xml-style includes translations in the standard xml style
Other options:
-u, --utf8 convert all strings to UTF-8 before merging
(default for everything except RFC822 style)
-p, --pass-through deprecated, does nothing and issues a warning
-m, --multiple-output output one localized file per locale, instead of
a single file containing all localized elements
-c, --cache=FILE specify cache file name
(usually \$top_builddir/po/.intltool-merge-cache)
-q, --quiet suppress most messages
--help display this help and exit
--version output version information and exit
Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
or send email to <xml-i18n-tools\@gnome.org>.
_EOF_
exit;
}
## Sub for printing error messages
sub print_error
{
print STDERR "Try `${PROGRAM} --help' for more information.\n";
exit;
}
sub print_message
{
print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG;
}
sub preparation
{
$PO_DIR = $ARGV[0];
$FILE = $ARGV[1];
$OUTFILE = $ARGV[2];
&gather_po_files;
&get_translation_database;
}
# General-purpose code for looking up translations in .po files
sub po_file2lang
{
my ($tmp) = @_;
$tmp =~ s/^.*\/(.*)\.po$/$1/;
return $tmp;
}
sub gather_po_files
{
for my $po_file (glob "$PO_DIR/*.po") {
$po_files_by_lang{po_file2lang($po_file)} = $po_file;
}
}
sub get_local_charset
{
my ($encoding) = @_;
my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "/usr/lib/charset.alias";
# seek character encoding aliases in charset.alias (glib)
if (open CHARSET_ALIAS, $alias_file)
{
while (<CHARSET_ALIAS>)
{
next if /^\#/;
return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i)
}
close CHARSET_ALIAS;
}
# if not found, return input string
return $encoding;
}
sub get_po_encoding
{
my ($in_po_file) = @_;
my $encoding = "";
open IN_PO_FILE, $in_po_file or die;
while (<IN_PO_FILE>)
{
## example: "Content-Type: text/plain; charset=ISO-8859-1\n"
if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/)
{
$encoding = $1;
last;
}
}
close IN_PO_FILE;
if (!$encoding)
{
print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG;
$encoding = "ISO-8859-1";
}
system ("$iconv -f $encoding -t UTF-8 </dev/null 2>/dev/null");
if ($?) {
$encoding = get_local_charset($encoding);
}
return $encoding
}
sub utf8_sanity_check
{
print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG;
$UTF8_ARG = 1;
}
sub get_translation_database
{
if ($cache_file) {
&get_cached_translation_database;
} else {
&create_translation_database;
}
}
sub get_newest_po_age
{
my $newest_age;
foreach my $file (values %po_files_by_lang)
{
my $file_age = -M $file;
$newest_age = $file_age if !$newest_age || $file_age < $newest_age;
}
$newest_age = 0 if !$newest_age;
return $newest_age;
}
sub create_cache
{
print "Generating and caching the translation database\n" unless $QUIET_ARG;
&create_translation_database;
open CACHE, ">$cache_file" || die;
print CACHE join "\x01", %translations;
close CACHE;
}
sub load_cache
{
print "Found cached translation database\n" unless $QUIET_ARG;
my $contents;
open CACHE, "<$cache_file" || die;
{
local $/;
$contents = <CACHE>;
}
close CACHE;
%translations = split "\x01", $contents;
}
sub get_cached_translation_database
{
my $cache_file_age = -M $cache_file;
if (defined $cache_file_age)
{
if ($cache_file_age <= &get_newest_po_age)
{
&load_cache;
return;
}
print "Found too-old cached translation database\n" unless $QUIET_ARG;
}
&create_cache;
}
sub create_translation_database
{
for my $lang (keys %po_files_by_lang)
{
my $po_file = $po_files_by_lang{$lang};
if ($UTF8_ARG)
{
my $encoding = get_po_encoding ($po_file);
if (lc $encoding eq "utf-8")
{
open PO_FILE, "<$po_file";
}
else
{
print STDERR "WARNING: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;;
open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|";
}
}
else
{
open PO_FILE, "<$po_file";
}
my $nextfuzzy = 0;
my $inmsgid = 0;
my $inmsgstr = 0;
my $msgid = "";
my $msgstr = "";
while (<PO_FILE>)
{
$nextfuzzy = 1 if /^#, fuzzy/;
if (/^msgid "((\\.|[^\\])*)"/ )
{
$translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
$msgid = "";
$msgstr = "";
if ($nextfuzzy) {
$inmsgid = 0;
} else {
$msgid = unescape_po_string($1);
$inmsgid = 1;
}
$inmsgstr = 0;
$nextfuzzy = 0;
}
if (/^msgstr "((\\.|[^\\])*)"/)
{
$msgstr = unescape_po_string($1);
$inmsgstr = 1;
$inmsgid = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -