calendar, prettydate: Fix strftime encoding bug
authorJoey Hess <joey@kitenet.net>
Mon, 30 Jan 2012 19:08:50 +0000 (15:08 -0400)
committerJoey Hess <joey@kitenet.net>
Mon, 30 Jan 2012 19:09:37 +0000 (15:09 -0400)
strftime is a C function, it does not return decoded utf8.
Several places in ikiwiki manually decoded it, but at least two
forgot to.

Also, strftime might not return even encoded utf8, if LC_TIME is set
to a non-utf8 value. Went ahead and supported decoding whatever encoding
it uses.

The remaining direct calls to strftime() are all ones that first set
LC_TIME=C, in order to get times that are not for human display.

IkiWiki.pm
IkiWiki/Plugin/calendar.pm
IkiWiki/Plugin/comments.pm
IkiWiki/Plugin/prettydate.pm
debian/changelog
doc/bugs/Encoding_problem_in_calendar_plugin.mdwn
doc/forum/Encoding_problem_in_french_with_ikiwiki-calendar.mdwn

index bc56501dab4f733ca34adbb4e88dcce66e6c102e..0a788f35bd69411e4ee536903fd8acc7a8580452 100644 (file)
@@ -20,7 +20,7 @@ use Exporter q{import};
 our @EXPORT = qw(hook debug error htmlpage template template_depends
        deptype add_depends pagespec_match pagespec_match_list bestlink
        htmllink readfile writefile pagetype srcfile pagename
-       displaytime will_render gettext ngettext urlto targetpage
+       displaytime strftime_utf8 will_render gettext ngettext urlto targetpage
        add_underlay pagetitle titlepage linkpage newpagefile
        inject add_link add_autofile
        %config %links %pagestate %wikistate %renderedfiles
@@ -1148,9 +1148,19 @@ sub formattime ($;$) {
                $format=$config{timeformat};
        }
 
+       return strftime_utf8($format, localtime($time));
+}
+
+my $strftime_encoding;
+sub strftime_utf8 {
        # strftime doesn't know about encodings, so make sure
-       # its output is properly treated as utf8
-       return decode_utf8(POSIX::strftime($format, localtime($time)));
+       # its output is properly treated as utf8.
+       # Note that this does not handle utf-8 in the format string.
+       $strftime_encoding = POSIX::setlocale(&POSIX::LC_TIME) =~ m#\.([^@]+)#
+               unless defined $strftime_encoding;
+       $strftime_encoding
+               ? Encode::decode($strftime_encoding, POSIX::strftime(@_))
+               : POSIX::strftime(@_);
 }
 
 sub date_3339 ($) {
index c7d2b7c01d8943f26e34e43231cc4ee26e0b6847..fc497b3c7351ea2151bfb14092568dbb687c3eb2 100644 (file)
@@ -22,7 +22,6 @@ use warnings;
 use strict;
 use IkiWiki 3.00;
 use Time::Local;
-use POSIX ();
 
 my $time=time;
 my @now=localtime($time);
@@ -123,10 +122,10 @@ sub format_month (@) {
        }
 
        # Find out month names for this, next, and previous months
-       my $monthabbrev=POSIX::strftime("%b", @monthstart);
-       my $monthname=POSIX::strftime("%B", @monthstart);
-       my $pmonthname=POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900)));
-       my $nmonthname=POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900)));
+       my $monthabbrev=strftime_utf8("%b", @monthstart);
+       my $monthname=strftime_utf8("%B", @monthstart);
+       my $pmonthname=strftime_utf8("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900)));
+       my $nmonthname=strftime_utf8("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900)));
 
        my $archivebase = 'archives';
        $archivebase = $config{archivebase} if defined $config{archivebase};
@@ -182,7 +181,7 @@ EOF
        my %dowabbr;
        for my $dow ($week_start_day..$week_start_day+6) {
                my @day=localtime(timelocal(0,0,0,$start_day++,$params{month}-1,$params{year}-1900));
-               my $downame = POSIX::strftime("%A", @day);
+               my $downame = strftime_utf8("%A", @day);
                my $dowabbr = substr($downame, 0, 1);
                $downame{$dow % 7}=$downame;
                $dowabbr{$dow % 7}=$dowabbr;
@@ -329,8 +328,8 @@ EOF
        for (my $month = 1; $month <= 12; $month++) {
                my @day=localtime(timelocal(0,0,0,15,$month-1,$params{year}-1900));
                my $murl;
-               my $monthname = POSIX::strftime("%B", @day);
-               my $monthabbr = POSIX::strftime("%b", @day);
+               my $monthname = strftime_utf8("%B", @day);
+               my $monthabbr = strftime_utf8("%b", @day);
                $calendar.=qq{\t<tr>\n}  if ($month % $params{months_per_row} == 1);
                my $tag;
                my $mtag=sprintf("%02d", $month);
index 3ad2a0e13a2a51ffce1301e020687b4b0c6b36d3..91a482ed6660059ed3a77f30b5236dbd891303a8 100644 (file)
@@ -9,7 +9,6 @@ use warnings;
 use strict;
 use IkiWiki 3.00;
 use Encode;
-use POSIX qw(strftime);
 
 use constant PREVIEW => "Preview";
 use constant POST_COMMENT => "Post comment";
@@ -460,7 +459,7 @@ sub editcomment ($$) {
        }
        $content .= " subject=\"$subject\"\n";
 
-       $content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
+       $content .= " date=\"" . strftime_utf8('%Y-%m-%dT%H:%M:%SZ', gmtime) . "\"\n";
 
        my $editcontent = $form->field('editcontent');
        $editcontent="" if ! defined $editcontent;
index 82d8a3df3eeef1c0b4a45c532774637a2a3e5209..b0931cb5533b36bcab5cbb3afa514ef75c51f132 100644 (file)
@@ -118,10 +118,10 @@ sub IkiWiki::formattime ($;$) {
                }
        }
 
-       $t=~s{\%A-}{my @yest=@t; $yest[6]--; strftime("%A", \@yest)}eg;
+       $t=~s{\%A-}{my @yest=@t; $yest[6]--; strftime_utf8("%A", \@yest)}eg;
 
        $format=~s/\%X/$t/g;
-       return strftime($format, \@t);
+       return strftime_utf8($format, \@t);
 }
 
 1
index 1765142a4f2021b4304582f558c149f9a09e3545..57fe7861c15cb43180c11c14309b63793aac9cad 100644 (file)
@@ -5,6 +5,7 @@ ikiwiki (3.20120116) UNRELEASED; urgency=low
   * Switch to YAML::XS to work around insanity in YAML::Mo. Closes: #657533
   * cvs: Ensure non-text files are added in binary mode. (Amitai Schlair)
   * cvs: Various cleanups and testing. (Amitai Schlair)
+  * calendar, prettydate: Fix strftime encoding bug.
 
  -- Joey Hess <joeyh@debian.org>  Mon, 16 Jan 2012 13:41:14 -0400
 
index 2ccc43c03ed3c8cdc033cdff4891c03b605f93e9..80e9f2c828248ae99f4e40f075302f78ef1c8147 100644 (file)
@@ -11,6 +11,10 @@ The problem is that I do not know Perl, encoding is one of the thing I would be
 Cheers,    
 Louis
 
+> Yes, this seems basically right. I've applied a modified version of this.
+> [[done]]
+> --[[Joey]] 
+
 
     diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
     index c7d2b7c..1345939 100644
index 7e21644acdfacba747d3b6db7b52f55556da8388..472412de16399d9ae728c1f7e6a1ec2a8a584287 100644 (file)
@@ -15,3 +15,6 @@ Is someone could test it and verify if it works or not?
 Thanks.
 
 Zut
+
+> This was discussed in [[bugs/Encoding_problem_in_calendar_plugin]]
+> and is now fixed. --[[Joey]]