[Po4a-devel]Config files enhancement

Nicolas François nicolas.francois@centraliens.net
Wed, 20 Apr 2005 01:00:28 +0200


--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sun, Apr 17, 2005 at 01:24:07PM +0200, Jordi Vilalta wrote:
> Well, my idea was to be able to reuse the options. Once po4aweb is defined 
> (in the example above), there can be lots of documents using this "alias". 
> Maybe we could do a mix between both approaches: common options defined as 
> module aliases, and file-specific options defined in the file line.

OK, I was only thinking about the -o options.

So here is another implementation.
I was able to use:
[type:man] ../../chage.1 fr:fr/chage.1 add_fr:addendums/fr/chage.1.fr.add modopt:-L UTF-8 -v
[type:man] ../../chfn.1 fr:fr/chfn.1 add_fr:addendums/fr/addendum.fr modopt:-L latin-1
[type:man] ../../chpasswd.8 fr:fr/chpasswd.8 add_fr:addendums/fr/chpasswd.8.fr.add modopt:-o debug=postrans
[type:man] ../../chsh.1 fr:fr/chsh.1 add_fr:addendums/fr/chsh.1.fr.add modopt:-o debug=0
[type:man] ../../dpasswd.8 fr:fr/dpasswd.8 add_fr:addendums/fr/addendum.fr
[type:man] ../../lastlog.8 fr:fr/lastlog.8 add_fr:addendums/fr/addendum.fr modopt:-k 0

However, I had to do a little modification on the initialize subroutine
from the man module:
As the man module uses a static variable to keep the options, this static
variable needs to be reset in initialize (other modules probably needs the
same  correction). Otherwise, if you use -o debug=postrans, then all the
next files will inherit from this option without any way to disable it

Also, I had to add the verbose option to the man module in order to use
po4a -v <file>
(This is already in the CVS, but maybe some other modules need to be
fixed)



The main bug of this implementation is that it doesn't allow option
parameter with space to be set from the file. The handling of quotes
should be added later. BTW, if you know of any library which do that, it
may be interesting.
Also, I don't tested how options are overridden when they are set on the
command line and on the file.


> We could use the same syntax (modopt and others) while defining the module 
> aliases, being able to do something like:
> 
> [po4a_alias: po4aweb] xml modopt:inline="<a>" opt:"-k 0" \
>                       opt_fr:"-L iso-8859-1" opt_zh:"-L utf-8"
> 
> [type: po4aweb] index.xml $lang:index.xml.$lang
> [type: po4aweb] features.xml $lang:features.xml.$lang modopt:inline="<b>"

The attached implementation only allows a (or some) "modopt:" parameter.
However, it should be very simple to implement what you want (it is just a
matter of keeping the options, and appending all the relevant (the one
from the module, the one from the file and the one from the language)
options when needed.

Just let me know if it seems OK, and if I should commit it (after some
cleanups) before the release (it may need some testing).

Regards,
-- 
Nekral

--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="po4a_options.patch"

Index: po4a
===================================================================
RCS file: /cvsroot/po4a/po4a/po4a,v
retrieving revision 1.26
diff -u -r1.26 po4a
--- po4a	4 Mar 2005 16:40:40 -0000	1.26
+++ po4a	19 Apr 2005 22:56:42 -0000
@@ -213,45 +213,70 @@
     exit 0;
 }
 
-my ($help,$type,$debug,@verbose,$quiet,@options,$split);
-@verbose = ();
-$debug = 0;
-$split = 0;
-my ($threshold)=(80);
-my ($mastchar,$locchar,$addchar);
-Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
-GetOptions(
-	'help|h'        => \$help,
-
-	'master-charset|M=s'    => \$mastchar,
-	'localized-charset|L=s' => \$locchar,
-	'addendum-charset|A=s' => \$addchar,
+sub get_options {
+    if (defined $_[0]) {
+        @ARGV = @_;
+        print "ARGV: @ARGV\n";
+    }
+    my @verbose = ();
+    my @options = ();
+    my %opts = (
+	"help"      => 0,
+	"type"      => "",
+	"debug"     => 0,
+	"verbose"   => 0,
+	"quiet"     => 0,
+	"split"     => 0,
+	"threshold" => 80,
+	"mastchar"  => "",
+	"locchar"   => "",
+	"addchar"   => "",
+	"options"   => {"verbose" => 0, "debug" => 0}
+    );
+    Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
+    GetOptions(
+	'help|h'        => \$opts{"help"},
+
+	'master-charset|M=s'    => \$opts{"mastchar"},
+	'localized-charset|L=s' => \$opts{"locchar"},
+	'addendum-charset|A=s' => \$opts{"addchar"},
 
 	'verbose|v'     => \@verbose,
-	'debug|d'       => \$debug,
-	'quiet|q'       => \$quiet,
-	'split|s'       => \$split,
-	'keep|k=s'      => \$threshold,
-	'version|V'     => \&show_version
-) or pod2usage();
-
-# Argument check
-$help && pod2usage (-verbose => 1, -exitval => 0);
-
-my ($verbose) = (scalar @verbose);
-$verbose = 1 if $debug;
-$verbose = -1 if $quiet;
-my %options = (
-    "verbose" => $verbose,
-    "debug" => $debug);
-
-foreach (@options) {
-    if (m/^([^=]*)=(.*)$/) {
-	$options{$1}="$2";
-    } else {
-	$options{$_}=1;
+	'debug|d'       => \$opts{"debug"},
+	'quiet|q'       => \$opts{"quiet"},
+	'split|s'       => \$opts{"split"},
+	'keep|k=s'      => \$opts{"threshold"},
+	'version|V'     => \&show_version,
+	'option|o=s'    => \@options
+    ) or pod2usage();
+
+    $opts{"verbose"} = scalar @verbose;
+    $opts{"verbose"} =  1 if $opts{"debug"};
+    $opts{"verbose"} = -1 if $opts{"quiet"};
+
+    # options to transmit to the modules
+    %{$opts{"options"}} = (
+	"verbose" => $opts{"verbose"},
+	"debug"   => $opts{"debug"}
+    );
+    foreach (@options) {
+        if (m/^([^=]*)=(.*)$/) {
+	    $opts{"options"}{$1}="$2";
+	} else {
+	    $opts{"options"}{$_}=1;
+	}
     }
+print %opts;
+print "\n";
+print %{$opts{"options"}};
+print "\n";
+    return %opts;
 }
+my @ORIGINAL_ARGV = @ARGV;
+pop @ORIGINAL_ARGV;
+my %po4a_opts = get_options(@ARGV);
+# Argument check
+$po4a_opts{"help"} && pod2usage (-verbose => 1, -exitval => 0);
 
 my $config_file= shift(@ARGV) || pod2usage();
 # Check file existence
@@ -299,7 +324,7 @@
 	$args = $args2;
     }
 
-    print "cmd=[$cmd]; main=$main; args=\"$args\"\n" if $debug;
+    print "cmd=[$cmd]; main=$main; args=\"$args\"\n" if $po4a_opts{"debug"};
 
     if ($cmd eq "po4a_paths") {
 	die wrap_ref_mod("$config_file:$nb", "",
@@ -321,6 +346,10 @@
 
     } elsif ($cmd =~ m/type: *(.*)/) {
 	$document{$main}{'format'} = $1;
+	if ($args =~ m/^(.*) modopt:(.*)$/) {
+	    $args = $1;
+	    $document{$main}{'modopt'} = $2;
+	}
 	foreach my $arg (split(/ /,$args)) {
 	    die wrap_ref_mod("$config_file:$nb", "",
 		gettext("Unparsable argument '%s' (%s)."), $arg, $line)
@@ -354,15 +383,23 @@
 # make a big pot
 if (-e $pot_filename) {
     print wrap_msg(gettext("Updating %s:"), $pot_filename)
-	if $verbose;
+	if $po4a_opts{"verbose"};
 } else {
     print wrap_msg(gettext("Creating %s:"), $pot_filename)
-	if $verbose;
+	if $po4a_opts{"verbose"};
 }
 
 my $potfile=Locale::Po4a::Po->new();
 foreach my $master (keys %document) {
-    my $doc=Locale::Po4a::Chooser::new($document{$master}{'format'},%options);
+    my %file_opts = %po4a_opts;
+    if (defined $document{$master}{'modopt'}) {
+	%file_opts = get_options(@ORIGINAL_ARGV,
+	                         split(/ /, $document{$master}{'modopt'}));
+    }
+    my $doc=Locale::Po4a::Chooser::new($document{$master}{'format'},
+                                       %{$file_opts{"options"}});
+
+
     # We ensure that the generated po will be in utf-8 if the input document
     # isn't entirely in ascii
     $doc->{TT}{utf_mode} = 1;
@@ -371,7 +408,7 @@
     my @file_in_name;
     push @file_in_name, $master;
     $doc->process('file_in_name'     => \@file_in_name,
-                  'file_in_charset'  => $mastchar);
+                  'file_in_charset'  => $file_opts{"mastchar"});
     $potfile = $doc->getpoout();
 }
 $potfile->write($pot_filename);
@@ -383,8 +420,8 @@
 foreach $lang (sort keys %po_filename) {
     if (-e $po_filename{$lang}) {
 	print STDERR wrap_msg(gettext("Updating %s:")." ", $po_filename{$lang})
-	    if ($verbose);
-	if ($split) {
+	    if ($po4a_opts{"verbose"});
+	if ($po4a_opts{"split"}) {
 	    my ($pot_filename,$po_filename,$bigpo_filename);
 	    (undef,$pot_filename)=File::Temp->tempfile("po4aXXXX",
 						       DIR    => "/tmp",
@@ -423,14 +460,14 @@
 	    unlink($po_filename) if -e $po_filename;
 
 	} else {
-	    system ("msgmerge -U ".$po_filename{$lang}." $pot_filename ".($verbose?"":">/dev/null 2>/dev/null"))
+	    system ("msgmerge -U ".$po_filename{$lang}." $pot_filename ".($po4a_opts{"verbose"}?"":">/dev/null 2>/dev/null"))
 		&& die wrap_msg(gettext("Error while running msgmerge: %s"), $!);
 	    system "msgfmt --statistics -v -o /dev/null ".$po_filename{$lang} 
-	    if $verbose;
+	    if $po4a_opts{"verbose"};
 	}
     } else {
 	print STDERR wrap_msg(gettext("Creating %s:"), $po_filename{$lang}) 
-	    if $verbose;
+	    if $po4a_opts{"verbose"};
 	system ("cp",$pot_filename,$po_filename{$lang}) == 0 ||
 	    die wrap_msg(gettext("Error while copying the po file: %s"), $!);
     }
@@ -441,7 +478,13 @@
     DOC: foreach my $master (sort keys %document) {
 	next unless defined $document{$master}{$lang};
 
-	my $doc=Locale::Po4a::Chooser::new($document{$master}{'format'} ,%options);
+	my %file_opts = %po4a_opts;
+	if (defined $document{$master}{'modopt'}) {
+	    %file_opts = get_options(@ORIGINAL_ARGV,
+	                             split(/ /, $document{$master}{'modopt'}));
+	}
+	my $doc=Locale::Po4a::Chooser::new($document{$master}{'format'},
+	                                   %{$file_opts{"options"}});
 
 	my (@file_in_name,@po_in_name);
 	push @file_in_name, $master;
@@ -450,15 +493,15 @@
 	$doc->process('file_in_name'  => \@file_in_name,
 	              'file_out_name' => $document{$master}{$lang},
 	              'po_in_name'    => \@po_in_name,
-                      'file_in_charset'  => $mastchar,
-                      'file_out_charset' => $locchar,
-                      'addendum_charset' => $addchar);
+                      'file_in_charset'  => $file_opts{"mastchar"},
+                      'file_out_charset' => $file_opts{"locchar"},
+                      'addendum_charset' => $file_opts{"addchar"});
 
 	my ($percent,$hit,$queries) = $doc->stats();
 
-	if ($percent<$threshold)  {
+	if ($percent<$file_opts{"threshold"})  {
 	    print STDERR wrap_msg(gettext("Discard %s (only %s%% translated; need %s%%)."),
-		$document{$master}{$lang}, $percent, $threshold);
+		$document{$master}{$lang}, $percent, $file_opts{"threshold"});
 	    unlink($document{$master}{$lang}) if (-e $document{$master}{$lang});
 	    next DOC;
 	}
@@ -473,7 +516,7 @@
 		}
 	    }
 	}
-	if ($verbose) {
+	if ($file_opts{"verbose"}) {
 	    if ($percent == 100) {
 		print STDERR wrap_msg(gettext("%s is %s%% translated (%s strings)."),
 		    $document{$master}{$lang}, $percent, $queries);
Index: lib/Locale/Po4a/Man.pm
===================================================================
RCS file: /cvsroot/po4a/po4a/lib/Locale/Po4a/Man.pm,v
retrieving revision 1.86
diff -u -r1.86 Man.pm
--- lib/Locale/Po4a/Man.pm	10 Apr 2005 19:23:18 -0000	1.86
+++ lib/Locale/Po4a/Man.pm	19 Apr 2005 22:56:44 -0000
@@ -309,10 +315,13 @@
     my %options = @_;
 
     $self->{options}{'debug'}='';
-    $self->{options}{'verbose'}='';
+    $self->{options}{'verbose'}=''; # not used internally, but needed by po4a
+
+    # reset the debug options
+    %debug = ();
 
     foreach my $opt (keys %options) {
-        if ($options{$opt}) {
+        if (defined $options{$opt}) {
             die wrap_mod("po4a::man",
                          dgettext("po4a", "Unknown option: %s"), $opt)
                 unless exists $self->{options}{$opt};

--MGYHOYXEY6WxJCY8--