+ my %ret;
+ if (istranslatable($page)) {
+ %ret = %{$translations{$page}};
+ }
+ elsif (istranslation($page)) {
+ my $masterpage = masterpage($page);
+ $ret{$config{po_master_language}{code}} = $masterpage;
+ foreach my $lang (sort keys %{$translations{$masterpage}}) {
+ next if $lang eq lang($page);
+ $ret{$lang} = $translations{$masterpage}{$lang};
+ }
+ }
+ return \%ret;
+} #}}}
+
+sub potfile ($) { #{{{
+ my $masterfile=shift;
+
+ (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/);
+ $dir='' if $dir eq './';
+ return File::Spec->catpath('', $dir, $name . ".pot");
+} #}}}
+
+sub pofile ($$) { #{{{
+ my $masterfile=shift;
+ my $lang=shift;
+
+ (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/);
+ $dir='' if $dir eq './';
+ return File::Spec->catpath('', $dir, $name . "." . $lang . ".po");
+} #}}}
+
+sub pofiles ($) { #{{{
+ my $masterfile=shift;
+ return map pofile($masterfile, $_), (keys %{$config{po_slave_languages}});
+} #}}}
+
+sub refreshpot ($) { #{{{
+ my $masterfile=shift;
+
+ my $potfile=potfile($masterfile);
+ 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->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.
+ 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;
+ IkiWiki::prep_writefile(basename($potfile),dirname($potfile));
+ $doc->writepo($potfile);
+} #}}}
+
+sub refreshpofiles ($@) { #{{{
+ my $masterfile=shift;
+ my @pofiles=@_;
+
+ my $potfile=potfile($masterfile);
+ error("[po/refreshpofiles] POT file ($potfile) does not exist") unless (-e $potfile);
+
+ foreach my $pofile (@pofiles) {
+ IkiWiki::prep_writefile(basename($pofile),dirname($pofile));
+ if (-e $pofile) {
+ system("msgmerge", "-U", "--backup=none", $pofile, $potfile) == 0
+ or error("[po/refreshpofiles:$pofile] failed to update");
+ }
+ else {
+ File::Copy::syscopy($potfile,$pofile)
+ or error("[po/refreshpofiles:$pofile] failed to copy the POT file");
+ }
+ }
+} #}}}
+
+sub buildtranslationscache() { #{{{
+ # use istranslation's side-effect
+ map istranslation($_), (keys %pagesources);
+} #}}}
+
+sub resettranslationscache() { #{{{
+ undef %translations;
+} #}}}
+
+sub needsbuild () { #{{{
+ my $needsbuild=shift;
+
+ # backup @needsbuild content so that change() can know whether
+ # a given master page was rendered because its source file was changed
+ @origneedsbuild=(@$needsbuild);
+
+ buildtranslationscache();
+
+ # make existing translations depend on the corresponding master page
+ foreach my $master (keys %translations) {
+ map add_depends($_, $master), values %{otherlanguages($master)};
+ }
+} #}}}
+
+sub scan (@) { #{{{
+ my %params=@_;
+ my $page=$params{page};
+ my $content=$params{content};
+
+ return unless UNIVERSAL::can("IkiWiki::Plugin::link", "import");
+
+ if (istranslation($page)) {
+ foreach my $destpage (@{$links{$page}}) {
+ if (istranslatable($destpage)) {
+ # replace one occurence of $destpage in $links{$page}
+ # (we only want to replace the one that was added by
+ # IkiWiki::Plugin::link::scan, other occurences may be
+ # there for other reasons)
+ for (my $i=0; $i<@{$links{$page}}; $i++) {
+ if (@{$links{$page}}[$i] eq $destpage) {
+ @{$links{$page}}[$i] = $destpage . '.' . lang($page);
+ last;
+ }
+ }
+ }
+ }
+ }
+ elsif (! istranslatable($page) && ! istranslation($page)) {
+ foreach my $destpage (@{$links{$page}}) {
+ if (istranslatable($destpage)) {
+ map {
+ push @{$links{$page}}, $destpage . '.' . $_;
+ } (keys %{$config{po_slave_languages}});
+ }
+ }
+ }
+} #}}}
+
+sub mytargetpage ($$) { #{{{
+ my $page=shift;
+ my $ext=shift;
+
+ if (istranslation($page)) {
+ my ($masterpage, $lang) = (masterpage($page), lang($page));
+ if (! $config{usedirs} || $masterpage eq 'index') {