]> scripts.mit.edu Git - www/ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
po: use rescan hook instead of rebuilding twice.
[www/ikiwiki.git] / IkiWiki / Plugin / po.pm
index 9cb047992e724d88eb6d68a339c3e06d435c14ec..519b6d12cb33f29601b92a286a009dee1428dba5 100644 (file)
@@ -28,7 +28,7 @@ use UNIVERSAL;
 my %translations;
 my @origneedsbuild;
 my %origsubs;
-my @slavelanguages; # orderer as in config po_slave_languages
+my @slavelanguages; # language codes ordered as in config po_slave_languages
 
 memoize("istranslatable");
 memoize("_istranslation");
@@ -39,6 +39,7 @@ sub import {
        hook(type => "checkconfig", id => "po", call => \&checkconfig);
        hook(type => "needsbuild", id => "po", call => \&needsbuild);
        hook(type => "scan", id => "po", call => \&scan, last => 1);
+       hook(type => "rescan", id => "po", call => \&rescan);
        hook(type => "filter", id => "po", call => \&filter);
        hook(type => "htmlize", id => "po", call => \&htmlize);
        hook(type => "pagetemplate", id => "po", call => \&pagetemplate, last => 1);
@@ -106,9 +107,9 @@ sub getsetup () {
                po_slave_languages => {
                        type => "string",
                        example => [
-                               'fr' => 'Français',
-                               'es' => 'Español',
-                               'de' => 'Deutsch'
+                               'fr|Français',
+                               'es|Español',
+                               'de|Deutsch'
                        ],
                        description => "slave languages (PO files)",
                        safe => 1,
@@ -141,24 +142,30 @@ sub checkconfig () {
 
        if (ref $config{po_slave_languages} eq 'ARRAY') {
                my %slaves;
-               for (my $i=0; $i<@{$config{po_slave_languages}}; $i = $i + 2) {
-                       $slaves{$config{po_slave_languages}->[$i]} = $config{po_slave_languages}->[$i + 1];
-                       push @slavelanguages, $config{po_slave_languages}->[$i];
-                }
+               foreach my $pair (@{$config{po_slave_languages}}) {
+                       my ($code, $name) = ( $pair =~ /^([a-z]{2})\|(.+)$/ );
+                       if (!defined $code || !defined $name) {
+                               error(sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
+                                             $pair));
+                       }
+                       $slaves{$code} = $name;
+                       push @slavelanguages, $code;
+
+               }
                $config{po_slave_languages} = \%slaves;
-        }
+       }
        elsif (ref $config{po_slave_languages} eq 'HASH') {
                @slavelanguages = sort {
                        $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b};
                } keys %{$config{po_slave_languages}};
-        }
+       }
 
        delete $config{po_slave_languages}{$config{po_master_language}{code}};;
 
        map {
                islanguagecode($_)
                        or error(sprintf(gettext("%s is not a valid language code"), $_));
-       } ($config{po_master_language}{code}, keys %{$config{po_slave_languages}});
+       } ($config{po_master_language}{code}, @slavelanguages);
 
        if (! exists $config{po_translatable_pages} ||
            ! defined $config{po_translatable_pages}) {
@@ -187,7 +194,7 @@ sub checkconfig () {
                next if $underlay=~/^locale\//;
 
                # Underlays containing the po files for slave languages.
-               foreach my $ll (keys %{$config{po_slave_languages}}) {
+               foreach my $ll (@slavelanguages) {
                        add_underlay("po/$ll/$underlay")
                                if -d "$config{underlaydirbase}/po/$ll/$underlay";
                }
@@ -266,6 +273,27 @@ sub filter (@) {
        return $content;
 }
 
+# re-run the scan hooks and run the preprocess ones in scan
+# mode on the po-to-markup converted content
+sub rescan (@) {
+       my %params=@_;
+       my $page=$params{page};
+       my $content=$params{content};
+
+       return unless exists $config{rebuild} && $config{rebuild};
+       return unless istranslation($page);
+
+       $content = po_to_markup($page, $content);
+       require IkiWiki;
+       IkiWiki::run_hooks(scan => sub {
+               shift->(
+                       page => $page,
+                       content => $content,
+               );
+       });
+       IkiWiki::preprocess($page, $page, $content, 1);
+}
+
 sub htmlize (@) {
        my %params=@_;
 
@@ -378,41 +406,6 @@ sub mydelete (@) {
 sub change (@) {
        my @rendered=@_;
 
-       # All meta titles are first extracted at scan time, i.e. before we turn
-       # PO files back into translated markdown; escaping of double-quotes in
-       # PO files breaks the meta plugin's parsing enough to save ugly titles
-       # to %pagestate at this time.
-       #
-       # Then, at render time, every page passes in turn through the Great
-       # Rendering Chain (filter->preprocess->linkify->htmlize), and the meta
-       # plugin's preprocess hook is this time in a position to correctly
-       # extract the titles from slave pages.
-       #
-       # This is, unfortunately, too late: if the page A, linking to the page
-       # B, is rendered before B, it will display the wrongly-extracted meta
-       # title as the link text to B.
-       #
-       # On the one hand, such a corner case only happens on rebuild: on
-       # refresh, every rendered page is fixed to contain correct meta titles.
-       # On the other hand, it can take some time to get every page fixed.
-       # We therefore re-render every rendered page after a rebuild to fix them
-       # at once. As this more or less doubles the time needed to rebuild the
-       # wiki, we do so only when really needed.
-
-       if (@rendered
-           && exists $config{rebuild} && defined $config{rebuild} && $config{rebuild}
-           && UNIVERSAL::can("IkiWiki::Plugin::meta", "getsetup")
-           && exists $config{meta_overrides_page_title}
-           && defined $config{meta_overrides_page_title}
-           && $config{meta_overrides_page_title}) {
-               debug(sprintf(gettext("rebuilding all pages to fix meta titles")));
-               resetalreadyfiltered();
-               require IkiWiki::Render;
-               foreach my $file (@rendered) {
-                       IkiWiki::render($file, sprintf(gettext("building %s"), $file));
-               }
-       }
-
        my $updated_po_files=0;
 
        # Refresh/create POT and PO files as needed.
@@ -552,7 +545,7 @@ sub formbuilder (@) {
        # This cannot be done in the formbuilder_setup hook as the list of types is
        # computed later.
        if ($form->field("do") eq "create") {
-               foreach my $field ($form->field) {
+               foreach my $field ($form->field) {
                        next unless "$field" eq "type";
                        next unless $field->type eq 'select';
                        my $orig_value = $field->value;
@@ -609,7 +602,7 @@ sub mybeautify_urlpath ($) {
                $res =~ s!/\Qindex.$config{htmlext}\E$!/!;
                map {
                        $res =~ s!/\Qindex.$_.$config{htmlext}\E$!/!;
-               } (keys %{$config{po_slave_languages}});
+               } @slavelanguages;
        }
        return $res;
 }
@@ -700,7 +693,7 @@ sub myisselflink ($$) {
        return 1 if $origsubs{'isselflink'}->($page, $link);
        if (istranslation($page)) {
                return $origsubs{'isselflink'}->(masterpage($page), $link);
-        }
+       }
        return;
 }
 
@@ -856,7 +849,7 @@ sub otherlanguages_codes ($) {
 sub otherlanguages_pages ($) {
        my $page=shift;
 
-        my %ret;
+       my %ret;
        map {
                $ret{$_} = otherlanguage_page($page, $_)
        } @{otherlanguages_codes($page)};
@@ -884,7 +877,7 @@ sub pofile ($$) {
 sub pofiles ($) {
        my $masterfile=shift;
 
-       return map pofile($masterfile, $_), (keys %{$config{po_slave_languages}});
+       return map pofile($masterfile, $_), @slavelanguages;
 }
 
 sub refreshpot ($) {
@@ -1042,7 +1035,7 @@ sub ishomepage ($) {
        my $page = shift;
 
        return 1 if $page eq 'index';
-       map { return 1 if $page eq 'index.'.$_ } keys %{$config{po_slave_languages}};
+       map { return 1 if $page eq 'index.'.$_ } @slavelanguages;
        return undef;
 }
 
@@ -1057,7 +1050,7 @@ sub deletetranslations ($) {
                if (-e $absfile && ! -l $absfile && ! -d $absfile) {
                        push @todelete, $file;
                }
-       } keys %{$config{po_slave_languages}};
+       } @slavelanguages;
 
        map {
                if ($config{rcs}) {
@@ -1188,7 +1181,7 @@ sub isvalidpo ($) {
        unlink $infile;
 
        if ($res) {
-           return IkiWiki::SuccessReason->new("valid gettext data");
+               return IkiWiki::SuccessReason->new("valid gettext data");
        }
        return IkiWiki::FailReason->new(gettext("invalid gettext data, go back ".
                                        "to previous page to continue edit"));
@@ -1200,7 +1193,7 @@ sub po4a_type ($) {
        my $pagetype = pagetype($file);
        if ($pagetype eq 'html') {
                return 'xhtml';
-        }
+       }
        return 'text';
 }
 
@@ -1214,13 +1207,13 @@ sub po4a_options($) {
                # how to disable options is not consistent across po4a modules
                $options{includessi} = '';
                $options{includeexternal} = 0;
-        }
+       }
        elsif ($pagetype eq 'mdwn') {
                $options{markdown} = 1;
-        }
-        else {
+       }
+       else {
                $options{markdown} = 0;
-        }
+       }
 
        return %options;
 }
@@ -1295,11 +1288,11 @@ sub match_needstranslation ($$;@) {
                }
                elsif ($wanted > 100) {
                        return IkiWiki::FailReason->new("parameter is greater than 100");
-                }
-        }
-        else {
+               }
+       }
+       else {
                $wanted=100;
-        }
+       }
 
        my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page);
        if ($percenttranslated eq 'N/A') {
@@ -1307,7 +1300,7 @@ sub match_needstranslation ($$;@) {
        }
        elsif ($percenttranslated < $wanted) {
                return IkiWiki::SuccessReason->new("file has $percenttranslated translated");
-        }
+       }
        else {
                return IkiWiki::FailReason->new("file is translated enough");
        }