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");
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);
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,
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}) {
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";
}
my $page = $params{page};
my $destpage = $params{destpage};
my $content = $params{content};
- my $fullpage = $params{fullpage};
-
- unless ($fullpage) {
- return $content;
- }
-
if (istranslation($page) && ! alreadyfiltered($page, $destpage)) {
$content = po_to_markup($page, $content);
setalreadyfiltered($page, $destpage);
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 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=@_;
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.
# 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;
$res =~ s!/\Qindex.$config{htmlext}\E$!/!;
map {
$res =~ s!/\Qindex.$_.$config{htmlext}\E$!/!;
- } (keys %{$config{po_slave_languages}});
+ } @slavelanguages;
}
return $res;
}
return 1 if $origsubs{'isselflink'}->($page, $link);
if (istranslation($page)) {
return $origsubs{'isselflink'}->(masterpage($page), $link);
- }
+ }
return;
}
sub otherlanguages_pages ($) {
my $page=shift;
- my %ret;
+ my %ret;
map {
$ret{$_} = otherlanguage_page($page, $_)
} @{otherlanguages_codes($page)};
sub pofiles ($) {
my $masterfile=shift;
- return map pofile($masterfile, $_), (keys %{$config{po_slave_languages}});
+ return map pofile($masterfile, $_), @slavelanguages;
}
sub refreshpot ($) {
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;
}
if (-e $absfile && ! -l $absfile && ! -d $absfile) {
push @todelete, $file;
}
- } keys %{$config{po_slave_languages}};
+ } @slavelanguages;
map {
if ($config{rcs}) {
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"));
my $pagetype = pagetype($file);
if ($pagetype eq 'html') {
return 'xhtml';
- }
+ }
return 'text';
}
# 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;
}
sub match_needstranslation ($$;@) {
my $page=shift;
+ my $wanted=shift;
+
+ if (defined $wanted && $wanted ne "") {
+ if ($wanted !~ /^\d+$/) {
+ return IkiWiki::FailReason->new("parameter is not an integer");
+ }
+ elsif ($wanted > 100) {
+ return IkiWiki::FailReason->new("parameter is greater than 100");
+ }
+ }
+ else {
+ $wanted=100;
+ }
my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page);
if ($percenttranslated eq 'N/A') {
return IkiWiki::FailReason->new("file is not a translatable page");
}
- elsif ($percenttranslated < 100) {
+ elsif ($percenttranslated < $wanted) {
return IkiWiki::SuccessReason->new("file has $percenttranslated translated");
- }
+ }
else {
- return IkiWiki::FailReason->new("file is fully translated");
+ return IkiWiki::FailReason->new("file is translated enough");
}
}