From: Joey Hess Date: Mon, 30 Aug 2010 18:47:57 +0000 (-0400) Subject: Merge remote branch 'intrigeri/po' X-Git-Tag: 3.20100831~33 X-Git-Url: http://git.tremily.us/?p=ikiwiki.git;a=commitdiff_plain;h=931036eb5c2a26dd0f4bae1c6d9003b65ad890ff;hp=67ac2bad74e42cb3dec564fb40a198688b2e358e Merge remote branch 'intrigeri/po' --- diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 6395ebdc2..f3530faf3 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -223,38 +223,61 @@ sub 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, @@ -384,41 +407,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. @@ -597,7 +585,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"))) { @@ -778,6 +766,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; @@ -854,7 +851,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; } diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index a57a2c8fe..341d67867 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -255,7 +255,7 @@ sub genwrapper () { debug("skeleton plugin running in genwrapper"); } -sub savestate () { +sub disable () { debug("skeleton plugin running in disable"); } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index a653ab2da..9921915b4 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -174,15 +174,15 @@ sub scan ($) { } delete $typedlinks{$page}; + # Preprocess in scan-only mode. + preprocess($page, $page, $content, 1); + run_hooks(scan => sub { shift->( page => $page, content => $content, ); }); - - # Preprocess in scan-only mode. - preprocess($page, $page, $content, 1); } else { will_render($file, $file, 1); diff --git a/t/po.t b/t/po.t index 1cd18c317..51321fa96 100755 --- a/t/po.t +++ b/t/po.t @@ -17,7 +17,7 @@ BEGIN { } } -use Test::More tests => 68; +use Test::More tests => 91; BEGIN { use_ok("IkiWiki"); } @@ -45,6 +45,7 @@ $config{po_slave_languages} = { $config{po_translatable_pages}='index or test1 or test2 or translatable'; $config{po_link_to}='negotiated'; IkiWiki::loadplugins(); +ok(IkiWiki::loadplugin('meta'), "meta plugin loaded"); ok(IkiWiki::loadplugin('po'), "po plugin loaded"); IkiWiki::checkconfig(); @@ -53,6 +54,7 @@ $pagesources{'index'}='index.mdwn'; $pagesources{'index.fr'}='index.fr.po'; $pagesources{'index.es'}='index.es.po'; $pagesources{'test1'}='test1.mdwn'; +$pagesources{'test1.es'}='test1.es.po'; $pagesources{'test1.fr'}='test1.fr.po'; $pagesources{'test2'}='test2.mdwn'; $pagesources{'test2.es'}='test2.es.po'; @@ -68,8 +70,10 @@ foreach my $page (keys %pagesources) { } ### populate srcdir -writefile('index.mdwn', $config{srcdir}, '[[translatable]] [[nontranslatable]]'); -writefile('test1.mdwn', $config{srcdir}, 'test1 content'); +writefile('index.mdwn', $config{srcdir}, + "[[!meta title=\"index title\"]]\n[[translatable]] [[nontranslatable]]"); +writefile('test1.mdwn', $config{srcdir}, + "[[!meta title=\"test1 title\"]]\ntest1 content"); writefile('test2.mdwn', $config{srcdir}, 'test2 content'); writefile('test3.mdwn', $config{srcdir}, 'test3 content'); writefile('translatable.mdwn', $config{srcdir}, '[[nontranslatable]]'); @@ -88,6 +92,9 @@ ok(! IkiWiki::Plugin::po::istranslation('index'), "index is not a translation"); ok(IkiWiki::Plugin::po::istranslation('index.fr'), "index.fr is a translation"); ok(IkiWiki::Plugin::po::istranslation('index.es'), "index.es is a translation"); ok(IkiWiki::Plugin::po::istranslation('/index.fr'), "/index.fr is a translation"); +ok(IkiWiki::Plugin::po::istranslatable('test1'), "test1 is translatable"); +ok(IkiWiki::Plugin::po::istranslation('test1.es'), "test1.es is a translation"); +ok(IkiWiki::Plugin::po::istranslation('test1.fr'), "test1.fr is a translation"); ok(IkiWiki::Plugin::po::istranslatable('test2'), "test2 is translatable"); ok(! IkiWiki::Plugin::po::istranslation('test2'), "test2 is not a translation"); ok(! IkiWiki::Plugin::po::istranslatable('test3'), "test3 is not translatable"); @@ -185,3 +192,25 @@ $msgprefix="beautify_urlpath (po_link_to=negotiated)"; is(IkiWiki::beautify_urlpath('test1/index.html'), './test1/', "$msgprefix test1/index.html"); is(IkiWiki::beautify_urlpath('test1/index.en.html'), './test1/', "$msgprefix test1/index.en.html"); is(IkiWiki::beautify_urlpath('test1/index.fr.html'), './test1/', "$msgprefix test1/index.fr.html"); + +### re-scan +refresh_n_scan('index.mdwn'); +is($pagestate{'index'}{meta}{title}, 'index title'); +is($pagestate{'index.es'}{meta}{title}, 'index title'); +is($pagestate{'index.fr'}{meta}{title}, 'index title'); +refresh_n_scan('test1.mdwn'); +is($pagestate{'test1'}{meta}{title}, 'test1 title'); +is($pagestate{'test1.es'}{meta}{title}, 'test1 title'); +is($pagestate{'test1.fr'}{meta}{title}, 'test1 title'); + +### istranslatedto +ok(IkiWiki::Plugin::po::istranslatedto('index', 'es')); +ok(IkiWiki::Plugin::po::istranslatedto('index', 'fr')); +ok(! IkiWiki::Plugin::po::istranslatedto('index', 'cz')); +ok(IkiWiki::Plugin::po::istranslatedto('test1', 'es')); +ok(IkiWiki::Plugin::po::istranslatedto('test1', 'fr')); +ok(! IkiWiki::Plugin::po::istranslatedto('test1', 'cz')); +ok(! IkiWiki::Plugin::po::istranslatedto('nontranslatable', 'es')); +ok(! IkiWiki::Plugin::po::istranslatedto('nontranslatable', 'cz')); +ok(! IkiWiki::Plugin::po::istranslatedto('test1.es', 'fr')); +ok(! IkiWiki::Plugin::po::istranslatedto('test1.fr', 'es'));