summaryrefslogtreecommitdiff
path: root/doc/patchqueue/locale_patch.mdwn
blob: 78e82f9ac62afacd5d78529d6d7acb02cee13ee2 (plain)

This v2 patch is a different approach after Joey's comments and some though.

It achieves:

  1. Proper local time, if the locale configuration option is used,
  2. 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 was impossible.

The svn backend sets LC_CTYPE to the following, in order of preference:

  • The current locale, if it contains utf8/UTF-8,
  • The current locale with the string ".UTF-8" appended to it,
  • en_US.UTF-8/en_GB.UTF-8 -- a bit hacky, but they're very common and they can help avoiding a call to locale -a, which may not be available in the current system,
  • The first UTF-8 locale it encounters from locale -a. Note that LC_CTYPE is the same for every UTF-8 locale, so it doesn't matter which one will be used.

-- [[Faidon]]


Index: IkiWiki/Rcs/svn.pm
===================================================================
--- IkiWiki/Rcs/svn.pm	(revision 967)
+++ IkiWiki/Rcs/svn.pm	(working copy)
@@ -4,11 +4,35 @@
 use warnings;
 use strict;
 use IkiWiki;
+use POSIX qw(setlocale LC_CTYPE);
 
 package IkiWiki;
 		
 my $svn_webcommit=qr/^web commit (by (\w+)|from (\d+\.\d+\.\d+\.\d+)):?(.*)/;
 
+sub find_lc_ctype() {
+	my $current = setlocale(LC_CTYPE);
+
+	# Respect current locale if it's a UTF-8 one
+	return $current if $current =~ m/UTF-?8$/i;
+
+	# Make some obvious attempts to avoid calling `locale -a`
+	foreach my $locale ("$current.UTF-8", "en_US.UTF-8", "en_GB.UTF-8") {
+		return $locale if setlocale(LC_CTYPE, $locale);
+	}
+
+	# Try to get all available locales and pick the first UTF-8 one if found
+	if (my @locale = grep(/UTF-?8$/i, `locale -a`)) {
+		chomp @locale;
+		return $locale[0] if setlocale(LC_CTYPE, $locale[0]);
+	}
+
+	# fallback to the current locale
+	return $current;
+
+} # }}}
+$ENV{LC_CTYPE} = $ENV{LC_CTYPE} || find_lc_ctype();
+
 sub svn_info ($$) { #{{{
 	my $field=shift;
 	my $file=shift;
Index: IkiWiki.pm
===================================================================
--- IkiWiki.pm	(revision 967)
+++ IkiWiki.pm	(working copy)
@@ -49,9 +49,21 @@
 	adminemail => undef,
 	plugin => [qw{mdwn inline htmlscrubber}],
 	timeformat => '%c',
+	locale => undef,
 } #}}}
    
 sub checkconfig () { #{{{
+	# locale stuff; avoid LC_ALL since it overrides everything
+	if (defined $ENV{LC_ALL}) {
+		$ENV{LANG} = $ENV{LC_ALL};
+		delete $ENV{LC_ALL};
+	}
+	if (defined $config{locale}) {
+		eval q{use POSIX};
+		$ENV{LANG} = $config{locale}
+			if POSIX::setlocale(&POSIX::LANG, $config{locale});
+	}
+
 	if ($config{w3mmode}) {
 		eval q{use Cwd q{abs_path}};
 		$config{srcdir}=possibly_foolish_untaint(abs_path($config{srcdir}));
Index: doc/ikiwiki.setup
===================================================================
--- doc/ikiwiki.setup	(revision 967)
+++ doc/ikiwiki.setup	(working copy)
@@ -72,6 +72,9 @@
 	#exclude => qr/\*.wav/,
 	# Time format (for strftime)
 	#timeformat => '%c',
+	# Locale to be used, useful for language customization of last-modified
+	# time. WARNING: Must be a UTF-8 locale!
+	#locale => 'en_US.UTF-8',
 	
 	# To add plugins, list them here.
 	#add_plugins => [qw{meta tag pagecount brokenlinks search smiley