]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
needsbuild hook interface changed; the hooks should now return the modified array...
[ikiwiki.git] / IkiWiki / Plugin / po.pm
index 519b6d12cb33f29601b92a286a009dee1428dba5..7b62092e1bf2071af4351499ce3bfadb39df10de 100644 (file)
@@ -39,7 +39,6 @@ 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);
@@ -222,40 +221,65 @@ sub needsbuild () {
        foreach my $master (keys %translations) {
                map add_depends($_, $master), values %{otherlanguages_pages($master)};
        }
+
+       return $needsbuild;
 }
 
-# Massage the recorded state of internal links so that:
-# - it matches the actually generated links, rather than the links as written
-#   in the pages' source
-# - backlinks are consistent in all cases
 sub scan (@) {
        my %params=@_;
        my $page=$params{page};
        my $content=$params{content};
-
-       if (istranslation($page)) {
-               foreach my $destpage (@{$links{$page}}) {
-                       if (istranslatable($destpage)) {
-                               # replace the occurence of $destpage in $links{$page}
-                               for (my $i=0; $i<@{$links{$page}}; $i++) {
-                                       if (@{$links{$page}}[$i] eq $destpage) {
-                                               @{$links{$page}}[$i] = $destpage . '.' . lang($page);
-                                               last;
-                                       }
-                               }
+       my $run_by_po=$params{run_by_po};
+
+       # Massage the recorded state of internal links so that:
+       # - it matches the actually generated links, rather than the links as
+       #   written in the pages' source
+       # - backlinks are consistent in all cases
+
+       # A second scan pass is made over translation pages, so as an
+       # optimization, we only do so on the second pass in this case,
+       # i.e. when this hook is called by itself.
+       if ($run_by_po && istranslation($page)) {
+               # replace the occurence of $destpage in $links{$page}
+               my @orig_links = @{$links{$page}};
+               $links{$page} = [];
+               foreach my $destpage (@orig_links) {
+                       if (istranslatedto($destpage, lang($page))) {
+                               add_link($page, $destpage . '.' . lang($page));
+                       }
+                       else {
+                               add_link($page, $destpage);
                        }
                }
        }
-       elsif (! istranslatable($page) && ! istranslation($page)) {
+       # No second scan pass is done for a non-translation page, so
+       # links massaging must happen on first pass in this case.
+       elsif (! $run_by_po && ! istranslatable($page) && ! istranslation($page)) {
                foreach my $destpage (@{$links{$page}}) {
                        if (istranslatable($destpage)) {
                                # make sure any destpage's translations has
                                # $page in its backlinks
-                               push @{$links{$page}},
-                                       values %{otherlanguages_pages($destpage)};
+                               foreach my $link (values %{otherlanguages_pages($destpage)}) {
+                                       add_link($page, $link);
+                               }
                        }
                }
        }
+
+       # Re-run the preprocess hooks in scan mode, then the scan hooks,
+       # over the po-to-markup converted content
+       return if $run_by_po; # avoid looping endlessly
+       return unless istranslation($page);
+       $content = po_to_markup($page, $content);
+       require IkiWiki;
+       IkiWiki::preprocess($page, $page, $content, 1);
+       IkiWiki::run_hooks(scan => sub {
+               shift->(
+                       page => $page,
+                       content => $content,
+                       run_by_po => 1,
+               );
+       });
 }
 
 # We use filter to convert PO to the master page's format,
@@ -273,27 +297,6 @@ 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=@_;
 
@@ -584,7 +587,7 @@ sub mybestlink ($$) {
        my $res=$origsubs{'bestlink'}->(masterpage($page), $link);
        my @caller = caller(1);
        if (length $res
-           && istranslatable($res)
+           && istranslatedto($res, lang($page))
            && istranslation($page)
            &&  !(exists $caller[3] && defined $caller[3]
                  && ($caller[3] eq "IkiWiki::PageSpec::match_link"))) {
@@ -765,6 +768,15 @@ sub istranslatable ($) {
        return;
 }
 
+sub istranslatedto ($$) {
+       my $page=shift;
+       my $destlang = shift;
+
+       $page=~s#^/##;
+       return 0 unless istranslatable($page);
+       exists $pagesources{otherlanguage_page($page, $destlang)};
+}
+
 sub _istranslation ($) {
        my $page=shift;
 
@@ -841,7 +853,10 @@ sub otherlanguages_codes ($) {
        foreach my $lang
                ($config{po_master_language}{code}, @slavelanguages) {
                next if $lang eq $curlang;
-               push @ret, $lang;
+               if ($lang eq $config{po_master_language}{code} ||
+                   istranslatedto(masterpage($page), $lang)) {
+                       push @ret, $lang;
+               }
        }
        return \@ret;
 }