UK english converter and option
[webmin.git] / fix-english.pl
1 #!/usr/local/bin/perl
2 # Convert words in lang/en files from UK to US spelling.
3 # Create lang/en_GB files containing words that are different.
4
5 if ($ARGV[0] eq "--svn" || $ARGV[0] eq "-svn") {
6         shift(@ARGV);
7         $svn = shift(@ARGV);
8         }
9
10 chdir("/usr/local/webadmin");
11 if (@ARGV) {
12         @modules = @ARGV;
13         }
14 else {
15         @modules = ( "." );
16         opendir(DIR, ".");
17         foreach $d (readdir(DIR)) {
18                 push(@modules, $d) if (-r "$d/module.info");
19                 }
20         closedir(DIR);
21         }
22
23 # Get the words
24 open(MAPPING, "english-mappings.txt") ||
25         die "Failed to open english-mappings.txt";
26 while(<MAPPING>) {
27         s/\r|\n//g;
28         s/#.*$//;
29         my ($us, $uk) = split(/\t+/, $_);
30         if ($us && $uk) {
31                 push(@us_mappings, [ $us, $uk ]);
32                 }
33         }
34 close(MAPPING);
35 @uk_mappings = map { [ $_->[1], $_->[0] ] } @us_mappings;
36 print STDERR "Found ",scalar(@uk_mappings)," mappings\n";
37
38 # Do all the given modules
39 @rv = ( );
40 foreach $m (@modules) {
41         print STDERR "Doing module $m\n";
42         push(@rv, &fix_english_file("$m/lang/en", "$m/lang/en_GB", 1));
43         push(@rv, &fix_english_file("$m/config.info",
44                                     "$m/config.info.en_GB", 1));
45         opendir(HELP, "$m/help");
46         foreach $h (readdir(HELP)) {
47                 if ($h =~ /^([^\.]+)\.html$/) {
48                         push(@rv, &fix_english_file("$m/help/$h",
49                                           "$m/help/$1.en_GB.html", 0));
50                         }
51                 }
52         closedir(HELP);
53         }
54
55 # Print and commit the files
56 foreach $f (@rv) {
57         print $f,"\n";
58         if ($svn) {
59                 ($dir, $rest) = split(/\//, $f, 2);
60                 system("cd $dir ; svn add $rest ; svn commit -m '$svn' $rest");
61                 }
62         }
63
64 sub fix_english_file
65 {
66 local ($us, $uk, $linefmt) = @_;
67 return ( ) if (!-r $us);
68 local @rv;
69 if ($linefmt) {
70         # Webmin = separated line file
71
72         # First fix up any UK spellings in the US file
73         local %uslines;
74         &read_file($us, \%uslines);
75         local $changed_us;
76         foreach my $k (keys %uslines) {
77                 $v = $uslines{$k};
78                 $usv = &convert_to_us($v);
79                 if ($usv ne $v) {
80                         $uslines{$k} = $usv;
81                         $changed_us++;
82                         }
83                 }
84         if ($changed_us) {
85                 &write_file($us, \%uslines);
86                 push(@rv, $us);
87                 }
88
89         # Then create a UK file with only lines that need changing
90         local %uklines;
91         &read_file($uk, \%uklines);
92         local $changed_uk;
93         foreach my $k (keys %uslines) {
94                 $v = $uslines{$k};
95                 $ukv = &convert_to_uk($v);
96                 if ($ukv ne $v && $uklines{$k} ne $ukv) {
97                         $uklines{$k} = $ukv;
98                         $changed_uk++;
99                         }
100                 }
101         if ($changed_uk) {
102                 &write_file($uk, \%uklines);
103                 push(@rv, $uk);
104                 }
105         }
106 else {
107         # Big blob of text
108
109         # First fix up any UK spellings in the US file
110         local $ustext = &read_file_contents($us);
111         $usv = &convert_to_us($ustext);
112         if ($usv ne $ustext) {
113                 &write_file_contents($us, $usv);
114                 push(@rv, $us);
115                 }
116
117         # Then create a UK file
118         $uktext = &read_file_contents($uk);
119         $ukv = &convert_to_uk($usv);
120         if ($uktext ne $ukv && $ukv ne $usv) {
121                 &write_file_contents($uk, $ukv);
122                 push(@rv, $uk);
123                 }
124         }
125 return @rv;
126 }
127
128 sub convert_to_us
129 {
130 local ($str) = @_;
131 return &convert_mapping($str, \@uk_mappings);
132 }
133
134 sub convert_to_uk
135 {
136 local ($str) = @_;
137 return &convert_mapping($str, \@us_mappings);
138 }
139
140 sub convert_mapping
141 {
142 local ($str, $fromto) = @_;
143 foreach my $w (@$fromto) {
144         my ($from, $to) = @$w;
145         $str =~ s/(\s|^)\Q$from\E(\s|$)/$1$to$2/g;
146         $from = ucfirst($from);
147         $to = ucfirst($to);
148         $str =~ s/(\s|^)\Q$from\E(\s|$)/$1$to$2/g;
149         }
150 return $str;
151 }
152
153 # read_file(file, &assoc, [&order], [lowercase])
154 # Fill an associative array with name=value pairs from a file
155 sub read_file
156 {
157 open(ARFILE, $_[0]) || return 0;
158 while(<ARFILE>) {
159         s/\r|\n//g;
160         if (!/^#/ && /^([^=]+)=(.*)$/) {
161                 $_[1]->{$_[3] ? lc($1) : $1} = $2;
162                 push(@{$_[2]}, $1) if ($_[2]);
163                 }
164         elsif (!/\S/) {
165                 push(@{$_[2]}, undef) if ($_[2]);
166                 }
167         }
168 close(ARFILE);
169 return 1;
170 }
171  
172 # write_file(file, array)
173 # Write out the contents of an associative array as name=value lines
174 sub write_file
175 {
176 local(%old, @order);
177 &read_file($_[0], \%old, \@order);
178 open(ARFILE, ">$_[0]");
179 foreach $k (@order) {
180         if (!defined($k)) {
181                 print ARFILE "\n";
182                 }
183         elsif (exists($_[1]->{$k})) {
184                 print ARFILE $k,"=",$_[1]->{$k},"\n";
185                 }
186         }
187 foreach $k (keys %{$_[1]}) {
188         print ARFILE $k,"=",$_[1]->{$k},"\n" if (!exists($old{$k}));
189         }
190 close(ARFILE);
191 }
192
193 sub read_file_contents
194 {
195 open(FILE, $_[0]) || return undef;
196 local $/ = undef;
197 local $rv = <FILE>;
198 close(FILE);
199 return $rv;
200 }
201
202 sub write_file_contents
203 {
204 open(FILE, ">$_[0]") || return undef;
205 print FILE $_[1];
206 close(FILE);
207 }
208