[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/support/lupdate-ezpublish3/ -> numberh.cpp (source)

   1  /**********************************************************************
   2  **   Copyright (C) 2000 Trolltech AS.  All rights reserved.
   3  **
   4  **   numberh.cpp
   5  **
   6  **   This file is part of Qt Linguist.
   7  **
   8  **   See the file LICENSE included in the distribution for the usage
   9  **   and distribution terms.
  10  **
  11  **   The file is provided AS IS with NO WARRANTY OF ANY KIND,
  12  **   INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
  13  **   A PARTICULAR PURPOSE.
  14  **
  15  **********************************************************************/
  16  
  17  #include <qmemarray.h>
  18  #include <qcstring.h>
  19  #include <qmap.h>
  20  #include <qstringlist.h>
  21  
  22  #include <ctype.h>
  23  #include <metatranslator.h>
  24  
  25  typedef QMap<QCString, MetaTranslatorMessage> TMM;
  26  typedef QValueList<MetaTranslatorMessage> TML;
  27  
  28  static bool isDigitFriendly( int c )
  29  {
  30      return ispunct( c ) || isspace( c );
  31  }
  32  
  33  static int numberLength( const char *s )
  34  {
  35      int i = 0;
  36  
  37      if ( isdigit(s[0]) ) {
  38      do {
  39          i++;
  40      } while ( isdigit(s[i]) ||
  41            (isDigitFriendly(s[i]) &&
  42             (isdigit(s[i + 1]) ||
  43              (isDigitFriendly(s[i + 1]) && isdigit(s[i + 2])))) );
  44      }
  45      return i;
  46  }
  47  
  48  /*
  49    Returns a version of 'key' where all numbers have been replaced by zeroes.  If
  50    there were none, returns "".
  51  */
  52  static QCString zeroKey( const char *key )
  53  {
  54      QCString zeroed( strlen(key) + 1 );
  55      char *z = zeroed.data();
  56      int i = 0, j = 0;
  57      int len;
  58      bool metSomething = FALSE;
  59  
  60      while ( key[i] != '\0' ) {
  61      len = numberLength( key + i );
  62      if ( len > 0 ) {
  63          i += len;
  64          z[j++] = '0';
  65          metSomething = TRUE;
  66      } else {
  67          z[j++] = key[i++];
  68      }
  69      }
  70      z[j] = '\0';
  71  
  72      if ( metSomething )
  73      return zeroed;
  74      else
  75      return "";
  76  }
  77  
  78  static QString translationAttempt( const QString& oldTranslation,
  79                     const char *oldSource,
  80                     const char *newSource )
  81  {
  82      int p = zeroKey( oldSource ).contains( '0' );
  83      int oldSourceLen = qstrlen( oldSource );
  84      QString attempt;
  85      QStringList oldNumbers;
  86      QStringList newNumbers;
  87      QMemArray<bool> met( p );
  88      QMemArray<int> matchedYet( p );
  89      int i, j;
  90      int k = 0, ell, best;
  91      int m, n;
  92      int pass;
  93  
  94      /*
  95        This algorithm is hard to follow, so we'll consider an example
  96        all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0"
  97        and newSource is "XeT 3.1".
  98  
  99        First, we set up two tables: oldNumbers and newNumbers. In our
 100        example, oldNumber[0] is "3.0" and newNumber[0] is "3.1".
 101      */
 102      for ( i = 0, j = 0; i < oldSourceLen; i++, j++ ) {
 103      m = numberLength( oldSource + i );
 104      n = numberLength( newSource + j );
 105      if ( m > 0 ) {
 106          oldNumbers.append( QCString(oldSource + i, m + 1) );
 107          newNumbers.append( QCString(newSource + j, n + 1) );
 108          i += m;
 109          j += n;
 110          met[k] = FALSE;
 111          matchedYet[k] = 0;
 112          k++;
 113      }
 114      }
 115  
 116      /*
 117        We now go over the old translation, "XeT 3.0", one letter at a
 118        time, looking for numbers found in oldNumbers. Whenever such a
 119        number is met, it is replaced with its newNumber equivalent. In
 120        our example, the "3.0" of "XeT 3.0" becomes "3.1".
 121      */
 122      for ( i = 0; i < (int) oldTranslation.length(); i++ ) {
 123      attempt += oldTranslation[i];
 124      for ( k = 0; k < p; k++ ) {
 125          if ( oldTranslation[i] == oldNumbers[k][matchedYet[k]] )
 126          matchedYet[k]++;
 127          else
 128          matchedYet[k] = 0;
 129      }
 130  
 131      /*
 132        Let's find out if the last character ended a match. We make
 133        two passes over the data. In the first pass, we try to
 134        match only numbers that weren't matched yet; if that fails,
 135        the second pass does the trick. This is useful in some
 136        suspicious cases, flagged below.
 137      */
 138      for ( pass = 0; pass < 2; pass++ ) {
 139          best = p; // an impossible value
 140          for ( k = 0; k < p; k++ ) {
 141          if ( (!met[k] || pass > 0) &&
 142               matchedYet[k] == (int) oldNumbers[k].length() &&
 143               numberLength(oldTranslation.latin1() + (i + 1) -
 144                    matchedYet[k]) == matchedYet[k] ) {
 145              // the longer the better
 146              if ( best == p || matchedYet[k] > matchedYet[best] )
 147              best = k;
 148          }
 149          }
 150          if ( best != p ) {
 151          attempt.truncate( attempt.length() - matchedYet[best] );
 152          attempt += newNumbers[best];
 153          met[best] = TRUE;
 154          for ( k = 0; k < p; k++ )
 155              matchedYet[k] = 0;
 156          break;
 157          }
 158      }
 159      }
 160  
 161      /*
 162        We flag two kinds of suspicious cases. They are identified as
 163        such with comments such as "{2000?}" at the end.
 164  
 165        Example of the first kind: old source text "TeX 3.0" translated
 166        as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the
 167        new text is.
 168      */
 169      for ( k = 0; k < p; k++ ) {
 170      if ( !met[k] )
 171          attempt += QString( " {" ) + newNumbers[k] + QString( "?}" );
 172      }
 173  
 174      /*
 175        Example of the second kind: "1 of 1" translated as "1 af 1",
 176        with new source text "1 of 2", generates "1 af 2 {1 or 2?}"
 177        because it's not clear which of "1 af 2" and "2 af 1" is right.
 178      */
 179      for ( k = 0; k < p; k++ ) {
 180      for ( ell = 0; ell < p; ell++ ) {
 181          if ( k != ell && oldNumbers[k] == oldNumbers[ell] &&
 182              newNumbers[k] < newNumbers[ell] )
 183          attempt += QString( " {" ) + newNumbers[k] + QString( " or " ) +
 184                 newNumbers[ell] + QString( "?}" );
 185      }
 186      }
 187      return attempt;
 188  }
 189  
 190  /*
 191    Augments a MetaTranslator with translations easily derived from
 192    similar existing (probably obsolete) translations.
 193  
 194    For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1"
 195    has no translation, "XeT 3.1" is added to the translator and is
 196    marked Unfinished.
 197  */
 198  void applyNumberHeuristic( MetaTranslator *tor, bool verbose )
 199  {
 200      TMM translated, untranslated;
 201      TMM::Iterator t, u;
 202      TML all = tor->messages();
 203      TML::Iterator it;
 204      int inserted = 0;
 205  
 206      for ( it = all.begin(); it != all.end(); ++it ) {
 207      if ( (*it).type() == MetaTranslatorMessage::Unfinished ) {
 208          if ( (*it).translation().isEmpty() )
 209          untranslated.insert( zeroKey((*it).sourceText()), *it );
 210      } else if ( !(*it).translation().isEmpty() ) {
 211          translated.insert( zeroKey((*it).sourceText()), *it );
 212      }
 213      }
 214  
 215      for ( u = untranslated.begin(); u != untranslated.end(); ++u ) {
 216      t = translated.find( u.key() );
 217      if ( t != translated.end() && !t.key().isEmpty() &&
 218           qstrcmp((*t).sourceText(), (*u).sourceText()) != 0 ) {
 219          MetaTranslatorMessage m( *u );
 220          m.setTranslation( translationAttempt((*t).translation(),
 221                           (*t).sourceText(),
 222                           (*u).sourceText()) );
 223          tor->insert( m );
 224          inserted++;
 225      }
 226      }
 227      if ( verbose && inserted != 0 )
 228      qWarning( " number heuristic provided %d translation%s",
 229            inserted, inserted == 1 ? "" : "s" );
 230  }


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7