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