koha-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Koha-cvs] CVS: koha/misc/translator opac.fr,NONE,1.1 text-extract.pl,NO


From: Paul POULAIN
Subject: [Koha-cvs] CVS: koha/misc/translator opac.fr,NONE,1.1 text-extract.pl,NONE,1.1 tmpl_process.pl,NONE,1.1 translator_doc.txt,NONE,1.1
Date: Fri, 05 Dec 2003 08:53:48 -0800

Update of /cvsroot/koha/koha/misc/translator
In directory sc8-pr-cvs1:/tmp/cvs-serv16892/misc/translator

Added Files:
        opac.fr text-extract.pl tmpl_process.pl translator_doc.txt 
Log Message:
translator tool. see translator_doc.txt

--- NEW FILE ---
1       
10      
11      
12      
13      
14      
15      
16      
17      
18      
19      
2       
20      
2002    
2003    
2004    
2005    
2006    
21      
22      
23      
24      
25      
26      
27      
28      
29      
3       
30      
31      
4       
5       
6       
7       
8       
9       
Account for     Compte de
Additional Author:      Autres auteurs
Advanced Search, More Options   Recherche avancée
AMOUNT  COUT
An Error has Occurred   Une erreur s'est produite
Any     Tout
Apr     Avril
Are any of our records incorrect? Have you moved recently, got a new phone 
number or e-mail address?    Un changement à nous faire connaitre ?
ARE OUR RECORDS CORRECT?        Est-ce correct
Aug     Aout
Author  Auteur
Author: Auteur
Available       Disponible
BARCODE CODE BARRE
Barcode Code barre
bgcolor='#ffffcc' align=center> 
bgcolor='#ffffcc'>      
Biblio number:  Notice biblio :
BIBLIO RECORD   Notice bibliographique
Biblionumber:   Numéro notice :
Cancelled:      Annulé
Cannot be Reserved      Non réservable
Cardnumber:     N° de carte
Catalogue Search        Recherche catalogue
Charges Charges
City    Ville
Class   Classe
Classification: 
Collection:     
Compact Disc    
Copies  Copies
Current Branch: Annexe
Current Loan    Prêt
Date Due        Date retour
Date:   
Day     Jour
Dec     
Dewey:  
Due date        Date retour
Easy / Picture Books    
Easy Reader     Lecture facile
Email   Mail
End reserve on this date:       Annuler réservation à cette date
Exact   
Feb     Fev
Fiction 
FINES & CHARGES Dettes
Firstname       Prénom
GROUP - GROUPE
Group Number:   Numéro groupe :
Hi      Bonjour,
Home    Accueil
Home Branch:    Annexe propriétaire
Home phone      Téléphone maison
Illus:  
Illustrator     Illustrateur
in      dans
input{font-size:16px}   
ISBN:   
Item Count      Nombre d'ouvrages
Item lost:      Ouvrage perdu
Item Type       Type d'ouvrage
Item Type:      Type d'ouvrage :
items currently issued. Ouvrage en prêt actuellement
items currently reserved.       Ouvrages réservés actuellement
Itemtype        Type d'ouvrage
Jan     Jan
Join    Rejoindre
Jul     Juill
Jun     Juin
Junior Fiction  
Junior Non-Fiction      
Keywords        Mot-clefs
KOHA    
Koha Login      Identifiant Koha
KOHA: Become a Member   KOHA : s'abonner
KOHA: Catalogue Search  Recherche catalogue
Koha: Horowhenua Library Trust Catalogue and Member Services    Koha, catalogue 
et outils abonnés
KOHA: Members Area      Zone abonnés
KOHA: OPAC Catalogue Search     Recherche OPAC
Last borrowed:  Dernier prêt
Last Borrower 1:        Dernier emprunteur 1
Last Borrower 2:        Dernier emprunteur 2
Last Seen       Vu
Last seen:      Vu :
Library Card:   Carte lecteur
Loan Length:    Durée prêt
Location        Localisation
Log In  S'identifier
Log In to Koha  S'identifier
Log Out Déconnecter
Logged in as:   Connecté en tant que :
Logged in as:   Connecté en tant que: 
Logged in as:  [        
Logout  Déconnecter
Mar     Mars
May     Mai
Members Home    Accueil lecteur
Month   Mois
Next Records    Enregistrement suivant
No      Non
No. of Items:   N° ouvrage
Non-Fiction     
Normal  Normal
Not Reservable  Non réservable
Note that if you enter a value in Keyword and a value somewhere else, only 
keyword will be used Notez que le mot clef est prioritaire
Note there will be a reserve charge of  Il y aura des frais de réservation de
Notes:  Notes
Nov     
Oct     
of      de
OK Start Search 
on issue bit    En prêt ?
Online  En ligne
OR :    OU
OR one or more from :   OU un ou plus de :
Pages:  
Paid for:       Payé pour :
Password:       Mot de passe :
pick up at:     Prendre à :
Place:  
Please confirm that you wish to request an item of these types: Confirmez que 
vous souhaitez réserver un ouvrage :
Please select the branch from which you want to collect the item:       
Sélectionnez l'annexe ou vous prendrez l'ouvrage
Please select which item types are ok for you. The first of these item that 
matches one of these types that becomes available will be set kept for you. 
Sélectionnez les types d'ouvrages souhaités. Le premier disponible sera gardé 
pour vous.
Please, change what's needed. An email will be sent to the library.      
Changer le nécessaire
Previous Records        Précédents
Published by :  Publié par
Publisher:      Editions
records.        lignes
Reference Books 
Renewals:       Renouvellements
Rental Charge:  Coût du prêt
Replacement Price:      Coût de remplacement
Request Demande
Reserve date    Date réservation
Reserve on this date:   Réserver à cette date :
Reserve page for item:  Réservation de l'ouvrage :
reserves already on this item.  Réservations déjà faites sur cet ouvrage
reserves.       Réservations
Results Résultats
Results  through  of  records.  
results found   Réponses trouvées
Search  IGNORE
search  IGNORE
Search the Catalogue    Chercher dans le catalogue
Sep     Sep
Serial: Périodique
Size:   Taille
Something new ? quelque chose à modifier ?
Sorry, KOHA doesnt think you have permission for this page      INTERDIT !
Sorry, KOHA doesnt think you have permission for this page.     INTERDIT
Sorry, there were no results    Désolé, aucun résultat !
Sorry, you cannot make more than        Impossible de faire plus de
Sorry, you cannot make more than  reserves.     Désolé, vous ne pouvez pas 
faire plus de réservations
Sorry, you cannot make reserves because you owe Vous ne pouvez réserver parce 
que vous devez
Sorry, you cannot make reserves because you owe .       DESOLE
Sorry, your session has timed out, please login again.  Déconnecté. Identifiez 
vous à nouveau.
STILL OWING     EN ATTENTE
Street address  Adresse postale
Subject Sujet
Subject:        Sujet :
Subtitle:       Sous-titre
Surname Nom
Teacher Reference       Ref. prof.
text/html; charset=iso8859-1    
There are       Il y a
through à
Title   Titre
to Koha à Koha
Total Due       Total dû
Total Number of Items:  Nombre total d'exemplaires
Try another     Essayez un autre
Type in the box and press the enter key.        Saisissez et validez avec Entrée
Unititle:       Titre unifié
Update Record   Mettre à jour
URL:    URL
View Accounts   Voir compte
Volume: 
Website Site web
WELCOME TO THE  KOHA OPAC       Bienvenue dans l'OPAC de Koha
WELCOME TO THE KOHA OPAC        
Which is to be picked up from   Qui sera retiré à
Work/Fax phone  Tel bureau
Year    Année
Year :  Année :
Yes     Oui
YesNo   
You already have a reserve placed on this item. Vous avez déjà placé une 
réservation sur cet exemplaire
You are accessing koha from a different ip address! please login again. Vous 
avez changé d'adresse IP. Identifiez vous à nouveau
You did not specify any seach criteria  Vous n'avez pas spécifié de critère
You entered an incorrect username or password, please try again.        
Identifiant ou mot de passe erroné. Essayez encore.
You have        Vous avez
You have  items currently issued.       Vous avez exemplaires en prêt
You have  items currently reserved.     Vous avez exemplaires réservés
You have a credit of    Vous avez un crédit de
You have no items on issue.     Vous n'avez pas d'exemplaire en prêt
You have outstanding charges and fines of       Vous avez des dettes de
You have reserved items waiting:        Vouas avez des réservations en attente
You must select a branch for pickup!    Sélectionnez une annexe ou retirer 
l'ouvrage
You must select at least on item type!  Vous devez sélectionner au moins 1 type 
d'exemplaire
You searched on Recherche effectuée sur
Young Adult Fiction     
Your changes won't appear until the library has validated them. Vos changement 
n'apparaitront que lorsque la bibliothèque les aura validé

--- NEW FILE ---
#!/usr/bin/perl
use HTML::Tree;
use Getopt::Std;
getopt("f:");
        my $tree = HTML::TreeBuilder->new; # empty tree

        $tree->parse_file($opt_f);
        sub give_id {
                my $x = $_[0];
                foreach my $c ($x->content_list) {
                        next if (ref($c) && $c->tag() eq "~comment");
                        print "$c\n" unless ref($c);
                        if (ref($c) && $c->attr('alt')) {
                                print $c->attr('alt')."\n";
                        }
                        if (ref($c) && $c->tag() eq 'meta') {
                                print $c->attr('content')."\n ";
                        }
                        give_id($c) if ref $c; # ignore text nodes
                }
        };
        give_id($tree);
        $tree = $tree->delete;

--- NEW FILE ---
#!/usr/bin/perl

use strict;
use Getopt::Long;

my (@in_files, $str_file, $split_char, $recursive, $type, $out_dir, $in_dir, 
@excludes, $filter);
my $help;
my $exclude_regex;

$split_char = ' ';

GetOptions(
        'input|i=s'     => address@hidden,
        'outputdir|o=s' => \$out_dir,
        'str-file|s=s' => \$str_file,
        'recursive|r' => \$recursive,
        'filter=s' => \$filter,
        'type=s' => \$type,
        'exclude=s' => address@hidden,
        'sep=s' => \$split_char,
        'help'  => \$help);

help() if $help;

# utiliser glob() pour tous les fichiers d'un repertoire

my $action = shift or usage();
my %strhash = ();

# Checks for missing input and string list arguments

if( !defined(@in_files) || !defined($str_file) )
{
        usage("You must at least specify input and string list filenames.");
}

# Type match defaults to *.tmpl if not specified
$type = "tmpl|inc" if !defined($type);

$filter = "./text-extract.pl -f" if !defined($filter);
# Input is not a file nor a directory
if( !(-d $in_files[0]) && !(-f $in_files[0]))
{
        usage("Unknow input. Input must a file or a directory. (Symbolic links 
are not supported for the moment).");
}
elsif( -d $in_files[0] )
{
        # input is a directory, generates list of files to process
        $in_dir = $in_files[0];
        $in_dir =~ s/\/$//; # strips the trailing / if any

        print "Generating list of files to process...\n";
        
        @in_files = ();
        @in_files = &listfiles(address@hidden, $in_dir, $type, $recursive);
        
        if(scalar(@in_files) == 0)
        {
                warn "Nothing to process in $in_dir matching *.$type.";
                exit -1;
        }
}

# Generates the global exclude regular expression
$exclude_regex =  "(".join("|", @excludes).")" if @excludes;

if( $action eq "create" )
{
        # updates the list. As the list is empty, every entry will be added
        %strhash = &update_strhash(\%strhash, address@hidden, $exclude_regex, 
$filter);
        # saves the list to the file
        write_strhash(\%strhash, $str_file, "\t");
}
elsif( $action eq "update" )
{
        # restores the string list from file
        %strhash = &restore_strhash(\%strhash, $str_file, $split_char);
        # updates the list, adding new entries if any
        %strhash = &update_strhash(\%strhash, address@hidden, $exclude_regex, 
$filter);
        # saves the list to the file
        write_strhash(\%strhash, $str_file, $split_char);
}
elsif( $action eq "install" )
{
        if(!defined($out_dir))
        {
                usage("You must specify an output directory when using the 
install method.");
        }
        
        if( $in_dir eq $out_dir )
        {
                warn "You must specify a different input and output 
directory.\n";
                exit -1;
        }

        # restores the string list from file
        %strhash = &restore_strhash(\%strhash, $str_file, $split_char);
        # creates the new tmpl file using the new translation
        &install_strhash(\%strhash, address@hidden, $in_dir, $out_dir);
}
else
{
        usage("Unknown action specified.");
}

exit 0;

##########################################################
# Creates the new template files in the output directory #
##########################################################

sub install_strhash
{
        my($strhash, $in_files, $in_dir, $out_dir) = @_;

        my $fh_in; my $fh_out; # handles for input and output files
        my $tmp_dir; # temporary directory name (used to create destination dir)

        $out_dir =~ s/\/$//; # chops the trailing / if any.

        # Processes every entry found.
        foreach my $file (@{$in_files})
        {
                if( !open($fh_in, "< $file") )
                {
                        warn "Can't open $file : $!\n";
                        next;
                }

                # generates the name of the output file
                my $out_file = $file;

                if(!defined $in_dir)
                {
                        # processing single files not an entire directory
                        $out_file = "$out_dir/$file";
                }
                else
                {
                        $out_file =~ s/^$in_dir/$out_dir/;
                }

                my $slash = rindex($out_file, "\/");
                $tmp_dir = substr($out_file, 0, $slash); #gets the directory 
where the file will be saved

                # the file doesn't exist
                if( !(-f $tmp_dir) && !(-l $tmp_dir) && !(-e $tmp_dir) )
                {
                        if(!mkdir($tmp_dir,0775)) # creates with rwxrwxr-x 
permissions
                        {
                                warn("Make directory $tmp_dir : $!");
                                close($fh_in);
                                exit(1);
                        }
                }
                elsif((-f $tmp_dir) || (-l $tmp_dir))
                {
                        warn("Unable to create directory $tmp_dir.\n A file or 
symbolic link with the same name already exists.");
                        close($fh_in);
                        exit(1);
                }
                
                # opens handle for output
                if( !open($fh_out, "> $out_file") )
                {
                        warn "Can't write $out_file : $!\n";
                        close($fh_in);
                        next;
                }

                print "Generating $out_file...\n";

                while(my $line = <$fh_in>)
                {
                        foreach my $text (sort  {length($b) <=> length($a)} 
keys %{$strhash})
                        {
                                # Test if the key has been translated
                                if( %{$strhash}->{$text} != 1 )
                                {
                                        # Does the line contains text that 
needs to be changed ?
                                        if( $line =~ /$text/ && 
%{$strhash}->{$text} ne "IGNORE")
                                        {
                                                # changing text
                                                my $subst = 
%{$strhash}->{$text};
                                                $line =~ 
s/(\W)$text(\W)/$1$subst$2/g;
                                        }
                                }
                        }

                        # Writing the modified (or not) line to output
                        printf($fh_out "%s", $line);
                }

                close($fh_in);
                close($fh_out);
        }
}

########################################################
# Updates the string list hash with the new components #
########################################################

sub update_strhash
{
        my($strhash, $in_files, $exclude, $filter)= @_;

        my $fh;

        # Processes every file entries
        foreach my $in (@{$in_files})
        {

                print "Processing $in...\n";

                # Creates a filehandle containing all the strings returned by
                # the plain text program extractor
                open($fh, "$filter $in |") or print "$filter $in : $!";
                next $in if !defined $fh;

                # Processes every string returned
                while(my $str = <$fh>)
                {
                        $str =~ s/[\n\r\f]+$//; # chomps the trailing \n (or 
<cr><lf> if file was edited with Windows)
                        $str =~ s/^\s+//; # remove trailing blanks
                        $str =~ s/\s+$//;

                        # the line begins with letter(s) followed by optional 
words and/or spaces
                        if($str =~ /^[ ]*[\w]+[ \w]*/)
                        {
                                # the line is to be excluded ?
                                if( !(defined($exclude) && ($str =~ 
/$exclude/o) && $str>0) )
                                {
                                        if( !defined(%{$strhash}->{$str}) )
                                        {
                                                # the line is not already in 
the list so add it
                                                %{$strhash}->{$str} = 1;
                                        }
                                }
                        }
                }

                close($fh);
        }
        
        return %{$strhash};
}

#####################################################
# Reads the input file and returns a generated hash #
#####################################################

sub restore_strhash
{
        my($strhash, $str_file, $split_char) = @_;
        
        my $fh;
        
        open($fh, "< $str_file") or die "$str_file : $!";
        
        print "Restoring string list from $str_file...\n";
        
        while( my $line = <$fh> )
        {
                chomp $line;
                
                # extracts the two fields
                my ($original, $translated) = split(/$split_char/, $line, 2);

                if($translated ne "")
                {
                        # the key has been translated
                        %{$strhash}->{$original} = $translated;
                }
                else
                {
                        # the key exist but has no translation.
                        %{$strhash}->{$original} = 1;
                }
                
        }
        
        close($fh);
        
        return %{$strhash};
}

#########################################
# Writes the string hashtable to a file #
#########################################

sub write_strhash
{
        my($strhash, $str_file, $split_char) = @_;

        my $fh;

        # Opens a handle for saving the list
        open($fh, "> $str_file") or die "$str_file : $!";

        print "Writing string list to $str_file...\n";

        foreach my $str(sort {uc($a) cmp uc($b) || length($a) <=> length($b)} 
keys %{$strhash})
        {
                if(%{$strhash}->{$str} != 1)
                {
                        printf($fh "%s%s%s\n", $str, $split_char, 
%{$strhash}->{$str});
                }
                else
                {
                        printf($fh "%s%s\n", $str, $split_char);
                }
        }

        close($fh);
}

########################################################
# List the contents of dir matching the pattern *.type #
########################################################

sub listfiles
{
        my($in_files, $dir, $type, $recursive) = @_;

        my $dir_h;
#       my @types = split(/ /,$type);
        opendir($dir_h, $dir) or warn("Can't open $dir : $!\n");

        my @tmp_list = grep(!/^\.\.?$/, readdir($dir_h));

        closedir($dir_h);

        foreach my $tmp_file (@tmp_list)
        {

                if( $recursive && (-d "$dir/$tmp_file") ) # entry is a directory
                {
                        @{$in_files} = listfiles($in_files, "$dir/$tmp_file", 
$type);
                }
                elsif( $tmp_file =~ /\.$type$/ )
                {
                        push(@{$in_files}, "$dir/$tmp_file");
                }
        }
        return @{$in_files};
}

######################################
# DEBUG ROUTINE                      #
# Prints the contents of a hashtable #
######################################

sub print_strhash
{
        my($strhash, $split_char) = @_;
        
        foreach my $str(sort keys %{$strhash})
        {
                if(%{$strhash}->{$str} != 1)
                {
                        printf("%s%s%s\n", $str, $split_char, 
%{$strhash}->{$str});
                }
                else
                {
                        printf("%s%s\n", $str, $split_char);
                }
        }
}       

#########################################
# Short help messsage printing function #
#########################################

sub usage
{
        warn join(" ", @_)."\n" if @_;
        warn <<EOF;

Usage : $0 method -i input.tmpl|/input/dir -s strlist.file
        [-o /output/dir] [options]

where method can be :
  * create : creates the string list from scratch using the input files.
  * update : updates an existing string list, adding the new strings to
             the list, leaving the others alone.
  * install : creates the new .tmpl files using the string list config file
              (--outputdir must be used to specify the output directory).

Use $0 --help for a complete listing of options.
EOF
        exit(1);
}

##############################################
# Long help message describing every options #
##############################################

sub help
{
        warn <<EOF;
Usage : $0 method [options]
        
where method can be :
  * create : creates the string list from scratch using the input files.
  * update : updates an existing string list, adding the new strings to
             the list, leaving the others alone.
  * install : creates the new .tmpl files using the string list config file
              (-o must be used to specify the output directory).

options can be :

  -i or --input=
     Specify the input to process. Input can be a file or a directory.
     When input is a directory, files matching the --type option will be
     processed.
     When using files, the parameter can be repeated to process a list
     of files.
   
  Example: $0 create -i foo.tmpl --input=bar.tmpl -s foobar.txt

  -s or --str-file=
     Specify the file where the different strings will be stored.

  -o or --outputdir=
     Specify the output directory to use when generating the translated
     input files.

  -r or --recursive=
     Use the recursive mode to process every entry in subdirectories.
     Note: Symbolic links used to link directories are not supported.

  --type=
     Defines the type of files to match when input is a directory.
     By default --type=tmpl

  --exclude=regex
     Use this option to exclude some entries extracted by the program.
     This option can be repeated to exclude many types of strings.

  Example: $0 create -i foo.tmpl -s foo.txt --exclude=^\[0-9\]+\$
   will create a list from foo.tmpl called foo.txt where lines
   composed of numbers only are excluded. Special characters need to
   be escaped.

  --filter=
     Specify the program to use to extract plain text from files.
     Default is str-extract which means str-extract must be in the path
     in order to use it.

  --sep=char
     Use this option to specify the char to be used to separate entries
     in the string list file.

  --help
     This help message.
EOF
        exit(0);
}

--- NEW FILE ---
TRANSLATION TOOL :
============
This transation tool should greatly help Koha translators.
It's composed of 2 script :
* test-extract.pl, that extracts the texts in a template. It is called by
* tmpl_process.
tmpl process can do 3 things :
- create a file with all sentences all files in a directory (& it's 
subdirectories)
- update an existing translation file.
- rebuild translated templates from english & translation file.

Call tmpl_process --help to get full explanations.

HOW TO TRANSLATE Koha :
============
1- create your translation file :
./tmpl_process.pl update -i 
/home/paul/koha.dev/koha/koha-tmpl/opac-tmpl/default/en/ -s opac.fr -r
2- translate your opac.fr file (english & french being separated by a tab
3- create your translated version :
./tmpl_process.pl install -i 
/home/paul/koha.dev/koha/koha-tmpl/opac-tmpl/default/en/ -o 
/home/paul/koha.dev/koha/koha-tmpl/opac-tmpl/default/fr2/ -s opac.fr -r
4- copy images in your new directory (as they are NOT moved by tmpl_process.pl 
install)

If something changes in english version, go back to pt1 & repeat.

WEAKNESSES
=======
I've found some weaknesses (some solvable probably, but maybe some unsolvable)
- HTML::Templates pb :
 if there is only a <TMPL* > tag between 2 strings, text-extract sometimes 
merges both strings, and so can't replace them in the translated template. I've 
solved all those cases with a <br/> or another HTML statement.

- SHORT STATEMENTS
 short statements (like "in") can be replaced stupidly (like in cgi-bin => 
gives cgi-bdans in french). the workaround has been to replace only complete 
words (
line 185 of tmpl_process :
$line =~ s/(\W)$text(\W)/$1$subst$2/g;
)
Don't seem to have any side effect.

- WORD exist in FILENAME
words that are in the templates and in a perl script name are replaced !
For example : Search is replace by Recherche in french, thus,giving <a 
href="cgi-bin/opac-Recherche.pl">, which is wrong...
The only way I've found to solve this is to ignore any translation whose 
translation string is IGNORE
(search is the only cas i've found in french opac)

- MISSING STRINGS
Maybe some strings that should be translated are missing.
You can add whatever you want in text-extract.pl.
For instance, it extracts :
- standard text
- text in alt="SOMETEXT"
- meta html encoding (8859-1) to enable non european translations.

COPYRIGHT
======
@ paul poulain (paul.poulain address@hidden free.fr) & Jerome Vizcaino vizcainj 
address@hidden esiee.fr




reply via email to

[Prev in Thread] Current Thread [Next in Thread]