diff options
-rw-r--r-- | doc/patchqueue/locale_patch.mdwn | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/doc/patchqueue/locale_patch.mdwn b/doc/patchqueue/locale_patch.mdwn new file mode 100644 index 000000000..8548d9b90 --- /dev/null +++ b/doc/patchqueue/locale_patch.mdwn @@ -0,0 +1,155 @@ +From [[Faidon]]: + +Joey, +Attached is a patch that adds locale support to ikiwiki. +A suitable locale is choosed in that order: +1) $config{locale} +2) $ENV{LC_ALL} +3) en_US.UTF-8 +4) en_*.UTF-8 +5) *.UTF-8 +5) en_US +6) en_* +7) * +8) POSIX +(where * == the first item found) + +The patch brings the following functionality: +a) Proper local time, either using a UTF-8 locale or not (by the means +of a new function decode_locale), +b) Support for UTF-8 (or ISO-8859-X) filenames in SVN. Before this +patch, commiting (or even rcs_updating) on repositories with UTF-8 +filenames is impossible. + +This is RFC because it has some hard-coded parts: 'locale -a' and +/usr/share/i18n/SUPPORTED. They obviously work on Debian, but I'm sure +they won't work on other distros, let along on other operating systems. + +Besides that, it's quite a big of a change and I could use some comments +to make it better :) + + Index: IkiWiki/Rcs/svn.pm + =================================================================== + --- IkiWiki/Rcs/svn.pm (revision 904) + +++ IkiWiki/Rcs/svn.pm (working copy) + @@ -174,16 +236,16 @@ + } + my $rev=int(possibly_foolish_untaint($ENV{REV})); + + - my $user=`svnlook author $config{svnrepo} -r $rev`; + + my $user=decode_locale(`svnlook author $config{svnrepo} -r $rev`); + chomp $user; + - my $message=`svnlook log $config{svnrepo} -r $rev`; + + my $message=decode_locale(`svnlook log $config{svnrepo} -r $rev`); + if ($message=~/$svn_webcommit/) { + $user="$1"; + $message=$2; + } + + my @changed_pages; + - foreach my $change (`svnlook changed $config{svnrepo} -r $rev`) { + + foreach my $change (decode_locale(`svnlook changed $config{svnrepo} -r $rev`)) { + chomp $change; + if ($change =~ /^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) { + push @changed_pages, $1; + @@ -197,7 +259,7 @@ + # subscribers a diff that might contain pages they did not + # sign up for. Should separate the diff per page and + # reassemble into one mail with just the pages subscribed to. + - my $diff=`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`; + + my $diff=decode_locale(`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`); + + my $subject="$config{wikiname} update of "; + if (@changed_pages > 2) { + Index: IkiWiki/Render.pm + =================================================================== + --- IkiWiki/Render.pm (revision 904) + +++ IkiWiki/Render.pm (working copy) + @@ -222,7 +222,7 @@ + eval q{use POSIX}; + # strftime doesn't know about encodings, so make sure + # its output is properly treated as utf8 + - return decode_utf8(POSIX::strftime( + + return decode_locale(POSIX::strftime( + $config{timeformat}, localtime($time))); + } #}}} + + Index: IkiWiki.pm + =================================================================== + --- IkiWiki.pm (revision 904) + +++ IkiWiki.pm (working copy) + @@ -9,6 +9,7 @@ + # Optimisation. + use Memoize; + memoize("abs2rel"); + +memoize("get_charset_from_locale"); + + use vars qw{%config %links %oldlinks %oldpagemtime %pagectime + %renderedfiles %pagesources %depends %hooks}; + @@ -49,9 +50,15 @@ + adminemail => undef, + plugin => [qw{mdwn inline htmlscrubber}], + timeformat => '%c', + + locale => get_preferred_locale(), + } #}}} + + sub checkconfig () { #{{{ + + debug("setting LC_ALL to '$config{locale}'"); + + eval q{use POSIX}; + + $ENV{LC_ALL} = $config{locale}; + + POSIX::setlocale(&POSIX::LC_ALL, $config{locale}); + + + if ($config{w3mmode}) { + eval q{use Cwd q{abs_path}}; + $config{srcdir}=possibly_foolish_untaint(abs_path($config{srcdir})); + @@ -489,4 +496,50 @@ + $hooks{$param{type}}{$param{id}}=\%param; + } # }}} + + +sub get_preferred_locale() { + + if (my $env = $ENV{LC_ALL}) { + + return $env; + + } + + + + my @avail=`locale -a`; + + chomp @avail; + + + + return "POSIX" unless @avail; + + + + my @ret; + + # prefer UTF-8 locales + + @avail = map { my $l = $_; $l =~ s/\.utf8/\.UTF-8/; $l; } @avail; + + @avail = @ret if @ret = grep(/\.UTF-8$/, @avail); + + + + # prefer en_US or en_ locales + + return $ret[0] if @ret = grep(/^en_US/, @avail); + + return $ret[0] if @ret = grep(/^en_/, @avail); + + return $ret[0] if @ret = grep(/^[^.@]+$/, @avail); + + + + # fallback to the first locale found + + return $avail[0]; + +} # }}} + + + +sub get_charset_from_locale($) { + + my $locale=shift; + + my ($l, $c); + + + + my $supportedlist = "/usr/share/i18n/SUPPORTED"; + + if (defined $locale and open(SUPPORTED, "< $supportedlist")) { + + while (<SUPPORTED>) { + + chomp; + + ($l, $c) = split(/\s+/); + + last if ($l eq $locale); + + } + + close(SUPPORTED); + + + + return $c if ($l eq $locale); + + } + + return "ISO-8859-1"; + +} # }}} + + + +sub decode_locale($) { + + return decode(get_charset_from_locale($config{locale}), shift); + +} # }}} + + + 1 |