6 my (@in_files, $str_file, $split_char, $recursive, $type, $out_dir, $in_dir, @excludes, $filter);
13 'input|i=s' => \@in_files,
14 'outputdir|o=s' => \$out_dir,
15 'str-file|s=s' => \$str_file,
16 'recursive|r' => \$recursive,
17 'filter=s' => \$filter,
19 'exclude=s' => \@excludes,
20 'sep=s' => \$split_char,
22 ) || (usage(), exit(-1));
26 # utiliser glob() pour tous les fichiers d'un repertoire
28 my $action = shift or usage();
31 # Checks for missing input and string list arguments
33 if( !defined(@in_files) || !defined($str_file) )
35 usage("You must at least specify input and string list filenames.");
38 # Type match defaults to *.tmpl if not specified
39 $type = "tmpl|inc" if !defined($type);
41 $filter = "./text-extract.pl -f" if !defined($filter);
42 # Input is not a file nor a directory
43 if( !(-d $in_files[0]) && !(-f $in_files[0]))
45 usage("Unknown input. Input must a file or a directory. (Symbolic links are not supported for the moment.)");
47 elsif( -d $in_files[0] )
49 # input is a directory, generates list of files to process
50 $in_dir = $in_files[0];
51 $in_dir =~ s/\/$//; # strips the trailing / if any
53 print "Generating list of files to process...\n";
56 @in_files = &listfiles(\@in_files, $in_dir, $type, $recursive);
58 if(scalar(@in_files) == 0)
60 warn "Nothing to process in $in_dir matching *.$type.";
65 # Generates the global exclude regular expression
66 $exclude_regex = "(".join("|", @excludes).")" if @excludes;
68 if( $action eq "create" )
70 # updates the list. As the list is empty, every entry will be added
71 %strhash = &update_strhash(\%strhash, \@in_files, $exclude_regex, $filter);
72 # saves the list to the file
73 write_strhash(\%strhash, $str_file, "\t");
75 elsif( $action eq "update" )
77 # restores the string list from file
78 %strhash = &restore_strhash(\%strhash, $str_file, $split_char);
79 # updates the list, adding new entries if any
80 %strhash = &update_strhash(\%strhash, \@in_files, $exclude_regex, $filter);
81 # saves the list to the file
82 write_strhash(\%strhash, $str_file, $split_char);
84 elsif( $action eq "install" )
86 if(!defined($out_dir))
88 usage("You must specify an output directory when using the install method.");
91 if( $in_dir eq $out_dir )
93 warn "You must specify a different input and output directory.\n";
97 # restores the string list from file
98 %strhash = &restore_strhash(\%strhash, $str_file, $split_char);
99 # creates the new tmpl file using the new translation
100 &install_strhash(\%strhash, \@in_files, $in_dir, $out_dir);
104 usage("Unknown action specified.");
109 ##########################################################
110 # Creates the new template files in the output directory #
111 ##########################################################
115 my($strhash, $in_files, $in_dir, $out_dir) = @_;
117 my $fh_in; my $fh_out; # handles for input and output files
118 my $tmp_dir; # temporary directory name (used to create destination dir)
120 $out_dir =~ s/\/$//; # chops the trailing / if any.
122 # Processes every entry found.
123 foreach my $file (@{$in_files})
125 if( !open($fh_in, "< $file") )
127 warn "Can't open $file : $!\n";
131 # generates the name of the output file
132 my $out_file = $file;
136 # processing single files not an entire directory
137 $out_file = "$out_dir/$file";
141 $out_file =~ s/^$in_dir/$out_dir/;
144 my $slash = rindex($out_file, "\/");
145 $tmp_dir = substr($out_file, 0, $slash); #gets the directory where the file will be saved
147 # the file doesn't exist
148 if( !(-f $tmp_dir) && !(-l $tmp_dir) && !(-e $tmp_dir) )
150 if(!mkdir($tmp_dir,0775)) # creates with rwxrwxr-x permissions
152 warn("Make directory $tmp_dir : $!");
157 elsif((-f $tmp_dir) || (-l $tmp_dir))
159 warn("Unable to create directory $tmp_dir.\n A file or symbolic link with the same name already exists.");
164 # opens handle for output
165 if( !open($fh_out, "> $out_file") )
167 warn "Can't write $out_file : $!\n";
172 print "Generating $out_file...\n";
174 while(my $line = <$fh_in>)
176 foreach my $text (sort {length($b) <=> length($a)} keys %{$strhash})
178 # Test if the key has been translated
179 if( %{$strhash}->{$text} != 1 )
181 # Does the line contains text that needs to be changed ?
182 if( $line =~ /$text/ && %{$strhash}->{$text} ne "IGNORE")
185 my $subst = %{$strhash}->{$text};
186 $line =~ s/(\W)$text(\W)/$1$subst$2/g;
190 $line =~ s/\<TMPL_(.*?)\>/\<\!-- TMPL_$1 --\>/g;
191 $line =~ s/\<\/TMPL_(.*?)\>/\<\!-- \/TMPL_$1 --\>/g;
192 # Writing the modified (or not) line to output
193 printf($fh_out "%s", $line);
201 ########################################################
202 # Updates the string list hash with the new components #
203 ########################################################
207 my($strhash, $in_files, $exclude, $filter)= @_;
211 # Processes every file entries
212 foreach my $in (@{$in_files})
215 print "Processing $in...\n";
217 # Creates a filehandle containing all the strings returned by
218 # the plain text program extractor
219 open($fh, "$filter $in |") or print "$filter $in : $!";
220 next $in if !defined $fh;
222 # Processes every string returned
223 while(my $str = <$fh>)
225 $str =~ s/[\n\r\f]+$//; # chomps the trailing \n (or <cr><lf> if file was edited with Windows)
226 $str =~ s/^\s+//; # remove trailing blanks, ':' or '*'
227 $str =~ s/\s*\**:*\s*$//;
229 # the line begins with letter(s) followed by optional words and/or spaces
230 if($str =~ /^[ ]*[\w]+[ \w]*/)
232 # the line is to be excluded ?
233 if( !(defined($exclude) && ($str =~ /$exclude/o) && $str>0) )
235 if( !defined(%{$strhash}->{$str}) )
237 # the line is not already in the list so add it
238 %{$strhash}->{$str}=1;
250 #####################################################
251 # Reads the input file and returns a generated hash #
252 #####################################################
256 my($strhash, $str_file, $split_char) = @_;
260 open($fh, "< $str_file") or die "$str_file : $!";
262 print "Restoring string list from $str_file...\n";
264 while( my $line = <$fh> )
268 # extracts the two fields
269 my ($original, $translated) = split(/$split_char/, $line, 2);
271 if($translated ne "*****")
273 # the key has been translated
274 %{$strhash}->{$original} = $translated;
278 # the key exist but has no translation.
279 %{$strhash}->{$original} = 1;
289 #########################################
290 # Writes the string hashtable to a file #
291 #########################################
295 my($strhash, $str_file, $split_char) = @_;
299 # Opens a handle for saving the list
300 open($fh, "> $str_file") or die "$str_file : $!";
302 print "Writing string list to $str_file...\n";
304 foreach my $str(sort {uc($a) cmp uc($b) || length($a) <=> length($b)} keys %{$strhash})
306 if(%{$strhash}->{$str} != 1)
308 printf($fh "%s%s%s\n", $str, $split_char, %{$strhash}->{$str});
312 printf($fh "%s%s%s\n", $str, $split_char,"*****") unless ($str >0);
319 ########################################################
320 # List the contents of dir matching the pattern *.type #
321 ########################################################
325 my($in_files, $dir, $type, $recursive) = @_;
328 # my @types = split(/ /,$type);
329 opendir($dir_h, $dir) or warn("Can't open $dir : $!\n");
331 my @tmp_list = grep(!/^\.\.?$/, readdir($dir_h));
335 foreach my $tmp_file (@tmp_list)
338 if( $recursive && (-d "$dir/$tmp_file") ) # entry is a directory
340 @{$in_files} = listfiles($in_files, "$dir/$tmp_file", $type);
342 elsif( $tmp_file =~ /\.$type$/ )
344 push(@{$in_files}, "$dir/$tmp_file");
350 ######################################
352 # Prints the contents of a hashtable #
353 ######################################
357 my($strhash, $split_char) = @_;
359 foreach my $str(sort keys %{$strhash})
361 if(%{$strhash}->{$str} != 1)
363 printf("%s%s%s\n", $str, $split_char, %{$strhash}->{$str});
367 printf("%s%s\n", $str, $split_char);
372 #########################################
373 # Short help messsage printing function #
374 #########################################
378 warn join(" ", @_)."\n" if @_;
381 Usage : $0 method -i input.tmpl|/input/dir -s strlist.file
382 [-o /output/dir] [options]
384 where method can be :
385 * create : creates the string list from scratch using the input files.
386 * update : updates an existing string list, adding the new strings to
387 the list, leaving the others alone.
388 * install : creates the new .tmpl files using the string list config file
389 (--outputdir must be used to specify the output directory).
391 Use $0 --help for a complete listing of options.
396 ##############################################
397 # Long help message describing every options #
398 ##############################################
403 Usage : $0 method [options]
405 where method can be :
406 * create : creates the string list from scratch using the input files.
407 * update : updates an existing string list, adding the new strings to
408 the list, leaving the others alone.
409 * install : creates the new .tmpl files using the string list config file
410 (-o must be used to specify the output directory).
415 Specify the input to process. Input can be a file or a directory.
416 When input is a directory, files matching the --type option will be
418 When using files, the parameter can be repeated to process a list
421 Example: $0 create -i foo.tmpl --input=bar.tmpl -s foobar.txt
424 Specify the file where the different strings will be stored.
427 Specify the output directory to use when generating the translated
431 Use the recursive mode to process every entry in subdirectories.
432 Note: Symbolic links used to link directories are not supported.
435 Defines the type of files to match when input is a directory.
436 By default --type=tmpl
439 Use this option to exclude some entries extracted by the program.
440 This option can be repeated to exclude many types of strings.
442 Example: $0 create -i foo.tmpl -s foo.txt --exclude=^\[0-9\]+\$
443 will create a list from foo.tmpl called foo.txt where lines
444 composed of numbers only are excluded. Special characters need to
448 Specify the program to use to extract plain text from files.
449 Default is str-extract which means str-extract must be in the path
453 Use this option to specify the char to be used to separate entries
454 in the string list file.