]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
po: send msgfmt output to /dev/null, else it creates messages.mo files
[ikiwiki.git] / IkiWiki / Plugin / po.pm
index 13110d24295154eba6908b2591601050d095cb6a..d741a792819ba691538261d216aa8b49df9278d4 100644 (file)
@@ -387,7 +387,16 @@ sub change(@) {
 sub cansave ($$$$) {
        my ($page, $content, $cgi, $session) = (shift, shift, shift, shift);
 
-       debug("po plugin running in cansave")
+       if (istranslation($page)) {
+               my $res = isvalidpo($content);
+               if ($res) {
+                       return undef;
+               }
+               else {
+                       return "$res";
+               }
+       }
+       return undef;
 }
 
 sub canremove ($$$) {
@@ -900,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;
@@ -934,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, "-o", "/dev/null") == 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
 # `----