4 Attached is a patch that adds locale support to ikiwiki.
5 A suitable locale is choosed in that order:
15 (where * == the first item found)
17 The patch brings the following functionality:
18 a) Proper local time, either using a UTF-8 locale or not (by the means
19 of a new function decode_locale),
20 b) Support for UTF-8 (or ISO-8859-X) filenames in SVN. Before this
21 patch, commiting (or even rcs_updating) on repositories with UTF-8
22 filenames is impossible.
24 This is RFC because it has some hard-coded parts: 'locale -a' and
25 /usr/share/i18n/SUPPORTED. They obviously work on Debian, but I'm sure
26 they won't work on other distros, let along on other operating systems.
28 Besides that, it's quite a big of a change and I could use some comments
31 Index: IkiWiki/Rcs/svn.pm
32 ===================================================================
33 --- IkiWiki/Rcs/svn.pm (revision 904)
34 +++ IkiWiki/Rcs/svn.pm (working copy)
37 my $rev=int(possibly_foolish_untaint($ENV{REV}));
39 - my $user=`svnlook author $config{svnrepo} -r $rev`;
40 + my $user=decode_locale(`svnlook author $config{svnrepo} -r $rev`);
42 - my $message=`svnlook log $config{svnrepo} -r $rev`;
43 + my $message=decode_locale(`svnlook log $config{svnrepo} -r $rev`);
44 if ($message=~/$svn_webcommit/) {
50 - foreach my $change (`svnlook changed $config{svnrepo} -r $rev`) {
51 + foreach my $change (decode_locale(`svnlook changed $config{svnrepo} -r $rev`)) {
53 if ($change =~ /^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) {
54 push @changed_pages, $1;
56 # subscribers a diff that might contain pages they did not
57 # sign up for. Should separate the diff per page and
58 # reassemble into one mail with just the pages subscribed to.
59 - my $diff=`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`;
60 + my $diff=decode_locale(`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`);
62 my $subject="$config{wikiname} update of ";
63 if (@changed_pages > 2) {
64 Index: IkiWiki/Render.pm
65 ===================================================================
66 --- IkiWiki/Render.pm (revision 904)
67 +++ IkiWiki/Render.pm (working copy)
70 # strftime doesn't know about encodings, so make sure
71 # its output is properly treated as utf8
72 - return decode_utf8(POSIX::strftime(
73 + return decode_locale(POSIX::strftime(
74 $config{timeformat}, localtime($time)));
78 ===================================================================
79 --- IkiWiki.pm (revision 904)
80 +++ IkiWiki.pm (working copy)
85 +memoize("get_charset_from_locale");
87 use vars qw{%config %links %oldlinks %oldpagemtime %pagectime
88 %renderedfiles %pagesources %depends %hooks};
91 plugin => [qw{mdwn inline htmlscrubber}],
93 + locale => get_preferred_locale(),
96 sub checkconfig () { #{{{
97 + debug("setting LC_ALL to '$config{locale}'");
99 + $ENV{LC_ALL} = $config{locale};
100 + POSIX::setlocale(&POSIX::LC_ALL, $config{locale});
102 if ($config{w3mmode}) {
103 eval q{use Cwd q{abs_path}};
104 $config{srcdir}=possibly_foolish_untaint(abs_path($config{srcdir}));
106 $hooks{$param{type}}{$param{id}}=\%param;
109 +sub get_preferred_locale() {
110 + if (my $env = $ENV{LC_ALL}) {
114 + my @avail=`locale -a`;
117 + return "POSIX" unless @avail;
120 + # prefer UTF-8 locales
121 + @avail = map { my $l = $_; $l =~ s/\.utf8/\.UTF-8/; $l; } @avail;
122 + @avail = @ret if @ret = grep(/\.UTF-8$/, @avail);
124 + # prefer en_US or en_ locales
125 + return $ret[0] if @ret = grep(/^en_US/, @avail);
126 + return $ret[0] if @ret = grep(/^en_/, @avail);
127 + return $ret[0] if @ret = grep(/^[^.@]+$/, @avail);
129 + # fallback to the first locale found
133 +sub get_charset_from_locale($) {
137 + my $supportedlist = "/usr/share/i18n/SUPPORTED";
138 + if (defined $locale and open(SUPPORTED, "< $supportedlist")) {
139 + while (<SUPPORTED>) {
141 + ($l, $c) = split(/\s+/);
142 + last if ($l eq $locale);
146 + return $c if ($l eq $locale);
148 + return "ISO-8859-1";
151 +sub decode_locale($) {
152 + return decode(get_charset_from_locale($config{locale}), shift);