X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/1d3da099b4763df37033e7955b8762f5b818d1b6..d0c9c21687b498fa40a6359fb7b7cbcd70034512:/IkiWiki/Plugin/po.pm diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 35e7c13ff..236b5984f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -388,11 +388,12 @@ sub cansave ($$$$) { my ($page, $content, $cgi, $session) = (shift, shift, shift, shift); if (istranslation($page)) { - if (defined po_to_markup($page, $content, "nonfatal")) { + my $res = isvalidpo($content); + if ($res) { return undef; } else { - return "Could not parse this page's content; is this valid gettext?"; + return "$res"; } } return undef; @@ -908,7 +909,7 @@ sub po_to_markup ($$;$) { UNLINK => 1)->filename; sub failure ($) { - my $msg = '[po/filter:'.$page.'] ' . shift; + my $msg = '[po/po_to_markup:'.$page.'] ' . shift; if ($nonfatal) { warn $msg; return undef; @@ -942,6 +943,48 @@ sub po_to_markup ($$;$) { return $content; } +# returns a SuccessReason or FailReason object +sub isvalidpo ($) { + my $content = shift; + + # NB: we don't use po_to_markup here, since Po4a parser does + # not mind invalid PO content + $content = '' unless defined $content; + $content = decode_utf8(encode_utf8($content)); + + # There are incompatibilities between some File::Temp versions + # (including 0.18, bundled with Lenny's perl-modules package) + # and others (e.g. 0.20, previously present in the archive as + # a standalone package): under certain circumstances, some + # return a relative filename, whereas others return an absolute one; + # we here use this module in a way that is at least compatible + # with 0.18 and 0.20. Beware, hit'n'run refactorers! + my $infile = new File::Temp(TEMPLATE => "ikiwiki-po-isvalidpo.XXXXXXXXXX", + DIR => File::Spec->tmpdir, + UNLINK => 1)->filename; + + sub failure ($) { + my $msg = '[po/isvalidpo] ' . shift; + unlink $infile; + return IkiWiki::FailReason->new("$msg"); + } + + writefile(basename($infile), File::Spec->tmpdir, $content) + or return failure("failed to write $infile"); + + my $res = (system("msgfmt", "--check", $infile) == 0); + + # Unlinking should happen automatically, thanks to File::Temp, + # but it does not work here, probably because of the way writefile() + # and Locale::Po4a::write() work. + unlink $infile; + + if ($res) { + return IkiWiki::SuccessReason->new("valid gettext data"); + } + return IkiWiki::FailReason->new("invalid gettext data"); +} + # ,---- # | PageSpec's # `----