diff options
author | Lucie Gérard <lucie.gerard@qt.io> | 2023-08-30 10:14:03 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-09-13 16:27:58 +0000 |
commit | de619b5eec88a677e51d206fb32b5eb47a018108 (patch) | |
tree | e1a8d4865f2433e4d14fbe72814d6cbc151e25b5 | |
parent | 9d201a41af62a9559fa242846c60b4d5e11faa03 (diff) |
lupdate: remove number heuristics
Adapt the troll print example
[ChangeLog][lupdate][Important Behavior Changes] Removed the
number heuristics feature. Users are advised to avoid hard-coded
numbers in translatable strings and use QString::arg instead.
Pick-to: 6.5
Task-number: QTBUG-115962
Change-Id: I64e920e7b6496924f2c1ee6d07bea6e73964177a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit cda38d3d08e689deab506a11ed8c54a04d3f40d4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | examples/linguist/doc/src/trollprint.qdoc | 19 | ||||
-rw-r--r-- | examples/linguist/trollprint/mainwindow.cpp | 8 | ||||
-rw-r--r-- | examples/linguist/trollprint/trollprint_pt.ts | 12 | ||||
-rw-r--r-- | src/linguist/linguist/doc/src/linguist-manual.qdoc | 2 | ||||
-rw-r--r-- | src/linguist/lupdate/lupdate.1 | 2 | ||||
-rw-r--r-- | src/linguist/lupdate/lupdate.h | 1 | ||||
-rw-r--r-- | src/linguist/lupdate/main.cpp | 6 | ||||
-rw-r--r-- | src/linguist/lupdate/merge.cpp | 216 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt | 5 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp | 6 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before | 16 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result | 12 |
12 files changed, 20 insertions, 285 deletions
diff --git a/examples/linguist/doc/src/trollprint.qdoc b/examples/linguist/doc/src/trollprint.qdoc index fc664594a..868bf69b1 100644 --- a/examples/linguist/doc/src/trollprint.qdoc +++ b/examples/linguist/doc/src/trollprint.qdoc @@ -195,20 +195,6 @@ Linguist}. The following items are of special interest: \list - \li \c MainWindow - \list - \li Troll Print 1.0 - marked "(obs.)", obsolete - \li About Troll Print 1.0 - marked "(obs.)", obsolete - \li Troll Print 1.0. Copyright 1999 Software, Inc. - - marked obsolete - \li Troll Print 1.1 - automatically translated as - "Troll Imprimir 1.1" - \li About Troll Print 1.1 - automatically translated as - "Troll Imprimir 1.1" - \li Troll Print 1.1. Copyright 1999-2000 Software, - Inc. - automatically translated as "Troll Imprimir 1.1. - Copyright 1999-2000 Software, Inc." - \endlist \li \c PrintPanel \list \li 2-sided - marked "(obs.)", obsolete @@ -217,8 +203,9 @@ \endlist \endlist - Notice that \c lupdate works hard behind the scenes to make revisions - easier, and it's pretty smart with numbers. + In order to make revisions easier, instead of tr("Troll Print 1.0") + you can use tr("Troll Print %1").arg("1.0") or such to avoid having to update + the string on every release. Go over the translations in \c MainWindow and mark these as "done". Translate "\<b\>TROLL PRINT\</b\>" as "\<b\>TROLL IMPRIMIR\</b\>". diff --git a/examples/linguist/trollprint/mainwindow.cpp b/examples/linguist/trollprint/mainwindow.cpp index d5503b258..b0a411dc5 100644 --- a/examples/linguist/trollprint/mainwindow.cpp +++ b/examples/linguist/trollprint/mainwindow.cpp @@ -15,15 +15,15 @@ MainWindow::MainWindow() createMenus(); //! [0] - setWindowTitle(tr("Troll Print 1.0")); + setWindowTitle(tr("Troll Print %1").arg("1.0")); //! [0] } void MainWindow::about() { - QMessageBox::information(this, tr("About Troll Print 1.0"), - tr("Troll Print 1.0.\n\n" - "Copyright 1999 Software, Inc.")); + QMessageBox::information(this, tr("About Troll Print %1").arg("1.0"), + tr("Troll Print %1.\n\n" + "Copyright 1999 Software, Inc.").arg("1.0")); } //! [1] diff --git a/examples/linguist/trollprint/trollprint_pt.ts b/examples/linguist/trollprint/trollprint_pt.ts index e5871bd08..82165ffd3 100644 --- a/examples/linguist/trollprint/trollprint_pt.ts +++ b/examples/linguist/trollprint/trollprint_pt.ts @@ -2,8 +2,8 @@ <context> <name>MainWindow</name> <message> - <source>Troll Print 1.0</source> - <translation>Troll Imprimir 1.0</translation> + <source>Troll Print %1</source> + <translation>Troll Imprimir %1</translation> </message> <message> <source>E&xit</source> @@ -26,14 +26,14 @@ <translation>A&juda</translation> </message> <message> - <source>About Troll Print 1.0</source> - <translation>Sobre Troll Imprimir 1.0</translation> + <source>About Troll Print %1</source> + <translation>Sobre Troll Imprimir %1</translation> </message> <message> - <source>Troll Print 1.0. + <source>Troll Print %1. Copyright 1999 Software, Inc.</source> - <translation>Troll Imprimir 1.0 + <translation>Troll Imprimir %1 Copyright 1999 Software, Inc.</translation> </message> diff --git a/src/linguist/linguist/doc/src/linguist-manual.qdoc b/src/linguist/linguist/doc/src/linguist-manual.qdoc index cd026b40b..fe557048e 100644 --- a/src/linguist/linguist/doc/src/linguist-manual.qdoc +++ b/src/linguist/linguist/doc/src/linguist-manual.qdoc @@ -279,7 +279,7 @@ \li \c {-no-ui-lines} \li Do not record line numbers in references to UI files. \row - \li \c {-disable-heuristic {sametext|similartext|number}} + \li \c {-disable-heuristic {sametext|similartext}} \li Disable the named merge heuristic. Can be specified multiple times. \row \li \c {-project <filename>} diff --git a/src/linguist/lupdate/lupdate.1 b/src/linguist/lupdate/lupdate.1 index 861e5bfee..a866965ca 100644 --- a/src/linguist/lupdate/lupdate.1 +++ b/src/linguist/lupdate/lupdate.1 @@ -28,7 +28,7 @@ used with version control systems if required. .PP .SH OPTIONS .TP -.I "-disable-heuristic {sametext|similartext|number}" +.I "-disable-heuristic {sametext|similartext}" Disable the named merge heuristic. Can be specified multiple times. .TP .I "-extensions <ext>[,<ext>...]" diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h index 6b7b25e02..5cc0f8c2b 100644 --- a/src/linguist/lupdate/lupdate.h +++ b/src/linguist/lupdate/lupdate.h @@ -27,7 +27,6 @@ enum UpdateOption { NoSort = 8, HeuristicSameText = 16, HeuristicSimilarText = 32, - HeuristicNumber = 64, AbsoluteLocations = 256, RelativeLocations = 512, NoLocations = 1024, diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp index e3d83b7d2..0ebe43214 100644 --- a/src/linguist/lupdate/main.cpp +++ b/src/linguist/lupdate/main.cpp @@ -254,7 +254,7 @@ static void printUsage() " Default is absolute for new files.\n" " -no-ui-lines\n" " Do not record line numbers in references to UI files.\n" - " -disable-heuristic {sametext|similartext|number}\n" + " -disable-heuristic {sametext|similartext}\n" " Disable the named merge heuristic. Can be specified multiple times.\n" " -project <filename>\n" " Name of a file containing the project's description in JSON format.\n" @@ -728,7 +728,7 @@ int main(int argc, char **argv) UpdateOptions options = Verbose | // verbose is on by default starting with Qt 4.2 - HeuristicSameText | HeuristicSimilarText | HeuristicNumber; + HeuristicSameText | HeuristicSimilarText; int numFiles = 0; bool metTsFlag = false; bool metXTsFlag = false; @@ -799,8 +799,6 @@ int main(int argc, char **argv) options &= ~HeuristicSameText; } else if (arg == QLatin1String("similartext")) { options &= ~HeuristicSimilarText; - } else if (arg == QLatin1String("number")) { - options &= ~HeuristicNumber; } else { printErr(u"Invalid heuristic name passed to -disable-heuristic.\n"_s); return 1; diff --git a/src/linguist/lupdate/merge.cpp b/src/linguist/lupdate/merge.cpp index 273ace6ad..f204fc73d 100644 --- a/src/linguist/lupdate/merge.cpp +++ b/src/linguist/lupdate/merge.cpp @@ -14,212 +14,6 @@ QT_BEGIN_NAMESPACE -static bool isDigitFriendly(QChar c) -{ - return c.isPunct() || c.isSpace(); -} - -static int numberLength(const QString &s, int i) -{ - if (i >= s.size() || !s.at(i).isDigit()) - return 0; - - int pos = i; - do { - ++i; - } while (i < s.size() - && (s.at(i).isDigit() - || (isDigitFriendly(s[i]) - && i + 1 < s.size() - && (s[i + 1].isDigit() - || (isDigitFriendly(s[i + 1]) - && i + 2 < s.size() - && s[i + 2].isDigit()))))); - return i - pos; -} - - -/* - Returns a version of 'key' where all numbers have been replaced by zeroes. If - there were none, returns "". -*/ -static QString zeroKey(const QString &key) -{ - QString zeroed; - bool metSomething = false; - - for (int i = 0; i < key.size(); ++i) { - int len = numberLength(key, i); - if (len > 0) { - i += len; - zeroed.append(QLatin1Char('0')); - metSomething = true; - } else { - zeroed.append(key.at(i)); - } - } - return metSomething ? zeroed : QString(); -} - -static QString translationAttempt(const QString &oldTranslation, - const QString &oldSource, const QString &newSource) -{ - int p = zeroKey(oldSource).count(QLatin1Char('0')); - QString attempt; - QStringList oldNumbers; - QStringList newNumbers; - QList<bool> met(p); - QList<int> matchedYet(p); - int i, j; - int k = 0, ell, best; - int m, n; - int pass; - - /* - This algorithm is hard to follow, so we'll consider an example - all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0" - and newSource is "XeT 3.1". - - First, we set up two tables: oldNumbers and newNumbers. In our - example, oldNumber[0] is "3.0" and newNumber[0] is "3.1". - */ - for (i = 0, j = 0; i < oldSource.size(); i++, j++) { - m = numberLength(oldSource, i); - n = numberLength(newSource, j); - if (m > 0) { - oldNumbers.append(oldSource.mid(i, m + 1)); - newNumbers.append(newSource.mid(j, n + 1)); - i += m; - j += n; - met[k] = false; - matchedYet[k] = 0; - k++; - } - } - - /* - We now go over the old translation, "XeT 3.0", one letter at a - time, looking for numbers found in oldNumbers. Whenever such a - number is met, it is replaced with its newNumber equivalent. In - our example, the "3.0" of "XeT 3.0" becomes "3.1". - */ - for (i = 0; i < oldTranslation.size(); i++) { - attempt += oldTranslation[i]; - for (k = 0; k < p; k++) { - if (matchedYet[k] < oldNumbers[k].size() && - oldTranslation[i] == oldNumbers[k][matchedYet[k]]) { - matchedYet[k]++; - } else { - matchedYet[k] = 0; - } - } - - /* - Let's find out if the last character ended a match. We make - two passes over the data. In the first pass, we try to - match only numbers that weren't matched yet; if that fails, - the second pass does the trick. This is useful in some - suspicious cases, flagged below. - */ - for (pass = 0; pass < 2; pass++) { - best = p; // an impossible value - for (k = 0; k < p; k++) { - if ((!met[k] || pass > 0) && - matchedYet[k] == oldNumbers[k].size() && - numberLength(oldTranslation, i + 1 - matchedYet[k]) == matchedYet[k]) { - // the longer the better - if (best == p || matchedYet[k] > matchedYet[best]) - best = k; - } - } - if (best != p) { - attempt.truncate(attempt.size() - matchedYet[best]); - attempt += newNumbers[best]; - met[best] = true; - for (k = 0; k < p; k++) - matchedYet[k] = 0; - break; - } - } - } - - /* - We flag two kinds of suspicious cases. They are identified as - such with comments such as "{2000?}" at the end. - - Example of the first kind: old source text "TeX 3.0" translated - as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the - new text is. - */ - for (k = 0; k < p; k++) { - if (!met[k]) - attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String("?}"); - } - - /* - Example of the second kind: "1 of 1" translated as "1 af 1", - with new source text "1 of 2", generates "1 af 2 {1 or 2?}" - because it's not clear which of "1 af 2" and "2 af 1" is right. - */ - for (k = 0; k < p; k++) { - for (ell = 0; ell < p; ell++) { - if (k != ell && oldNumbers[k] == oldNumbers[ell] && - newNumbers[k] < newNumbers[ell]) - attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String(" or ") + - newNumbers[ell] + QLatin1String("?}"); - } - } - return attempt; -} - - -/* - Augments a Translator with translations easily derived from - similar existing (probably obsolete) translations. - - For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1" - has no translation, "XeT 3.1" is added to the translator and is - marked Unfinished. - - Returns the number of additional messages that this heuristic translated. -*/ -int applyNumberHeuristic(Translator &tor) -{ - QMap<QString, QPair<QString, QString> > translated; - QList<bool> untranslated(tor.messageCount()); - int inserted = 0; - - for (int i = 0; i < tor.messageCount(); ++i) { - const TranslatorMessage &msg = tor.message(i); - bool hasTranslation = msg.isTranslated(); - if (msg.type() == TranslatorMessage::Unfinished) { - if (!hasTranslation) - untranslated[i] = true; - } else if (hasTranslation && msg.translations().size() == 1) { - const QString &key = zeroKey(msg.sourceText()); - if (!key.isEmpty()) - translated.insert(key, qMakePair(msg.sourceText(), msg.translation())); - } - } - - for (int i = 0; i < tor.messageCount(); ++i) { - if (untranslated[i]) { - TranslatorMessage &msg = tor.message(i); - const QString &key = zeroKey(msg.sourceText()); - if (!key.isEmpty()) { - const auto t = translated.constFind(key); - if (t != translated.constEnd() && t->first != msg.sourceText()) { - msg.setTranslation(translationAttempt(t->second, t->first, - msg.sourceText())); - inserted++; - } - } - } - } - return inserted; -} - - /* Augments a Translator with trivially derived translations. @@ -493,13 +287,6 @@ Translator merge( */ int sameTextHeuristicCount = (options & HeuristicSameText) ? applySameTextHeuristic(outTor) : 0; - /* - The number heuristic handles cases where a message has an - obsolete counterpart with mostly numbers differing in the - source text. - */ - int sameNumberHeuristicCount = (options & HeuristicNumber) ? applyNumberHeuristic(outTor) : 0; - if (options & Verbose) { int totalFound = neww + known; err += QStringLiteral(" Found %1 source text(s) (%2 new and %3 already existing)\n") @@ -513,9 +300,6 @@ Translator merge( } } - if (sameNumberHeuristicCount) - err += QStringLiteral(" Number heuristic provided %1 translation(s)\n") - .arg(sameNumberHeuristicCount); if (sameTextHeuristicCount) err += QStringLiteral(" Same-text heuristic provided %1 translation(s)\n") .arg(sameTextHeuristicCount); diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt index e363cc8cb..f8c994f34 100644 --- a/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt +++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt @@ -1,5 +1,4 @@ Updating 'project\.ts'\.\.\. - Found 4 source text\(s\) \(4 new and 0 already existing\) - Removed 6 obsolete entries - Number heuristic provided 2 translation\(s\) + Found 2 source text\(s\) \(2 new and 0 already existing\) + Removed 4 obsolete entries Same-text heuristic provided 1 translation\(s\) diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp index 0915b556c..ef37410ec 100644 --- a/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp @@ -36,17 +36,11 @@ class A: public QObject { Q_OBJECT void foo() { - // number Heuristics - tr("version 2.0 now"); - // same text match tr("this is the matched same text"); // failed same text tr("this is the non-matched same text"); - - // number heuristics QTBUG-111775 - tr("1xb"); } }; diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before index ca731d961..2d1b201a9 100644 --- a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before +++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before @@ -2,14 +2,6 @@ <!DOCTYPE TS> <TS version="2.0" language="de_DE"> <context> - <name>A</name> - <message> - <location filename="main.cpp" line="53"/> - <source>version 1.0 now</source> - <translation>teraz wersja 1.0</translation> - </message> -</context> -<context> <name>B</name> <message> <location filename="main.cpp" line="56"/> @@ -35,12 +27,4 @@ <translation>völlig andere variante des reinfalls mit same-text</translation> </message> </context> -<context> - <name>D</name> - <message> - <location filename="main.cpp" line="62"/> - <source>1ab</source> - <translation>1ab</translation> - </message> -</context> </TS> diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result index 546d1f1f4..3c150a30c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result @@ -5,23 +5,13 @@ <name>A</name> <message> <location filename="main.cpp" line="40"/> - <source>version 2.0 now</source> - <translation type="unfinished">teraz wersja 1.0 {2.0 ?}</translation> - </message> - <message> - <location filename="main.cpp" line="43"/> <source>this is the matched same text</source> <translation type="unfinished">der same-text-treffer</translation> </message> <message> - <location filename="main.cpp" line="46"/> + <location filename="main.cpp" line="43"/> <source>this is the non-matched same text</source> <translation type="unfinished"></translation> </message> - <message> - <location filename="main.cpp" line="49"/> - <source>1xb</source> - <translation type="unfinished">1ab {1x?}</translation> - </message> </context> </TS> |