]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
po: s/utf-8/UTF-8, to solve part of the double commit bug.
[ikiwiki.git] / IkiWiki / Plugin / po.pm
index 14c7318feff935209e85e317039f0cee70fe620d..e85c9d760efd5782ea218c11ec398c8eeda74c73 100644 (file)
@@ -51,16 +51,20 @@ sub import {
        hook(type => "formbuilder_setup", id => "po", call => \&formbuilder_setup, last => 1);
        hook(type => "formbuilder", id => "po", call => \&formbuilder);
 
-       $origsubs{'beautify_urlpath'}=\&IkiWiki::beautify_urlpath;
-       inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath);
-       $origsubs{'targetpage'}=\&IkiWiki::targetpage;
-       inject(name => "IkiWiki::targetpage", call => \&mytargetpage);
-       $origsubs{'urlto'}=\&IkiWiki::urlto;
-       inject(name => "IkiWiki::urlto", call => \&myurlto);
-       $origsubs{'cgiurl'}=\&IkiWiki::cgiurl;
-       inject(name => "IkiWiki::cgiurl", call => \&mycgiurl);
-       $origsubs{'rootpage'}=\&IkiWiki::rootpage;
-       inject(name => "IkiWiki::rootpage", call => \&myrootpage);
+       if (! %origsubs) {
+               $origsubs{'bestlink'}=\&IkiWiki::bestlink;
+               inject(name => "IkiWiki::bestlink", call => \&mybestlink);
+               $origsubs{'beautify_urlpath'}=\&IkiWiki::beautify_urlpath;
+               inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath);
+               $origsubs{'targetpage'}=\&IkiWiki::targetpage;
+               inject(name => "IkiWiki::targetpage", call => \&mytargetpage);
+               $origsubs{'urlto'}=\&IkiWiki::urlto;
+               inject(name => "IkiWiki::urlto", call => \&myurlto);
+               $origsubs{'cgiurl'}=\&IkiWiki::cgiurl;
+               inject(name => "IkiWiki::cgiurl", call => \&mycgiurl);
+               $origsubs{'rootpage'}=\&IkiWiki::rootpage;
+               inject(name => "IkiWiki::rootpage", call => \&myrootpage);
+       }
 }
 
 
@@ -83,7 +87,8 @@ sub getsetup () {
        return
                plugin => {
                        safe => 0,
-                       rebuild => 1,
+                       rebuild => 1, # format plugin
+                       section => "format",
                },
                po_master_language => {
                        type => "string",
@@ -130,6 +135,7 @@ sub checkconfig () {
                                      $field, 'po'));
                }
        }
+       delete $config{po_slave_languages}{$config{po_master_language}{code}};;
 
        map {
                islanguagecode($_)
@@ -153,10 +159,6 @@ sub checkconfig () {
                warn(gettext('po_link_to=negotiated requires usedirs to be enabled, falling back to po_link_to=default'));
                $config{po_link_to}='default';
        }
-       unless ($config{po_link_to} eq 'default') {
-               $origsubs{'bestlink'}=\&IkiWiki::bestlink;
-               inject(name => "IkiWiki::bestlink", call => \&mybestlink);
-       }
 
        push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/;
 
@@ -175,7 +177,8 @@ sub checkconfig () {
                if ($config{po_master_language}{code} ne 'en') {
                        # Add underlay containing translated source files
                        # for the master language.
-                       add_underlay("locale/$config{po_master_language}{code}/$underlay");
+                       add_underlay("locale/$config{po_master_language}{code}/$underlay")
+                               if -d "$config{underlaydirbase}/locale/$config{po_master_language}{code}/$underlay";
                }
        }
 }
@@ -309,7 +312,7 @@ sub pagetemplate (@) {
        if (ishomepage($page) && $template->query(name => "title")) {
                $template->param(title => $config{wikiname});
        }
-} # }}}
+}
 
 # Add the renamed page translations to the list of to-be-renamed pages.
 sub renamepages (@) {
@@ -388,31 +391,32 @@ sub change (@) {
                resetalreadyfiltered();
                require IkiWiki::Render;
                foreach my $file (@rendered) {
-                       debug(sprintf(gettext("building %s"), $file));
-                       IkiWiki::render($file);
+                       IkiWiki::render($file, sprintf(gettext("building %s"), $file));
                }
        }
 
        my $updated_po_files=0;
 
        # Refresh/create POT and PO files as needed.
-       # (But avoid doing so if they are in an underlay directory.)
        foreach my $file (grep {istranslatablefile($_)} @rendered) {
                my $masterfile=srcfile($file);
                my $page=pagename($file);
                my $updated_pot_file=0;
+
+               # Avoid touching underlay files.
+               next if $masterfile ne "$config{srcdir}/$file";
+
                # Only refresh POT file if it does not exist, or if
-               # $pagesources{$page} was changed: don't if only the HTML was
+               # the source was changed: don't if only the HTML was
                # refreshed, e.g. because of a dependency.
-               if ($masterfile eq "$config{srcdir}/$file" &&
-                  ((grep { $_ eq $pagesources{$page} } @origneedsbuild)
-                   || ! -e potfile($masterfile))) {
+               if ((grep { $_ eq $pagesources{$page} } @origneedsbuild) ||
+                   ! -e potfile($masterfile)) {
                        refreshpot($masterfile);
                        $updated_pot_file=1;
                }
                my @pofiles;
                foreach my $po (pofiles($masterfile)) {
-                       next if ! $updated_pot_file && -e $po;
+                       next if ! $updated_pot_file && -e $po;
                        next if grep { $po=~/\Q$_\E/ } @{$config{underlaydirs}};
                        push @pofiles, $po;
                }
@@ -425,8 +429,7 @@ sub change (@) {
 
        if ($updated_po_files) {
                commit_and_refresh(
-                       gettext("updated PO files"),
-                       "IkiWiki::Plugin::po::change");
+                       gettext("updated PO files"));
        }
 }
 
@@ -560,15 +563,20 @@ sub formbuilder (@) {
 # `----
 
 # Implement po_link_to 'current' and 'negotiated' settings.
-# Not injected otherwise.
 sub mybestlink ($$) {
        my $page=shift;
        my $link=shift;
 
+       return $origsubs{'bestlink'}->($page, $link)
+               if defined $config{po_link_to} && $config{po_link_to} eq "default";
+
        my $res=$origsubs{'bestlink'}->(masterpage($page), $link);
+       my @caller = caller(1);
        if (length $res
            && istranslatable($res)
-           && istranslation($page)) {
+           && istranslation($page)
+           &&  !(exists $caller[3] && defined $caller[3]
+                 && ($caller[3] eq "IkiWiki::PageSpec::match_link"))) {
                return $res . "." . lang($page);
        }
        return $res;
@@ -578,7 +586,7 @@ sub mybeautify_urlpath ($) {
        my $url=shift;
 
        my $res=$origsubs{'beautify_urlpath'}->($url);
-       if ($config{po_link_to} eq "negotiated") {
+       if (defined $config{po_link_to} && $config{po_link_to} eq "negotiated") {
                $res =~ s!/\Qindex.$config{po_master_language}{code}.$config{htmlext}\E$!/!;
                $res =~ s!/\Qindex.$config{htmlext}\E$!/!;
                map {
@@ -722,6 +730,7 @@ sub istranslatablefile ($) {
        my $type=pagetype($file);
        return 0 if ! defined $type || $type eq 'po';
        return 0 if $file =~ /\.pot$/;
+       return 0 if ! defined $config{po_translatable_pages};
        return 1 if pagespec_match(pagename($file), $config{po_translatable_pages});
        return;
 }
@@ -842,15 +851,15 @@ sub refreshpot ($) {
        my %options = ("markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0);
        my $doc=Locale::Po4a::Chooser::new('text',%options);
        $doc->{TT}{utf_mode} = 1;
-       $doc->{TT}{file_in_charset} = 'utf-8';
-       $doc->{TT}{file_out_charset} = 'utf-8';
+       $doc->{TT}{file_in_charset} = 'UTF-8';
+       $doc->{TT}{file_out_charset} = 'UTF-8';
        $doc->read($masterfile);
        # let's cheat a bit to force porefs option to be passed to
        # Locale::Po4a::Po; this is undocument use of internal
        # Locale::Po4a::TransTractor's data, compulsory since this module
        # prevents us from using the porefs option.
        $doc->{TT}{po_out}=Locale::Po4a::Po->new({ 'porefs' => 'none' });
-       $doc->{TT}{po_out}->set_charset('utf-8');
+       $doc->{TT}{po_out}->set_charset('UTF-8');
        # do the actual work
        $doc->parse;
        IkiWiki::prep_writefile(basename($potfile),dirname($potfile));
@@ -938,8 +947,8 @@ sub percenttranslated ($) {
        $doc->process(
                'po_in_name'    => [ $file ],
                'file_in_name'  => [ $masterfile ],
-               'file_in_charset'  => 'utf-8',
-               'file_out_charset' => 'utf-8',
+               'file_in_charset'  => 'UTF-8',
+               'file_out_charset' => 'UTF-8',
        ) or error("po(percenttranslated) ".
                   sprintf(gettext("failed to translate %s"), $page));
        my ($percent,$hit,$queries) = $doc->stats();
@@ -1025,17 +1034,18 @@ sub deletetranslations ($) {
 
        if (@todelete) {
                commit_and_refresh(
-                       gettext("removed obsolete PO files"),
-                       "IkiWiki::Plugin::po::deletetranslations");
+                       gettext("removed obsolete PO files"));
        }
 }
 
-sub commit_and_refresh ($$) {
-       my ($msg, $author) = (shift, shift);
+sub commit_and_refresh ($) {
+       my $msg = shift;
 
        if ($config{rcs}) {
                IkiWiki::disable_commit_hook();
-               IkiWiki::rcs_commit_staged($msg, $author, "127.0.0.1");
+               IkiWiki::rcs_commit_staged(
+                       message => $msg,
+               );
                IkiWiki::enable_commit_hook();
                IkiWiki::rcs_update();
        }
@@ -1053,11 +1063,8 @@ sub commit_and_refresh ($$) {
        IkiWiki::saveindex();
 }
 
-# on success, returns the filtered content.
-# on error, if $nonfatal, warn and return undef; else, error out.
-sub po_to_markup ($$;$) {
+sub po_to_markup ($$) {
        my ($page, $content) = (shift, shift);
-       my $nonfatal = shift;
 
        $content = '' unless defined $content;
        $content = decode_utf8(encode_utf8($content));
@@ -1080,10 +1087,6 @@ sub po_to_markup ($$;$) {
 
        my $fail = sub ($) {
                my $msg = "po(po_to_markup) - $page : " . shift;
-               if ($nonfatal) {
-                       warn $msg;
-                       return undef;
-               }
                error($msg, sub { unlink $infile, $outfile});
        };
 
@@ -1098,14 +1101,13 @@ sub po_to_markup ($$;$) {
        $doc->process(
                'po_in_name'    => [ $infile ],
                'file_in_name'  => [ $masterfile ],
-               'file_in_charset'  => 'utf-8',
-               'file_out_charset' => 'utf-8',
+               'file_in_charset'  => 'UTF-8',
+               'file_out_charset' => 'UTF-8',
        ) or return $fail->(gettext("failed to translate"));
        $doc->write($outfile)
                or return $fail->(sprintf(gettext("failed to write %s"), $outfile));
 
-       $content = readfile($outfile)
-               or return $fail->(sprintf(gettext("failed to read %s"), $outfile));
+       $content = readfile($outfile);
 
        # Unlinking should happen automatically, thanks to File::Temp,
        # but it does not work here, probably because of the way writefile()
@@ -1218,4 +1220,19 @@ sub match_currentlang ($$;@) {
        }
 }
 
+sub match_needstranslation ($$;@) {
+       my $page=shift;
+
+       my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page);
+       if ($percenttranslated eq 'N/A') {
+               return IkiWiki::FailReason->new("file is not a translatable page");
+       }
+       elsif ($percenttranslated < 100) {
+               return IkiWiki::SuccessReason->new("file has $percenttranslated translated");
+        }
+       else {
+               return IkiWiki::FailReason->new("file is fully translated");
+       }
+}
+
 1