use IkiWiki 2.00;
use Encode;
use Locale::Po4a::Chooser;
+use Locale::Po4a::Po;
use File::Basename;
use File::Copy;
use File::Spec;
use Memoize;
my %translations;
-memoize("istranslatable");
+our %filtered;
+
+## FIXME: makes some test cases cry once every two tries; this may be
+## related to the artificial way the testsuite is run, or not.
+# memoize("istranslatable");
memoize("_istranslation");
memoize("percenttranslated");
+# backup references to subs that will be overriden
+my %origsubs;
+$origsubs{'bestlink'}=\&IkiWiki::bestlink;
+$origsubs{'beautify_urlpath'}=\&IkiWiki::beautify_urlpath;
+$origsubs{'targetpage'}=\&IkiWiki::targetpage;
+
sub import {
hook(type => "getsetup", id => "po", call => \&getsetup);
hook(type => "checkconfig", id => "po", call => \&checkconfig);
hook(type => "needsbuild", id => "po", call => \&needsbuild);
- hook(type => "targetpage", id => "po", call => \&targetpage);
- hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath);
- hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink);
hook(type => "filter", id => "po", call => \&filter);
hook(type => "htmlize", id => "po", call => \&htmlize);
hook(type => "pagetemplate", id => "po", call => \&pagetemplate);
+ inject(name => "IkiWiki::bestlink", call => \&mybestlink);
+ inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath);
+ inject(name => "IkiWiki::targetpage", call => \&mytargetpage);
}
sub getsetup () { #{{{
'name' => 'English'
},
description => "master language (non-PO files)",
- safe => 1,
+ safe => 0,
rebuild => 1,
},
po_slave_languages => {
'de' => 'Deutsch'
},
description => "slave languages (PO files)",
- safe => 1,
+ safe => 0,
rebuild => 1,
},
po_translatable_pages => {
example => "!*/Discussion",
description => "PageSpec controlling which pages are translatable",
link => "ikiwiki/PageSpec",
- safe => 1,
+ safe => 0,
rebuild => 1,
},
po_link_to => {
type => "string",
example => "current",
description => "internal linking behavior (default/current/negotiated)",
- safe => 1,
+ safe => 0,
rebuild => 1,
},
} #}}}
$doc->{TT}{utf_mode} = 1;
$doc->{TT}{file_in_charset} = 'utf-8';
$doc->{TT}{file_out_charset} = 'utf-8';
+ # 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.
+ my %po_options = ('porefs' => 'none');
+ $doc->{TT}{po_out}=Locale::Po4a::Po->new(\%po_options);
+ $doc->{TT}{po_out}->set_charset('utf-8');
+ # do the actual work
$doc->parse;
$doc->writepo($potfile);
} #}}}
foreach my $pofile (@pofiles) {
if (-e $pofile) {
- my $cmd = "msgmerge -U $pofile $potfile";
+ my $cmd = "msgmerge -U --backup=none $pofile $potfile";
system ($cmd) == 0
or error("[po/refreshpofiles:$pofile] failed to update");
}
}
# refresh/create POT and PO files as needed
+ my $updated_po_files=0;
foreach my $page (keys %pagesources) {
my $pageneedsbuild = grep { $_ eq $pagesources{$page} } @$needsbuild;
if (istranslatable($page)) {
push @pofiles, $pofile;
}
}
- refreshpofiles($file, @pofiles) if (@pofiles);
+ if (@pofiles) {
+ refreshpofiles($file, @pofiles) ;
+ map { IkiWiki::rcs_add($_); } @pofiles if ($config{rcs});
+ $updated_po_files = 1;
+ }
}
}
- # refresh %translations, using istranslation's side-effect
- # (not needed yet, but when newly created POT/PO files are
- # added to %pagesources and other data structures, we'll need
- # this)
- foreach my $page (keys %pagesources) {
- istranslation($page);
+ # check staged changes in and trigger a wiki refresh.
+ if ($updated_po_files) {
+ if ($config{rcs}) {
+ IkiWiki::disable_commit_hook();
+ IkiWiki::rcs_commit_staged(gettext("updated PO files"),
+ "refreshpofiles", "127.0.0.1");
+ IkiWiki::enable_commit_hook();
+ IkiWiki::rcs_update();
+ }
+ IkiWiki::refresh();
+ IkiWiki::saveindex();
+ # refresh module's private variables
+ undef %filtered;
+ undef %translations;
+ foreach my $page (keys %pagesources) {
+ istranslation($page);
+ }
}
+
# make existing translations depend on the corresponding master page
foreach my $master (keys %translations) {
foreach my $slave (values %{$translations{$master}}) {
}
} #}}}
-sub targetpage (@) { #{{{
- my %params = @_;
- my $page=$params{page};
- my $ext=$params{ext};
+sub mytargetpage ($$) { #{{{
+ my $page=shift;
+ my $ext=shift;
if (istranslation($page)) {
my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/);
- if (! $config{usedirs} || $page eq 'index') {
+ if (! $config{usedirs} || $masterpage eq 'index') {
return $masterpage . "." . $lang . "." . $ext;
}
else {
return $page . "/index." . $config{po_master_language}{code} . "." . $ext;
}
}
- return;
+ return $origsubs{'targetpage'}->($page, $ext);
} #}}}
-sub tweakurlpath ($) { #{{{
- my %params = @_;
- my $url=$params{url};
+sub mybeautify_urlpath ($) { #{{{
+ my $url=shift;
+ my $res=$origsubs{'beautify_urlpath'}->($url);
if ($config{po_link_to} eq "negotiated") {
- $url =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!;
+ $res =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!;
}
- return $url;
+ return $res;
} #}}}
-sub tweakbestlink ($$) { #{{{
- my %params = @_;
- my $page=$params{page};
- my $link=$params{link};
- if ($config{po_link_to} eq "current"
- && istranslatable($link)
- && istranslation($page)) {
- my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/);
- return $link . "." . $curlang;
+sub urlto_with_orig_beautiful_urlpath($$) { #{{{
+ my $to=shift;
+ my $from=shift;
+
+ inject(name => "IkiWiki::beautify_urlpath", call => $origsubs{'beautify_urlpath'});
+ my $res=urlto($to, $from);
+ inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath);
+
+ return $res;
+} #}}}
+
+sub mybestlink ($$) { #{{{
+ my $page=shift;
+ my $link=shift;
+ my $res=$origsubs{'bestlink'}->($page, $link);
+ if (length $res) {
+ if ($config{po_link_to} eq "current"
+ && istranslatable($res)
+ && istranslation($page)) {
+ my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/);
+ return $res . "." . $curlang;
+ }
+ else {
+ return $res;
+ }
}
- return $link;
+ return "";
} #}}}
-our %filtered;
# We use filter to convert PO to the master page's type,
# since other plugins should not work on PO files
sub filter (@) { #{{{
elsif (istranslation($page)) {
my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/);
push @ret, {
- url => urlto($masterpage, $page),
+ url => urlto_with_orig_beautiful_urlpath($masterpage, $page),
code => $config{po_master_language}{code},
language => $config{po_master_language}{name},
master => 1,
url => urlto($translations{$masterpage}{$lang}, $page),
code => $lang,
language => $config{po_slave_languages}{$lang},
- percent => percenttranslated($page),
+ percent => percenttranslated($translations{$masterpage}{$lang}),
} unless ($lang eq $curlang);
}
}
sub pagetemplate (@) { #{{{
my %params=@_;
my $page=$params{page};
+ my $destpage=$params{destpage};
my $template=$params{template};
if (istranslation($page) && $template->query(name => "percenttranslated")) {
$template->param(percenttranslated => percenttranslated($page));
}
+ if ($template->query(name => "istranslation")) {
+ $template->param(istranslation => istranslation($page));
+ }
+ if ($template->query(name => "istranslatable")) {
+ $template->param(istranslatable => istranslatable($page));
+ }
if ($template->query(name => "otherlanguages")) {
$template->param(otherlanguages => [otherlanguages($page)]);
+ if (istranslatable($page)) {
+ foreach my $translation (values %{$translations{$page}}) {
+ add_depends($page, $translation);
+ }
+ }
+ elsif (istranslation($page)) {
+ my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/);
+ add_depends($page, $masterpage);
+ foreach my $translation (values %{$translations{$masterpage}}) {
+ add_depends($page, $translation);
+ }
+ }
+ }
+ # Rely on IkiWiki::Render's genpage() to decide wether
+ # a discussion link should appear on $page; this is not
+ # totally accurate, though: some broken links may be generated
+ # when cgiurl is disabled.
+ # This compromise avoids some code duplication, and will probably
+ # prevent future breakage when ikiwiki internals change.
+ # Known limitations are preferred to future random bugs.
+ if ($template->param('discussionlink') && istranslation($page)) {
+ my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/);
+ $template->param('discussionlink' => htmllink(
+ $page,
+ $destpage,
+ $masterpage . '/' . gettext("Discussion"),
+ noimageinline => 1,
+ forcesubpage => 0,
+ linktext => gettext("Discussion"),
+ ));
}
} # }}}