summaryrefslogtreecommitdiff
path: root/LedgerSMB/locales.pl
blob: 91f610153586057ecce87265e2dd96c9388f9858 (plain)
  1. #!/usr/bin/perl
  2. # -n do not include custom_ scripts
  3. # -a build all file
  4. # -m do not generate missing files
  5. use FileHandle;
  6. use Getopt::Long;
  7. Getopt::Long::Configure('bundling');
  8. $basedir = "../..";
  9. $bindir = "$basedir/bin";
  10. $customdir = "$bindir/custom";
  11. $menufile = "menu.ini";
  12. my $excludeCustom = 0;
  13. my $buildAll = 0;
  14. my $noMissing = 0;
  15. my $goodOpt = 0;
  16. $goodOpt = GetOptions (
  17. 'n' => \$excludeCustom, 'no-custom' => \$excludeCustom,
  18. 'a' => \$buildAll, 'build-all' => \$buildAll,
  19. 'm' => \$noMissing, 'no-missing' => \$noMissing);
  20. if (!$goodOpt) {
  21. printf "Invalid options\n";
  22. exit 1;
  23. }
  24. open(FH, "LANGUAGE");
  25. $language = <FH>;
  26. close(FH);
  27. chomp $language;
  28. $language =~ s/\((.*)\)/$1/;
  29. $charset = $1;
  30. opendir DIR, "$bindir" or die "$!";
  31. @progfiles = grep { /\.pl/; !/(_|^\.)/ } readdir DIR;
  32. seekdir DIR, 0;
  33. @customfiles = grep /_/, readdir DIR;
  34. closedir DIR;
  35. # put customized files into @customfiles
  36. @customfiles = () if ($excludeCustom);
  37. if ($excludeCustom) {
  38. @menufiles = ($menufile);
  39. } else {
  40. opendir DIR, "$bindir" or die "$!";
  41. @menufiles = grep { /.*?_$menufile$/ } readdir DIR;
  42. closedir DIR;
  43. ## unshift @menufiles, $menufile;
  44. ## opendir DIR, "$customdir" or die "$!";
  45. ## @menufiles = grep { /^$menufile$/ } readdir DIR;
  46. ## closedir DIR;
  47. unshift @menufiles, $menufile;
  48. }
  49. if (-f "all") {
  50. eval { require "all"; };
  51. %all = %{$self{texts}};
  52. %{$self{texts}} = ();
  53. } else {
  54. # build %all file from individual files
  55. foreach $file (@progfiles) {
  56. &scanfile("$bindir/$file");
  57. }
  58. }
  59. # remove the old missing file
  60. if (-f 'missing') {
  61. unlink "missing";
  62. }
  63. foreach $file (@progfiles) {
  64. next if -d "$bindir/$file";
  65. %locale = ();
  66. %submit = ();
  67. %subrt = ();
  68. @missing = ();
  69. %missing = ();
  70. &scanfile("$bindir/$file");
  71. # scan custom_{module}.pl or {login}_{module}.pl files
  72. foreach $customfile (@customfiles) {
  73. if ($customfile =~ /_$file/) {
  74. if (-f "$bindir/$customfile") {
  75. &scanfile("$bindir/$customfile");
  76. }
  77. }
  78. }
  79. # if this is the menu.pl file
  80. if ($file eq 'menu.pl') {
  81. foreach $item (@menufiles) {
  82. &scanmenu("$basedir/$item");
  83. }
  84. }
  85. $file =~ s/\.pl//;
  86. if (-f "$file.missing") {
  87. eval { require "$file.missing"; };
  88. unlink "$file.missing";
  89. for (keys %$missing) {
  90. $self{texts}{$_} ||= $missing->{$_};
  91. }
  92. }
  93. open FH, ">$file" or die "$! : $file";
  94. if ($charset) {
  95. print FH qq|\$self{charset} = '$charset';\n\n|;
  96. }
  97. print FH q|$self{texts} = {
  98. |;
  99. foreach $key (sort keys %locale) {
  100. $text = ($self{texts}{$key}) ? $self{texts}{$key} : $all{$key};
  101. $count++;
  102. $text =~ s/'/\\'/g;
  103. $text =~ s/\\$/\\\\/;
  104. $keytext = $key;
  105. $keytext =~ s/'/\\'/g;
  106. $keytext =~ s/\\$/\\\\/;
  107. if (!$text) {
  108. $notext++;
  109. push @missing, $keytext;
  110. next;
  111. }
  112. print FH qq| '$keytext'|.(' ' x (27-length($keytext))).qq| => '$text',\n|;
  113. }
  114. print FH q|};
  115. $self{subs} = {
  116. |;
  117. foreach $key (sort keys %subrt) {
  118. $text = $key;
  119. $text =~ s/'/\\'/g;
  120. $text =~ s/\\$/\\\\/;
  121. print FH qq| '$text'|.(' ' x (27-length($text))).qq| => '$text',\n|;
  122. }
  123. foreach $key (sort keys %submit) {
  124. $text = ($self{texts}{$key}) ? $self{texts}{$key} : $all{$key};
  125. next unless $text;
  126. $text =~ s/'/\\'/g;
  127. $text =~ s/\\$/\\\\/;
  128. $english_sub = $key;
  129. $english_sub =~ s/'/\\'/g;
  130. $english_sub =~ s/\\$/\\\\/;
  131. $english_sub = lc $key;
  132. $translated_sub = lc $text;
  133. $english_sub =~ s/( |-|,|\/|\.$)/_/g;
  134. $translated_sub =~ s/( |-|,|\/|\.$)/_/g;
  135. print FH qq| '$translated_sub'|.(' ' x (27-length($translated_sub))).qq| => '$english_sub',\n|;
  136. }
  137. print FH q|};
  138. 1;
  139. |;
  140. close FH;
  141. if (!$noMissing) {
  142. if (@missing) {
  143. open FH, ">$file.missing" or die "$! : missing";
  144. print FH qq|# module $file
  145. # add the missing texts and run locales.pl to rebuild
  146. \$missing = {
  147. |;
  148. foreach $text (@missing) {
  149. $text =~ s/'/\\'/g;
  150. $text =~ s/\\$/\\\\/;
  151. print FH qq| '$text'|.(' ' x (27-length($text))).qq| => '',\n|;
  152. }
  153. print FH q|};
  154. 1;
  155. |;
  156. close FH;
  157. }
  158. }
  159. # redo the all file
  160. if ($buildAll) {
  161. open FH, ">all" or die "$! : all";
  162. print FH q|# These are all the texts to build the translations files.
  163. # to build unique strings edit the module files instead
  164. # this file is just a shortcut to build strings which are the same
  165. |;
  166. if ($charset) {
  167. print FH qq|\$self{charset} = '$charset';\n\n|;
  168. }
  169. print FH q|
  170. $self{texts} = {
  171. |;
  172. foreach $key (sort keys %all) {
  173. $keytext = $key;
  174. $keytext =~ s/'/\\'/g;
  175. $keytext =~ s/\\$/\\\\/;
  176. $text = $all{$key};
  177. $text =~ s/'/\\'/g;
  178. $text =~ s/\\$/\\\\/;
  179. print FH qq| '$keytext'|.(' ' x (27-length($keytext))).qq| => '$text',\n|;
  180. }
  181. print FH q|};
  182. 1;
  183. |;
  184. close FH;
  185. }
  186. }
  187. $per = sprintf("%.1f", ($count - $notext) / $count * 100);
  188. print "\n$language - ${per}%\n";
  189. exit;
  190. # eof
  191. sub scanfile {
  192. my ($file, $level) = @_;
  193. my $fh = new FileHandle;
  194. return unless (-e $file or $file !~ /custom/);
  195. open $fh, "$file" or die "$! : $file";
  196. $file =~ s/\.pl//;
  197. $file =~ s/$bindir\///;
  198. %temp = ();
  199. for (keys %{$self{texts}}) {
  200. $temp{$_} = $self{texts}{$_};
  201. }
  202. # read translation file if it exists
  203. if (-f $file) {
  204. eval { do "$file"; };
  205. for (keys %{$self{texts}}) {
  206. $all{$_} ||= $self{texts}{$_};
  207. if ($level) {
  208. $temp{$_} ||= $self{texts}{$_};
  209. } else {
  210. $temp{$_} = $self{texts}{$_};
  211. }
  212. }
  213. }
  214. %{$self{texts}} = ();
  215. for (sort keys %temp) {
  216. $self{texts}{$_} = $temp{$_};
  217. }
  218. while (<$fh>) {
  219. # is this another file
  220. if (/require\s+\W.*\.pl/) {
  221. my $newfile = $&;
  222. $newfile =~ s/require\s+\W//;
  223. $newfile =~ s/\$form->{path}\///;
  224. &scanfile("$basedir/$newfile", 1) if $newfile !~ /_/;
  225. }
  226. # is this a sub ?
  227. if (/^sub /) {
  228. ($null, $subrt) = split / +/;
  229. $subrt{$subrt} = 1;
  230. next;
  231. }
  232. my $rc = 1;
  233. while ($rc) {
  234. if (/Locale/) {
  235. if (!/^use /) {
  236. my ($null, $country) = split /,/;
  237. $country =~ s/^ +["']//;
  238. $country =~ s/["'].*//;
  239. }
  240. }
  241. if (/\$locale->text.*?\W\)/) {
  242. my $string = $&;
  243. $string =~ s/\$locale->text\(\s*['"(q|qq)]['\/\\\|~]*//;
  244. $string =~ s/\W\)+.*$//;
  245. # if there is no $ in the string record it
  246. unless ($string =~ /\$\D.*/) {
  247. # this guarantees one instance of string
  248. $locale{$string} = 1;
  249. # is it a submit button before $locale->
  250. if (/type="?submit"?/i) {
  251. $submit{$string} = 1;
  252. }
  253. }
  254. }
  255. # exit loop if there are no more locales on this line
  256. ($rc) = ($' =~ /\$locale->text/);
  257. # strip text
  258. s/^.*?\$locale->text.*?\)//;
  259. }
  260. }
  261. close($fh);
  262. }
  263. sub scanmenu {
  264. my $file = shift;
  265. my $fh = new FileHandle;
  266. open $fh, "$file" or die "$! : $file";
  267. my @a = grep /^\[/, <$fh>;
  268. close($fh);
  269. # strip []
  270. grep { s/(\[|\])//g } @a;
  271. foreach my $item (@a) {
  272. $item =~ s/ *$//;
  273. @b = split /--/, $item;
  274. foreach $string (@b) {
  275. chomp $string;
  276. if ($string !~ /^\s*$/) {
  277. $locale{$string} = 1;
  278. }
  279. }
  280. }
  281. }