X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=locale%2Fde%2Flocales.pl;h=bb30c7a908b05dc733fc312c83af2b3953699246;hb=5828bfe58adf3be1d463392caf5c5fc29b30a8ac;hp=36d0e4785dc67c3f785693f1a44a8ebf88a62344;hpb=ae1b5cbad92eb30f55747d2aa986b9a0b7a433b5;p=kivitendo-erp.git diff --git a/locale/de/locales.pl b/locale/de/locales.pl index 36d0e4785..bb30c7a90 100755 --- a/locale/de/locales.pl +++ b/locale/de/locales.pl @@ -6,34 +6,61 @@ # this version of locles processes not only all required .pl files # but also all parse_html_templated files. -use POSIX; -use FileHandle; use Data::Dumper; +use FileHandle; +use Getopt::Long; +use List::Util qw(first); +use POSIX; +use Pod::Usage; $| = 1; $basedir = "../.."; $bindir = "$basedir/bin/mozilla"; $dbupdir = "$basedir/sql/Pg-upgrade"; +$dbupdir2 = "$basedir/sql/Pg-upgrade2"; $menufile = "menu.ini"; $submitsearch = qr/type\s*=\s*[\"\']?submit/i; -foreach $item (@ARGV) { - $item =~ s/-//g; - $arg{$item} = 1; +%referenced_html_files = (); + +my $opt_v = 0; +my $opt_n = 0; +my $opt_c = 0; + +sub parse_args { + my ($help, $man); + + GetOptions('no-custom-files' => \$opt_n, + 'check-files' => \$opt_c, + 'verbose' => \$opt_v, + 'help' => \$help, + 'man' => \$man,); + + if ($help) { + pod2usage(1); + exit 0; + } + + if ($man) { + pod2usage(-exitstatus => 0, -verbose => 2); + exit 0; + } } +parse_args(); + opendir DIR, "$bindir" or die "$!"; -@progfiles = grep { /\.pl/; !/(_|^\.)/ } readdir DIR; +@progfiles = grep { /\.pl$/ && !/(_|^\.)/ } readdir DIR; seekdir DIR, 0; @customfiles = grep /_/, readdir DIR; closedir DIR; # put customized files into @customfiles -@customfiles = () if ($arg{n}); -if ($arg{n}) { - @menufiles = ($menufile); +if ($opt_n) { + @customfiles = (); + @menufiles = ($menufile); } else { opendir DIR, "$basedir" or die "$!"; @menufiles = grep { /.*?_$menufile$/ } readdir DIR; @@ -45,11 +72,17 @@ opendir DIR, $dbupdir or die "$!"; @dbplfiles = grep { /\.pl$/ } readdir DIR; closedir DIR; +opendir DIR, $dbupdir2 or die "$!"; +@dbplfiles2 = grep { /\.pl$/ } readdir DIR; +closedir DIR; + # slurp the translations in if (-f 'all') { require "all"; } +my %old_texts = %{ $self->{texts} }; + # Read HTML templates. #%htmllocale = (); #@htmltemplates = <../../templates/webpages/*/*_master.html>; @@ -59,10 +92,11 @@ if (-f 'all') { map({ handle_file($_, $bindir); } @progfiles); map({ handle_file($_, $dbupdir); } @dbplfiles); +map({ handle_file($_, $dbupdir2); } @dbplfiles2); sub handle_file { my ($file, $dir) = @_; - print "\n$file" if $arg{v}; + print "\n$file" if $opt_v; %locale = (); %submit = (); %subrt = (); @@ -88,7 +122,7 @@ sub handle_file { if ($file eq 'menunew.pl') { foreach $item (@menufiles) { &scanmenu("$basedir/$item"); - print "." if $arg{v}; + print "." if $opt_v; } } @@ -99,20 +133,22 @@ sub handle_file { foreach $text (keys %$missing) { if ($locale{$text} || $htmllocale{$text}) { - unless ($self{texts}{$text}) { - $self{texts}{$text} = $missing->{$text}; + unless ($self->{texts}{$text}) { + $self->{texts}{$text} = $missing->{$text}; } } } open FH, ">$file" or die "$! : $file"; - print FH q|$self{texts} = { + print FH q|#!/usr/bin/perl + +$self->{texts} = { |; foreach $key (sort keys %locale) { - if ($self{texts}{$key}) { - $text = $self{texts}{$key}; + if ($self->{texts}{$key}) { + $text = $self->{texts}{$key}; } else { $text = $key; } @@ -130,7 +166,7 @@ sub handle_file { print FH q|}; -$self{subs} = { +$self->{subs} = { |; foreach $key (sort keys %subrt) { @@ -141,7 +177,7 @@ $self{subs} = { } foreach $key (sort keys %submit) { - $text = ($self{texts}{$key}) ? $self{texts}{$key} : $key; + $text = ($self->{texts}{$key}) ? $self->{texts}{$key} : $key; $text =~ s/'/\\'/g; $text =~ s/\\$/\\\\/; @@ -175,16 +211,18 @@ $self{subs} = { open FH, ">all" or die "$! : all"; -print FH q|# These are all the texts to build the translations files. +print FH q|#!/usr/bin/perl + +# These are all the texts to build the translations files. # The file has the form of 'english text' => 'foreign text', # you can add the translation in this file or in the 'missing' file # run locales.pl from this directory to rebuild the translation files -$self{texts} = { +$self->{texts} = { |; foreach $key (sort keys %alllocales) { - $text = $self{texts}{$key}; + $text = $self->{texts}{$key}; $count++; @@ -212,7 +250,9 @@ close FH; if (@missing) { open FH, ">missing" or die "$! : missing"; - print FH q|# add the missing texts and run locales.pl to rebuild + print FH q|#!/usr/bin/perl + +# add the missing texts and run locales.pl to rebuild $missing = { |; @@ -230,15 +270,52 @@ $missing = { } +@lost = (); + +if (-f "lost") { + require "lost"; + unlink "lost"; +} + +while (($text, $translation) = each %old_texts) { + next if ($alllocales{$text}); + + push @lost, { 'text' => $text, 'translation' => $translation }; +} + +if (scalar @lost) { + splice @lost, 0, (scalar @lost - 50) if (scalar @lost > 50); + + open FH, ">lost"; + print FH "#!/usr/bin/perl\n\n" . + "# The last 50 texts that have been removed.\n" . + "# This file will be auto-generated by locales.pl. Do not edit it.\n\n" . + "\@lost = (\n"; + + foreach $entry (@lost) { + $entry->{text} =~ s/\'/\\\'/g; + $entry->{translation} =~ s/\'/\\\'/g; + print FH " { 'text' => '$entry->{text}', 'translation' => '$entry->{translation}' },\n"; + } + + print FH ");\n\n1;\n"; + close FH; +} + open(FH, "LANGUAGE"); @language = ; close(FH); $trlanguage = $language[0]; chomp $trlanguage; +if ($opt_c) { + search_unused_htmlfiles(); + search_translated_htmlfiles_wo_master(); +} + $per = sprintf("%.1f", ($count - $notext) / $count * 100); print "\n$trlanguage - ${per}%"; -print " - $notext missing" if $notext; +print " - $notext/$count missing" if $notext; print "\n"; exit; @@ -271,7 +348,7 @@ sub extract_text_between_parenthesis { } elsif (($cur_char eq '"') || ($cur_char eq '\'')) { $inside_string = $cur_char; - } elsif ($cur_char eq ")") { + } elsif (($cur_char eq ")") || ($cur_char eq ',')) { return ($text, substr($line, $pos + 1)); } @@ -301,6 +378,9 @@ sub scanfile { my $dont_include_subs = shift; my $scanned_files = shift; + # sanitize file + $file =~ s=/+=/=g; + $scanned_files = {} unless ($scanned_files); return if ($scanned_files->{$file}); $scanned_files->{$file} = 1; @@ -321,22 +401,29 @@ sub scanfile { if (/require\s+\W.*\.pl/) { my $newfile = $&; $newfile =~ s/require\s+\W//; - $newfile =~ s/\$form->{path}\///; + $newfile =~ s|bin/mozilla||; # &scanfile("$bindir/$newfile", 0, $scanned_files); $cached{$file}{scan}{"$bindir/$newfile"} = 1; } elsif (/use\s+SL::(.*?);/) { + my $module = $1; + $module =~ s|::|/|g; # &scanfile("../../SL/${1}.pm", 1, $scanned_files); - $cached{$file}{scannosubs}{"../../SL/${1}.pm"} = 1; + $cached{$file}{scannosubs}{"../../SL/${module}.pm"} = 1; } # is this a template call? - if (/parse_html_template\s*\(\s*[\"\']([\w\/]+)/) { + if (/parse_html_template2?\s*\(\s*[\"\']([\w\/]+)\s*[\"\']/) { my $newfile = "$basedir/templates/webpages/$1_master.html"; + if (/parse_html_template2/) { + print "E: " . strip_base($file) . " is still using 'parse_html_template2' for " . strip_base($newfile) . ".\n"; + } if (-f $newfile) { # &scanhtmlfile($newfile); # &converthtmlfile($newfile); $cached{$file}{scanh}{$newfile} = 1; - print "." if $arg{v}; + print "." if $opt_v; + } elsif ($opt_c) { + print "W: missing HTML template: " . strip_base($newfile) . " (referenced from " . strip_base($file) . ")\n"; } } @@ -421,6 +508,8 @@ sub scanfile { map { &scanfile($_, 0, $scanned_files) } keys %{$cached{$file}{scan}}; map { &scanfile($_, 1, $scanned_files) } keys %{$cached{$file}{scannosubs}}; map { &scanhtmlfile($_) } keys %{$cached{$file}{scanh}}; + + @referenced_html_files{keys %{$cached{$file}{scanh}}} = (1) x scalar keys %{$cached{$file}{scanh}}; } sub scanmenu { @@ -429,7 +518,7 @@ sub scanmenu { my $fh = new FileHandle; open $fh, "$file" or die "$! : $file"; - my @a = grep /^\[/, <$fh>; + my @a = grep m/^\[/, <$fh>; close($fh); # strip [] @@ -448,9 +537,10 @@ sub scanmenu { sub scanhtmlfile { local *IN; - + if (!defined $cached{$_[0]}) { - + my %plugins = ( 'loaded' => { }, 'needed' => { } ); + open(IN, $_[0]) || die $_[0]; my $copying = 0; @@ -459,6 +549,34 @@ sub scanhtmlfile { while (my $line = ) { chomp($line); + while ($line =~ m/\[\%[^\w]*use[^\w]+(\w+)[^\w]*?\%\]/gi) { + $plugins{loaded}->{$1} = 1; + } + + while ($line =~ m/\[\%[^\w]*(\w+)\.\w+\(/g) { + my $plugin = $1; + $plugins{needed}->{$plugin} = 1 if (first { $_ eq $plugin } qw(HTML LxERP JavaScript MultiColumnIterator)); + } + + while ($line =~ m/\[\% # Template-Start-Tag + [\-~#] # Whitespace-Unterdrückung + \s* # Optional beliebig viele Whitespace + [\'\"] # Anfang des zu übersetzenden Strings + (.*?) # Der zu übersetzende String + [\'\"] # Ende des zu übersetzenden Strings + \s*\|\s* # Pipe-Zeichen mit optionalen Whitespace davor und danach + \$T8 # Filteraufruf + .*? # Optionale Argumente für den Filter und Whitespaces + [\-~#] # Whitespace-Unterdrückung + \%\] # Template-Ende-Tag + /ix) { + print "Found filter >>>$1<<<\n"; + $cached{$_[0]}{all}{$1} = 1; + $cached{$_[0]}{html}{$1} = 1; + $plugins{needed}->{T8} = 1; + substr $line, $-[1], $+[0] - $-[0], ''; + } + while ("" ne $line) { if (!$copying) { if ($line =~ m||i) { @@ -478,7 +596,7 @@ sub scanhtmlfile { substr($line, 0, $+[0]) = ""; $text =~ s/\s+/ /g; - $copying = 0; + $copying = 0; if ($issubmit) { # $submit{$text} = 1; $cached{$_[0]}{submit}{$text} = 1; @@ -499,13 +617,19 @@ sub scanhtmlfile { } close(IN); + + foreach my $plugin (keys %{ $plugins{needed} }) { + next if ($plugins{loaded}->{$plugin}); + print "E: " . strip_base($_[0]) . " requires the Template plugin '$plugin', but is not loaded with '[\% USE $plugin \%]'.\n"; + } + &converthtmlfile($_[0]); } # copy back into global arrays - map { $alllocales{$_} = 1 } keys %{$cached{$_[0]}{all}}; - map { $htmllocales{$_} = 1 } keys %{$cached{$_[0]}{html}}; - map { $submit{$_} = 1 } keys %{$cached{$_[0]}{submit}}; + map { $alllocales{$_} = 1 } keys %{$cached{$_[0]}{all}}; + map { $htmllocale{$_} = 1 } keys %{$cached{$_[0]}{html}}; + map { $submit{$_} = 1 } keys %{$cached{$_[0]}{submit}}; } sub converthtmlfile { @@ -551,7 +675,7 @@ sub converthtmlfile { $copying = 0; $alllocales{$text} = 1; $htmllocale{$text} = 1; - print(OUT $self{"texts"}{$text} || $text); + print(OUT $self->{"texts"}{$text} || $text); print(OUT "\n") if ("" eq $line); $text = ""; @@ -566,3 +690,95 @@ sub converthtmlfile { close(IN); close(OUT); } + +sub search_unused_htmlfiles { + my @unscanned_dirs = ('../../templates/webpages'); + + while (scalar @unscanned_dirs) { + my $dir = shift @unscanned_dirs; + + foreach my $entry (<$dir/*>) { + if (-d $entry) { + push @unscanned_dirs, $entry; + + } elsif (($entry =~ /_master.html$/) && -f $entry && !$referenced_html_files{$entry}) { + print "W: unused HTML template: " . strip_base($entry) . "\n"; + + } + } + } +} + +sub search_translated_htmlfiles_wo_master { + my @unscanned_dirs = ('../../templates/webpages'); + + while (scalar @unscanned_dirs) { + my $dir = shift @unscanned_dirs; + + foreach my $entry (<$dir/*>) { + if (-d $entry) { + push @unscanned_dirs, $entry; + + } elsif (($entry =~ /_[a-z]+\.html$/) && ($entry !~ /_master.html$/) && -f $entry) { + my $master = $entry; + $master =~ s/[a-z]+\.html$/master.html/; + if (! -f $master) { + print "W: translated HTML template without master: " . strip_base($entry) . "\n"; + } + } + } + } +} + +sub strip_base { + my $s = "$_[0]"; # Create a copy of the string. + + $s =~ s|^../../||; + $s =~ s|templates/webpages/||; + + return $s; +} + +__END__ + +=head1 NAME + +locales.pl - Collect strings for translation in Lx-Office + +=head1 SYNOPSIS + +locales.pl [options] + + Options: + -n, --no-custom-files Do not process files whose name contains "_" + -c, --check-files Run extended checks on HTML files + -v, --verbose Be more verbose + -h, --help Show this help + +=head1 OPTIONS + +=over 8 + +=item B<-n>, B<--no-custom-files> + +Do not process files whose name contains "_", e.g. "custom_io.pl". + +=item B<-c>, B<--check-files> + +Run extended checks on the usage of templates. This can be used to +discover HTML templates that are never used as well as the usage of +non-existing HTML templates. + +=item B<-v>, B<--verbose> + +Be more verbose. + +=back + +=head1 DESCRIPTION + +This script collects strings from Perl files, the menu.ini file and +HTML templates and puts them into the file "all" for translation. It +also distributes those translations back to the individual files. + +=cut