Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
linguist-manual.qdoc
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \page qtlinguist-index.html
6 \title Qt Linguist Manual
7 \ingroup qttools
8 \ingroup internationalization
9 \brief Using Qt translation tools: lupdate, lrelease, and \QL.
10
11 \startpage {index.html}{Qt Reference Documentation}
12 \nextpage Release managers
13
14 \keyword Qt Linguist
15
16 Release managers, translators, and developers can use Qt tools to translate
17 Qt C++ and Qt Quick applications into local languages.
18
19 In addition to the Qt translation file (TS) format, \QL and \c lupdate
20 support XML Localization Interchange File Format (XLIFF).
21
22 \table
23 \row
24 \li \inlineimage front-publishing.png {Icon showing an publishing action}
25 \li \inlineimage front-ui.png {UI illustration showing Start buttons,
26 toggle controls, and a circular selector on a dark
27 screen}
28 \li \inlineimage front-coding.png {Illustration showing a code}
29 \row
30 \li \l{Release managers}
31 \li \l{Translators}
32 \li \l{Developers}
33 \row
34 \li
35 \list
36 \li \l {Creating translation files}
37 \li \l {Using lupdate}
38 \li \l {Using lrelease}
39 \li \l {Using lconvert}
40 \li \l {Using lcheck}
41 \endlist
42 \li
43 \list
44 \li \l {Qt Linguist user interface}
45 \li \l {Translating strings}
46 \li \l {Selecting context or label to translate}
47 \li \l {Selecting strings to translate}
48 \li \l {Viewing strings in context}
49 \li \l {Reusing translations}
50 \li \l {Validating translations}
51 \li \l {Translating multiple languages simultaneously}
52 \endlist
53 \li
54 \list
55 \li \l{TS file format}
56 \li \l{Text ID based translations}
57 \li \l{Meta strings reference}
58 \li \l{CMake Commands in Qt6 LinguistTools}{CMake commands}
59 \li \l{Examples}
60 \endlist
61 \endtable
62
63 The following video shows how to internationalize and localize a simple
64 example application:
65
66 \youtube xNIz78IPBu0
67*/
68
69/*!
70 \page linguist-toc.html
71 \title All topics
72
73 \list
74 \li \l{Release managers}
75 \list
76 \li \l {Creating translation files}
77 \li \l {Using lupdate}
78 \li \l {Using lrelease}
79 \endlist
80 \li \l{Translators}
81 \list
82 \li \l {Qt Linguist user interface}
83 \li \l {Translating strings}
84 \li \l {Selecting context or label to translate}
85 \li \l {Selecting strings to translate}
86 \li \l {Viewing strings in context}
87 \li \l {Reusing translations}
88 \li \l {Validating translations}
89 \li \l {Translating multiple languages simultaneously}
90 \endlist
91 \li \l{Developers}
92 \list
93 \li \l{TS file format}
94 \li \l{Text ID based translations}
95 \li \l{Meta strings reference}
96 \li \l{CMake Commands in Qt6 LinguistTools}{CMake commands}
97 \li \l{Examples}
98 \endlist
99 \endlist
100 */
101
102/*!
103 \page linguist-manager.html
104 \title Release managers
105
106 \previouspage Qt Linguist Manual
107 \nextpage Creating translation files
108
109 \image front-publishing.png {Icon showing an publishing action}
110
111 Release managers use \c lupdate to generate a set of translation source (TS)
112 files from the application source files (QML and C++) and pass them to
113 translators. The translators use \QL to translate the strings and pass the
114 TS files back to the release managers. They use \c lrelease to generate
115 compact versions of the TS files, called Qt message (QM) files, that are
116 ready for use by the application.
117
118 \list
119 \li \l {Creating translation files}
120 \li \l {Using lupdate}
121 \li \l {Using lrelease}
122 \endlist
123
124 You can use the tools in repeated cycles as applications change and evolve.
125 They preserve existing translations and make it easy to identify new strings.
126 In addition, you can use the \QL phrase books to consistently translate
127 multiple applications and projects.
128
129 You can configure CMake projects to automatically run \c lupdate and
130 \c lrelease when you build a project and generate TS and QM files for you.
131
132 You can use the Qt Design Studio
133 \l{https://doc-snapshots.qt.io/qtdesignstudio/studio-translations.html}
134 {Translations} view to test and manage \l {Text ID based translations}
135 {ID-based translations}.
136*/
137
138/*!
139 \page linguist-creating-ts-files.html
140
141 \previouspage Release managers
142 \nextpage Using lupdate
143
144 \title Creating translation files
145
146 Most of the text to translate in an application consists of either single
147 words or short phrases. These typically appear as window titles, menu
148 items, tooltips, and labels to buttons, check boxes, and radio buttons.
149
150 Developers mark the phrases as translatable in the QML and C++ source code.
151 The Qt tools provide context information for each of the phrases to help the
152 translator understand their meaning. The developer can add comments to the
153 phrases.
154
155 Translation files consist of all the user-visible text and \key Ctrl key
156 shortcuts in an application and translations of that text.
157
158 To create translation files:
159
160 \list 1
161
162 \li Run \c lupdate to generate the first set of translation source (TS)
163 files with all the user-visible text but no translations.
164
165 \li Give the TS files to translators who add translations using \QL.
166 \QL indicates changed and deleted source text.
167
168 \li Run \c lupdate to incorporate any new text added to the application.
169 \c lupdate synchronizes the user-visible text from the application
170 with the translations. Existing translations in the TS file are
171 preserved.
172
173 \li Run \c lrelease to read the TS files and produce the QM files used
174 by the application at runtime.
175
176 \endlist
177
178 For \c lupdate to work successfully, it must know which translation files to
179 produce. Specify the files in the application's Qt project file.
180
181 When building with CMake, you use \l{CMake Commands in Qt6 LinguistTools}
182 {CMake commands} to add targets that create or update TS files and transform
183 them into QM files. The translation files are generated when you build the
184 targets.
185*/
186
187/*!
188 \page linguist-lupdate.html
189 \target lupdate
190
191 \previouspage Release managers
192 \nextpage Using lrelease
193
194 \title Using lupdate
195
196 The \c lupdate command line tool finds translatable strings in C++ source,
197 C++ header, Java, Python, QML, and UI files and generates or updates TS
198 files.
199
200 When building with qmake, specify the files to process at the command line
201 or in a .pro file.
202
203 When building with CMake, use \l{CMake Commands in Qt6 LinguistTools}
204 {CMake commands} to add targets that create or update TS files and transform
205 them into QM files. The \c lupdate tool is run with the \l {lupdate options}
206 {options} you pass to the commands when you build the target.
207
208 For more information about specifying translations in project files, see
209 \l{Localizing Applications}.
210
211 \section1 lupdate syntax
212
213 \badcode
214 lupdate [options] [project-file]...
215 lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file
216 \endcode
217
218 Where:
219
220 \list
221 \li \c options means one or several \l {lupdate options}.
222 \li \c project-file is the project configuration file.
223 \li \c source-file is a file that contains translatable strings.
224 \li \c path is the path to a folder that contains translation
225 source files.
226 \li \c @lst-file reads additional file names (one per line) or
227 includepaths (one per line and prefixed with \c -I) from \e lst-file.
228 \li \c ts-files are the TS files to generate or update.
229 \endlist
230
231 To view the latest help, enter:
232
233 \badcode
234 lupdate -help
235 \endcode
236
237 \section2 lupdate options
238
239 \table
240 \header
241 \li Option
242 \li Action
243 \row
244 \li \c {-help}
245 \li Display up-to-date help information and exit.
246 \row
247 \li \c {-no-obsolete}
248 \li Drop all obsolete and vanished strings.
249 \row
250 \li \c {-extensions <ext>[,<ext>]...}
251 \li Process files with the given extensions, only. Use commas to
252 separate extensions in the list. Do not use whitespace. The default
253 value is:
254 \c {java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml,qrc}.
255 \row
256 \li \c {-pluralonly}
257 \li Only include plural form messages.
258 \row
259 \li \c {-silent}
260 \li Do not explain what is being done.
261 \row
262 \li \c {-no-sort}
263 \li Do not sort contexts in TS files.
264 \row
265 \li \c {-sort-messages}
266 \li Sort messages in a context alphabetically in TS files.
267 \row
268 \li \c {-no-recursive}
269 \li Do not recursively scan directories.
270 \row
271 \li \c {-recursive}
272 \li Recursively scan directories (default).
273 \row
274 \li \c {-warnings-are-errors}
275 \li Treat warnings as errors.
276 \row
277 \li \c {-I <includepath> or -I<includepath>}
278 \li Look for include files in this additional location. You can specify
279 multiple paths.
280 \row
281 \li \c {-locations {absolute|relative|none}}
282 \li Specify or override the way to save source code references in TS
283 files.
284 \list
285 \li \c absolute means that the source file path is relative to
286 the target file, but the line number is absolute.
287 \li \c relative means that the source file path is relative to
288 the target file. The line number is relative to other
289 entries in the same source file.
290 \li \c none stores no information about source location.
291 \endlist
292 If you do not specify the location, \c lupdate determines it from
293 existing TS files. The default value for new files is \c absolute.
294 \row
295 \li \c {-no-ui-lines}
296 \li Do not record line numbers in references to UI files.
297 \row
298 \li \c {-disable-heuristic {sametext|similartext}}
299 \li Disable the named merge heuristic. Can be specified multiple times.
300 \row
301 \li \c {-project <filename>}
302 \li Name of a file containing the project's description in JSON format.
303 You can use the \c lprodump tool to generate the file from a .pro
304 file.
305 \row
306 \li \c {-pro <filename>}
307 \li Name of a .pro file. Useful for files with the .pro file syntax but
308 some other file suffix. Projects are recursed into and merged.
309 This option is deprecated. Use the \c lupdate-pro tool instead.
310 \row
311 \li \c {-pro-out <directory>}
312 \li Virtual output directory for processing subsequent .pro files.
313 \row
314 \li \c {-pro-debug}
315 \li Trace processing .pro files. Specify twice for more verbosity.
316 \row
317 \li \c {-source-language <language>[_<region>]}
318 \li Specify the language of the source strings for new files.
319 Defaults to POSIX if not specified.
320 \row
321 \li \c {-target-language <language>[_<region>]}
322 \li Specify the language of the translations for new files.
323 If you do not specify the language, \c lupdate determines it from
324 the file name.
325 \row
326 \li \c {-tr-function-alias <function>{+=,=}<alias>[,<function>{+=,=}<alias>]...}
327 \li With \c {+=}, recognize \c <alias> as an alternative spelling of
328 \c <function>.
329 With \c {=,} recognize \c <alias> as the only spelling of
330 \c <function>.
331
332 Available \c <function> values (with their currently defined aliases)
333 are:
334 \list
335 \li \c {Q_DECLARE_TR_FUNCTIONS} (\c {=Q_DECLARE_TR_FUNCTIONS})
336 \li \c {QT_TR_N_NOOP} (\c {=QT_TR_N_NOOP})
337 \li \c {QT_TRID_N_NOOP} (\c {=QT_TRID_N_NOOP})
338 \li \c {QT_TRANSLATE_N_NOOP} (\c {=QT_TRANSLATE_N_NOOP})
339 \li \c {QT_TRANSLATE_N_NOOP3} (\c {=QT_TRANSLATE_N_NOOP3})
340 \li \c {QT_TR_NOOP} (\c {=QT_TR_NOOP})
341 \li \c {QT_TRID_NOOP} (\c {=QT_TRID_NOOP})
342 \li \c {QT_TRANSLATE_NOOP} (\c {=QT_TRANSLATE_NOOP})
343 \li \c {QT_TRANSLATE_NOOP3} (\c {=QT_TRANSLATE_NOOP3})
344 \li \c {QT_TR_NOOP_UTF8} (\c {=QT_TR_NOOP_UTF8})
345 \li \c {QT_TRANSLATE_NOOP_UTF8} (\c {=QT_TRANSLATE_NOOP_UTF8})
346 \li \c {QT_TRANSLATE_NOOP3_UTF8} (\c {=QT_TRANSLATE_NOOP3_UTF8})
347 \li \c {findMessage} (\c {=findMessage})
348 \li \c {qtTrId} (\c {=qtTrId})
349 \li \c {tr} (\c {=tr})
350 \li \c {trUtf8} (\c {=trUtf8})
351 \li \c {translate} (\c {=translate})
352 \li \c {qsTr} (\c {=qsTr})
353 \li \c {qsTrId} (\c {=qsTrId})
354 \li \c {qsTranslate} (\c {=qsTranslate})
355 \endlist
356 \row
357 \li \c {-ts <ts-file>...}
358 \li Specify the output files. This overrides \c TRANSLATIONS.
359 \row
360 \li \c {-version}
361 \li Display the version of \c lupdate and exit.
362 \endtable
363
364 \section1 Examples
365
366 \section2 Using lupdate with CMake
367
368 When building with CMake, use \l{CMake Commands in Qt6 LinguistTools}
369 {CMake commands} to add translations on targets to the CMakeLists.txt
370 file, and then build the targets.
371
372 Select one of the following options:
373
374 \list
375 \li Use \l qt_add_translations on a target, such as \e app.
376 This calls \l qt_add_lupdate and \l qt_add_lrelease.
377 \li Use \c qt_add_lupdate on a target.
378 \endlist
379
380 Build a target (for example, \c app_lupdate) to update the .ts
381 files for it. To update the .ts files for all targets, build the
382 target \c {update_translations}.
383
384 \section2 Using lupdate with qmake
385
386 To generate a translation file for a single QML file:
387
388 \badcode
389 lupdate main.qml -ts main_en.ts
390 \endcode
391
392 To make a translation file for another language, for example French,
393 copy main_en.ts to main_fr.ts, and translate the strings in the
394 French TS file.
395
396 \c lupdate processes QML files that are listed in the \c .qrc file:
397
398 \badcode
399 RESOURCES += qml.qrc
400 \endcode
401
402 To have all QML files processed by \c lupdate:
403
404 \badcode
405 lupdate application.qrc -ts myapp_en.ts
406 \endcode
407
408 To process all QML files in the current working directory (or its subfolders)
409 without using a \c .qrc file:
410
411 \badcode
412 lupdate . -extensions qml -ts myapp_en.ts
413 \endcode
414
415 To check for translatable strings in both QML and C++ source files:
416
417 \badcode
418 lupdate qml.qrc filevalidator.cpp -ts myapp_en.ts
419 \endcode
420
421 To generate .ts files that will be used for English and French without
422 specifying the languages in the project file:
423
424 \badcode
425 lupdate qml.qrc filevalidator.cpp -ts myapp_en.ts myapp_fr.ts
426 \endcode
427
428 Give the TS files to the translator who uses \QL to read the files and
429 insert the translations.
430
431 \section1 XLIFF format files
432
433 The TS file format is a simple human-readable XML format that you
434 can use with version control systems. In addition, \c lupdate can
435 process Localization Interchange File Format (XLIFF) files (\c .xlf).
436
437 \note Only XLIFF versions 1.1 and 1.2 are currently supported.
438
439 You can open and edit XLIFF files in \QL.
440*/
441
442/*!
443 \page linguist-lrelease.html
444 \target lrelease
445
446 \previouspage Using lupdate
447 \nextpage Using lconvert
448
449 \title Using lrelease
450
451 The \c lrelease command line tool produces QM files out of TS files. The
452 QM file format is a compact binary format that the localized application
453 uses. It provides extremely fast lookup for translations.
454
455 When building with qmake, specify the files to process at the command line
456 or in a .pro file.
457
458 When building with CMake, use \l{CMake Commands in Qt6 LinguistTools}
459 {CMake commands} to add targets that create or update TS files and
460 transform them into QM files. The \c lrelease tool is run with the
461 \l {lrelease options}{options} you pass to the commands when you build
462 the target.
463
464 Run \c lrelease whenever you want to release the application, from the
465 initial test version through to the final release version. The application
466 does not need QM files to run, but if they are available, the application
467 detects them and uses them automatically.
468
469 \note The \c lrelease tool only incorporates translations that you
470 mark as \e finished. Otherwise, it uses the original text instead.
471
472 \section1 lrelease syntax
473
474 \badcode
475 lrelease [options] -project project-file
476 lrelease [options] ts-files [-qm qm-file]
477 \endcode
478
479 Where:
480
481 \list
482 \li \c options means one or several \l {lrelease options}.
483 \li \c project-file is the project configuration file.
484 \li \c ts-files are the TS files to use as input for the QM files.
485 \li \c qm-file is the name of the QM file to generate.
486 \endlist
487
488 \note Passing .pro files to \c lrelease is deprecated. Use the
489 \c lrelease-pro tool or the \c lrelease.prf feature when using qmake.
490
491 To view the latest help, enter:
492
493 \badcode
494 lrelease -help
495 \endcode
496
497 \section2 lrelease options
498
499 \table
500 \header
501 \li Option
502 \li Action
503 \row
504 \li \c {-help}
505 \li Display up-to-date help information and exit.
506 \row
507 \li \c {-idbased}
508 \li Deprecated. The flag is not required anymore and will be removed
509 in a future version. It was used to enable ID based translation.
510 \row
511 \li \c {-compress}
512 \li Compress the QM files.
513 \row
514 \li \c {-nounfinished}
515 \li Do not include unfinished translations.
516 \row
517 \li \c {-fail-on-unfinished}
518 \li Generate an error if unfinished translations are found
519 \row
520 \li \c {-removeidentical}
521 \li If the translated text is the same as the source text, exclude the
522 message.
523 \row
524 \li \c {-markuntranslated <prefix>}
525 \li If a message has no real translation, use the source text
526 prefixed with the given string instead.
527 \row
528 \li \c {-project <filename>}
529 \li Name of a file containing the project's description in JSON format.
530 You can use the \c lprodump tool to generate the file from a .pro
531 file.
532 \row
533 \li \c {-silent}
534 \li Do not explain what is being done.
535 \row
536 \li \c {-verbose}
537 \li Explain what is being done (default).
538 \row
539 \li \c {-version}
540 \li Display the version of \c lrelease and exit.
541 \endtable
542
543 \section1 Examples
544
545 \section2 Using lrelease with CMake
546
547 When building with CMake, use \l{CMake Commands in Qt6 LinguistTools}
548 {CMake commands} to add translations on targets to the CMakeLists.txt
549 file, and then build the targets.
550
551 Select one of the following options:
552
553 \list
554 \li Use \l qt_add_translations on a target, such as \e app.
555 This calls \l qt_add_lupdate and \l qt_add_lrelease.
556 \li Use \c qt_add_lrelease on a target.
557 \endlist
558
559 Build a target (for example, \c app_lrelease) to update the .qm
560 files for it. To update the .qm files for all targets, build the
561 target \c {release_translations}.
562
563 \section2 Using lrelease with qmake
564
565 To run \c lrelease without specifying a project file:
566
567 \badcode
568 lrelease.exe main_en.ts languages\main_fr.ts
569 \endcode
570*/
571
572/*!
573 \page linguist-lconvert.html
574 \target lconvert
575
576 \previouspage Using lrelease
577 \nextpage Using lconvert
578
579 \title Using lconvert
580
581 The \c lconvert command line tool filters and converts translation data
582 files.
583
584 It supports the following file formats:
585 \list
586 \li \c pot - GNU Gettext localization template files
587 \li \c qph - Qt Linguist Phrase Book
588 \li \c ts - Qt translation sources
589 \li \c po - GNU Gettext localization files
590 \li \c qm - Compiled Qt translations
591 \li \c xlf - XLIFF localization files
592 \endlist
593
594 \section1 lconvert syntax
595
596 \badcode
597 lconvert [options] <infile> [<infile>...]
598 \endcode
599
600 Where:
601
602 \list
603 \li \c options means one or several \l {lconvert options}.
604 \li \c infile is an input file. You can specify multiple input files.
605 \endlist
606
607 If you specify multiple input files, they are merged with translations from
608 later files taking precedence.
609
610 To view the latest \c lconvert help, enter:
611
612 \badcode
613 lconvert -help
614 \endcode
615
616 \section2 lconvert options
617
618 \table
619 \header
620 \li Option
621 \li Action
622 \row
623 \li \c -h \br \c -help
624 \li Display up-to-date help information and exit.
625 \row
626 \li \c {-i <infile>} \br \c {-input-file <infile>}
627 \li Specify an input file. Use this option if \c{<infile>} starts with a dash.
628 Use this option several times to merge inputs.
629 May be \c {-} (standard input) for use in a pipe.
630 \row
631 \li \c {-o <outfile>} \br \c {-output-file <outfile>}
632 \li Specify an output file. Default is \c {-} (standard output).
633 \row
634 \li \c {-if <informat>} \br \c {-input-format <format>}
635 \li Specify input format for subsequent input files.
636 The format is auto-detected from the file name and defaults to \c ts.
637 \row
638 \li \c {-of <outformat>} \br \c {-output-format <outformat>}
639 \li Specify output format. See \c -if.
640 \row
641 \li \c {-drop-tags <regexp>}
642 \li Drop named extra tags when writing \c TS or \c XLIFF files.
643 You can specify this option repeatedly.
644 \row
645 \li \c {-drop-translations}
646 \li Drop existing translations and reset the status to \c unfinished.
647 That implies \c {--no-obsolete}.
648 \row
649 \li \c {-source-language <language>[_<region>]}
650 \li Specify/override the language of the source strings. Defaults to
651 POSIX if not specified and the file does not name it yet.
652 \row
653 \li \c {-target-language <language>[_<region>]}
654 \li Specify or override the language of the translation.
655 By default, the target language is read from the file content or
656 guessed from the file name.
657 \row
658 \li \c {-no-obsolete}
659 \li Drop obsolete messages.
660 \row
661 \li \c {-no-finished}
662 \li Drop finished messages.
663 \row
664 \li \c {-no-untranslated}
665 \li Drop untranslated messages.
666 \row
667 \li \c {-sort-contexts}
668 \li Sort contexts in the output \c TS file alphabetically.
669 \row
670 \li \c {-sort-messages}
671 \li Sort messages in a context alphabetically in \c TS files.
672 \row
673 \li \c {-locations {absolute|relative|none}}
674 \li Override how source code references are saved in \c TS files.
675 Default is \c absolute.
676 \row
677 \li \c {-no-ui-lines}
678 \li Drop line numbers from references to \c UI files.
679 \row
680 \li \c {-pluralonly}
681 \li Drop non-plural form messages.
682 \row
683 \li \c {-verbose}
684 \li Explain what is being done.
685 \endtable
686
687 \section1 Examples
688
689 \section2 Convert TS file to XLIFF
690
691 To convert a single TS file to XLIFF, run the following command in the
692 terminal:
693
694 \badcode
695 lconvert -o myapp_de.xlf myapp_de.ts
696 \endcode
697
698 \section2 Merge multiple QM files
699
700 The following command merges multiple QM files into \c {full_de.qm}:
701
702 \badcode
703 lconvert -o full_de.qm qtbase_de.qm myapp_de.qm mylib_de.qm
704 \endcode
705
706 \section2 Using lconvert with CMake
707
708 To call \c lconvert when configuring or building your CMake project, load
709 the \c Qt6LinguistTools package and use \c
710 {$<TARGET_FILE_NAME:Qt6::lconvert>} for locating the \c lconvert executable.
711
712 The following example adds a custom target \c xlf_de that converts a single
713 TS file to XLIFF.
714
715 \badcode
716 find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
717
718 add_custom_command(
719 OUTPUT myapp_de.xlf
720 COMMAND $<TARGET_FILE:Qt6::lconvert> -o myapp_de.xlf myapp_de.ts
721 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/myapp_de.ts"
722 VERBATIM
723 )
724
725 add_custom_target(xlf_de
726 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/myapp_de.xlf"
727 )
728 \endcode
729*/
730
731/*!
732\page linguist-lcheck.html
733\target lcheck
734\previouspage Using lconvert
735\nextpage Translators
736
737\title Using lcheck
738
739The \c lcheck command line tool validates Qt \c {TS} translation files and
740produces a human-readable report. It is part of the Qt Linguist toolchain
741and is intended for batch or CI usage to catch common localization issues
742early. By default, \c lcheck runs a set of checks and returns a non-zero
743exit code if at least one enabled check fails.
744
745The default checks are:
746
747\list
748 \li \b Accelerator check — Verifies that the number of ampersands
749 (mnemonics) in source and translation match.
750 \li \b Surrounding whitespace check — Verifies that leading and trailing
751 whitespace of source and translation match.
752 \li \b Ending punctuation check — Verifies that source and translation
753 end with the same punctuation.
754 \li \b Place marker check — Verifies consistent usage of \c {%1}, \c {%2},
755 and so on, between source and translation.
756\endlist
757
758Each check can be disabled individually using command line options.
759
760\section1 lcheck syntax
761
762\badcode
763lcheck [options] -o report-output-file ts-file
764lcheck [options] ts-file
765\endcode
766
767Where:
768
769\list
770 \li \c options means one or several \l {lcheck options}.
771 \li \c ts-file is the \c {TS} file to validate.
772 \li \c report-output-file is the path of the file to write the report to.
773 If omitted, the report is written to the standard error stream.
774\endlist
775
776To view the latest help, enter:
777
778\badcode
779lcheck -help
780\endcode
781
782\section2 lcheck options
783
784\table
785\header
786 \li Option
787 \li Action
788\row
789 \li \c {-help}
790 \li Display up-to-date help information and exit.
791\row
792 \li \c {-no-accelerator}
793 \li Disable the accelerator (ampersand) consistency check.
794\row
795 \li \c {-no-punctuation}
796 \li Disable the ending punctuation consistency check.
797\row
798 \li \c {-no-place-marker}
799 \li Disable the check that ensures \c {%1}, \c {%2}, … are used
800 consistently between source and translation.
801\row
802 \li \c {-no-whitespaces}
803 \li Disable the surrounding whitespace consistency check.
804\row
805 \li \c {-check-finished}
806 \li Also check messages marked as \e finished. By default, finished
807 translations are not checked.
808\row
809 \li \c {-o <outfile>}
810 \li Write the validation report to \c <outfile>. If not specified, the
811 report is written to standard error.
812\row
813 \li \c {-version}
814 \li Display the version of \c lcheck and exit.
815\endtable
816
817\note The process exit status is non-zero if any enabled check fails. This
818makes \c lcheck suitable for use in CI pipelines.
819
820\section1 Examples
821
822\section2 Write a report to a file
823
824\badcode
825lcheck -o lcheck_report.txt translations/myapp_de.ts
826\endcode
827
828\section2 Disable selected checks
829
830The following command runs all checks except accelerator and punctuation:
831
832\badcode
833lcheck -no-accelerator -no-punctuation translations/myapp_de.ts
834\endcode
835
836\section2 Check finished translations as well
837
838\badcode
839lcheck -check-finished translations/myapp_de.ts
840\endcode
841
842\section2 Use lcheck in a CI step
843
844\badcode
845lcheck translations/myapp_de.ts && echo "Translations OK" || echo "Issues found"
846\endcode
847
848\section2 Using lcheck with CMake
849
850To call \c lcheck when configuring or building your CMake project, load
851the \c Qt6LinguistTools package and use \c {$<TARGET_FILE:Qt6::lcheck>}
852to locate the \c lcheck executable.
853
854The following example adds a custom target \c check_translations that runs
855\c lcheck over a TS file and writes a report next to the build artifacts.
856
857\badcode
858find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
859
860add_custom_command(
861 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/lcheck_report.txt"
862 COMMAND $<TARGET_FILE:Qt6::lcheck>
863 -o "${CMAKE_CURRENT_BINARY_DIR}/lcheck_report.txt"
864 "${CMAKE_CURRENT_SOURCE_DIR}/translations/myapp_de.ts"
865 DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/translations/myapp_de.ts"
866 VERBATIM
867)
868
869add_custom_target(check_translations
870 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/lcheck_report.txt"
871)
872\endcode
873
874\section2 Using lcheck with qmake
875
876You can run \c lcheck directly on a TS file without specifying a project file:
877
878\badcode
879lcheck translations/myapp_de.ts
880\endcode
881*/
882
883/*!
884 \page linguist-translators.html
885
886 \previouspage Using lcheck
887 \nextpage Qt Linguist user interface
888
889 \title Translators
890
891 \image front-ui.png {UI illustration showing Start buttons, toggle,
892 controls, and a circular selector on a dark screen}
893
894 \QL is a tool for translating strings in Qt applications. Once you have
895 installed Qt, you can start \QL in the same way as any other application on
896 the development host.
897
898 \note You can obtain an installer for \QL only (without the entire Qt SDK)
899 from \l {https://download.qt.io/linguist_releases/}. The installer is
900 available for Windows, and works with Qt 6.
901
902 To address issues that arise from the subtleties and complexities of
903 human language, translators and developers may need to:
904
905 \list
906 \li Translate a single phrase into several different forms depending on
907 context. For example, \e open in English might become \e{\ouml}\e{ffnen},
908 \e {open file}, or \e aufbauen, \e {open internet connection}, in German.
909
910 \li Change the mnemonic characters in keyboard shortcuts without introducing
911 conflicts. For example, \c \&Quit in English becomes \e Avslutt in
912 Norwegian, which does not contain the letter \e Q. You cannot use a
913 letter that is already in use unless you change several shortcuts.
914
915 \li Rephrase strings that contain variables. For example, you might need to
916 place the variables in a different order when you translate the string
917 \e {The 25 files selected will take 63 seconds to process}, where the
918 two numbers are inserted programmatically at runtime.
919 \endlist
920
921 For more information about how to use \QL to translate applications, see:
922
923 \list
924 \li \l {Qt Linguist user interface}
925 \li \l {Translating strings}
926 \li \l {Selecting context or label to translate}
927 \li \l {Selecting strings to translate}
928 \li \l {Viewing strings in context}
929 \li \l {Reusing translations}
930 \li \l {Validating translations}
931 \li \l {Translating multiple languages simultaneously}
932 \li \l {AI translation}
933 \endlist
934*/
935
936/*!
937 \page linguist-ui.html
938
939 \previouspage Translators
940 \nextpage Translating strings
941
942 \title Qt Linguist user interface
943
944 The \QL main window contains a menu bar and the following views:
945
946 \list
947
948 \li \uicontrol Context/Label (\key F6) lists translation contexts or labels.
949
950 \li \uicontrol Strings (\key F7) lists translatable strings in the
951 selected context.
952
953 \li \uicontrol {Sources and Forms} (\key F9) displays the selected
954 string in the source code.
955
956 \li Translation area displays the selected string and enables you to
957 enter a translation for it.
958
959 \li \uicontrol {Phrases and guesses} (\key F10) lists possible
960 translations for the current string.
961
962 \li \uicontrol Warnings (\key F8) lists translated strings that fail
963 validation tests.
964
965 \endlist
966
967 \image linguist.webp {Qt Linguist UI}
968
969 The translation area (1) is always visible. To show or hide the other views,
970 select \uicontrol View > \uicontrol Views, or use keyboard shortcuts.
971 You can drag the views by their title bars and arrange them around the
972 translation area or even outside the main window.
973*/
974
975/*!
976 \page linguist-translating-strings.html
977
978 \previouspage Qt Linguist user interface
979 \nextpage Selecting context or label to translate
980
981 \title Translating strings
982
983 Open translation source (TS) files in \QL for translation. TS files are
984 human-readable XML files containing source phrases and their translations.
985 TS files are usually created and updated by \c lupdate. If you do not have
986 a TS file, see \l {Creating translation files} to learn how to generate one.
987
988 You can use \QL also to translate files in the international XML
989 Localization Interchange File Format (XLIFF) that are generated by other
990 programs. However, for standard Qt projects, only the TS file format is
991 used. Only XLIFF versions 1.1 and 1.2 are currently supported.
992
993 \QL displays the target language in the translation area, and adapts the
994 number of input fields for plural forms accordingly. When you open several
995 TS files to translate simultaneously, the \uicontrol Translator and
996 \uicontrol {Translator comment} fields are displayed for each language.
997 For more information about setting the location information, see
998 \l{Changing the target locale}.
999
1000 If the developer provides a disambiguating comment, you can see it in the
1001 \uicontrol {Developer comments} field.
1002
1003 To translate strings:
1004 \list 1
1005
1006 \li Select \uicontrol File > \uicontrol Open to load a TS file.
1007
1008 \li Select a context in the \uicontrol Context view to display translatable
1009 strings in the \uicontrol Strings view.
1010
1011 \image linguist-ui.webp {}
1012
1013 \li Select a string to display it in the \uicontrol {Source text} field
1014 in the translation area. The whitespace within the source text is
1015 visualized.
1016
1017 \li Enter the translation of the current string in the \uicontrol Translation
1018 field.
1019
1020 Double-click an existing translation in the
1021 \uicontrol {Phrases and guesses} field to use it as the translation
1022 for the current string. \QL reads the phrases from phrase books and
1023 bases the guesses on existing translations of similar phrases in the
1024 TS file.
1025
1026 \li Optionally, enter a comment for other translators in the
1027 \uicontrol {Translator comment} field.
1028
1029 \li To accept the translation, press \key {Ctrl+Enter}, select
1030 \inlineimage linguist-doneandnext.png {Icon}
1031 , or click the icon to the left of the selected source string in the
1032 string list.
1033
1034 \li Select \uicontrol File > \uicontrol Save to save your work.
1035
1036 \endlist
1037
1038 Repeat this process until all strings in the string list are marked with
1039 \inlineimage linguist-check-on.png {Check icon}
1040 (\uicontrol {Accepted/Correct}) or
1041 \inlineimage linguist-check-warning.png {Check warning icon}
1042 (\uicontrol {Accepted/Warnings}). Then select the next context and continue.
1043
1044 To view the number of words and characters in the source text and in the
1045 translated text, select \uicontrol View > \uicontrol Statistics.
1046
1047 Select \uicontrol File > \uicontrol Release to create a QM
1048 file with the same base name as the current translation source file.
1049 The \c lrelease tool performs the same function on \e all of an
1050 application's translation source files.
1051
1052 To print the translation source and the translations, select \uicontrol File >
1053 \uicontrol Print.
1054
1055 To quit \QL, select \uicontrol File > \uicontrol Exit.
1056
1057 \section1 Moving between translatable strings
1058
1059 To move to the next unfinished translation, select
1060 \inlineimage nextunfinished.png {Icon}
1061 (\uicontrol {Next Unfinished}) or press \key{Ctrl+J}.
1062
1063 To move to the next source text, select \inlineimage next.png {next icon}
1064 , press \key{Ctrl+Shift+J}, or select \uicontrol Translation >
1065 \uicontrol Next.
1066
1067 \section1 Phrases that require multiple translations depending on context
1068
1069 The same phrase may occur in more than one context without conflict. When
1070 you reach another occurrence of a translated phrase, \QL provides
1071 the previous translation as a possible translation in the
1072 \uicontrol {Phrases and guesses} view.
1073
1074 If a phrase occurs more than once within a particular context, it appears
1075 only once in the \uicontrol Context view, and the translation is applied
1076 to every occurrence within the context. If the same phrase means different
1077 things within the same context, the developer must provide a comment for
1078 each occurrence of the phrase. The duplicate phrases appear in the
1079 \uicontrol Context view. The developer's comments appear in the translation
1080 area on a light blue background.
1081
1082 \section1 Changing keyboard shortcuts
1083
1084 A keyboard shortcut is a key combination that performs an action.
1085
1086 \section2 Alt key shortcuts
1087
1088 In menu item and button text, a \e mnemonic character (marked by underlining)
1089 indicates that pressing \key Alt or \key Ctrl with the underlined character
1090 performs the same action as clicking the menu item or pressing the button.
1091
1092 For example, applications often use \e F as the mnemonic character in the
1093 \uicontrol {File} menu, so you can either click the menu item or press
1094 \key {Alt+F} to open the menu. The mnemonic character in the translatable
1095 string is prefixed with an ampersand: \c {\&File}. The translation for the
1096 string should also have an ampersand in it, preferably in front of the same
1097 character.
1098
1099 You can determine the meaning of an \key Alt key shortcut from the phrase
1100 that contains the ampersand. You can use another mnemonic character if the
1101 translated phrase does not contain the current one or if it is used in
1102 the translation of some other shortcut in the context. Some key shortcuts,
1103 usually those on the menu bar, may apply in other contexts.
1104
1105 \section2 Ctrl key shortcuts
1106
1107 \key Ctrl key shortcuts can exist independently of any visual control.
1108 Typically, they invoke actions in menus that would require multiple
1109 keystrokes or mouse clicks or actions that do not appear in any menu
1110 or on any button. For example, the \uicontrol {File} menu might contain a
1111 \uicontrol {\underline{N}ew Ctrl+N} item that you can invoke by pressing
1112 \key {Ctrl+N} even when the \uicontrol {File} menu is closed.
1113
1114 Each \key Ctrl key shortcut appears in the \uicontrol Strings view
1115 as a separate string. For example, \key{Ctrl+Enter}. Since
1116 the string does not have a context to give it meaning, such as
1117 the context of the phrase in which an \key Alt key shortcut appears,
1118 you must rely on the developer to include a \l{QObject::tr()}
1119 {disambiguation comment} to explain the action the \key Ctrl key
1120 shortcut performs. The comment appears under \uicontrol {Developer comments}
1121 in the translation area below the \uicontrol {Source text} field.
1122
1123 Ideally, you can copy translations for \key Ctrl key shortcuts by
1124 selecting \uicontrol Translation > \uicontrol {Copy from source text}.
1125 However, if the character does not make sense in the target language,
1126 change it. Whichever character (alpha or digit) you choose, use the form
1127 \key {Ctrl+} followed by the upper case character. Qt automatically displays
1128 the correct name at runtime. As with \key Alt key shortcuts, if you change
1129 the character, make sure that it does not conflict with any other
1130 \key Ctrl key shortcut.
1131
1132 \note Do not translate the \key Alt, \key Ctrl or \key Shift parts of
1133 the shortcuts, as Qt recognizes them and automatically translates them
1134 for supported languages.
1135
1136 \section1 Handling numbered arguments and plural forms
1137
1138 A numbered argument is a placeholder that will be replaced with text at
1139 runtime. It appears in a source string as a percent sign followed by
1140 a digit. For example, in the \c{After processing file %1, file %2
1141 is next in line} string, \c{%1} and \c{%2} are numbered arguments that
1142 are replaced with the first and second file names at runtime. The
1143 same numbered arguments must appear in the translation, but not
1144 necessarily in the same order. A German translation of the string
1145 might reverse the phrases, for example \c{Datei %2 wird bearbeitet, wenn
1146 Datei %1 fertig ist}. Both numbered arguments appear in the
1147 translation, but in the reverse order. A numbered argument is always
1148 replaced by the same text in the translations, regardless of the position
1149 in the argument sequence in the source string.
1150
1151 The use of numbered arguments is often accompanied by the use of
1152 plural forms in the source text. In many languages, the form of the
1153 text will depend on the value shown, and more than one translation
1154 is required. If the developers have marked up the source text in
1155 correct way, fields for each of the possible plural forms will be
1156 available in the translation area. For more information, see
1157 \l{Writing Source Code for Translation}.
1158
1159 \section1 Handling numeric character references (NCR) in translations
1160
1161 Select \uicontrol {NCR mode} to toggle the representation of
1162 numeric character references in both the source text and the translation
1163 fields. When selected, special characters in the text are displayed as their
1164 corresponding NCRs (for examlple, &#160; for a non-breaking space). Otherwise, the
1165 characters appear in their standard visual form. This feature is useful
1166 for instance to maintain the same special characters (such as
1167 emojis, special spaces) in both the source text and its translations.
1168
1169 \section1 Changing the target locale
1170
1171 You can set the locale information explicitly in \uicontrol Edit >
1172 \uicontrol {Translation File Settings}. If the target language and country
1173 are not explicitly set when you open a translation source file, \QL
1174 attempts to deduct them from the translation source file name. This
1175 requires that the translation files adhere to the following file name
1176 convention:
1177 \c appname_language[_country].ts, where:
1178
1179 \list
1180 \li \c language is an ISO 639 language code in lowercase.
1181 \li \c country is an ISO 3166 two-letter country code in uppercase.
1182 \endlist
1183
1184 If this attempt to resolve the target language and country fails, the
1185 \uicontrol {Translation File Settings} window opens.
1186
1187 For example, \c app_de.ts sets the
1188 target language to German, and \c app_de_CH.ts sets the target language to
1189 German and the target country to Switzerland. This also helps loading
1190 translations for the current locale automatically. For more information, see
1191 \l{Enable Translation}.
1192
1193 \image linguist-translationfilesettings.png {Screenshot showing Qt Linguist
1194 settings window with source language POSIX and target language German}
1195*/
1196
1197/*!
1198 \page linguist-selecting-context.html
1199
1200 \previouspage Translating strings
1201 \nextpage Selecting strings to translate
1202
1203 \title Selecting context or label to translate
1204
1205 The \uicontrol Context/Label view lists the contexts (\uicontrol {Text based}) or
1206 labels (\uicontrol {ID based}) in which strings to be translated
1207 appear. The text-based translations are grouped into contexts, while ID-based
1208 translations are grouped into labels (see \l{Grouping ID-Based Translations}).
1209 The \uicontrol Context/Label lists the \e groups (that is, context or labels)
1210 based on the selected tab:
1211 \list
1212 \li Upon switching to the \uicontrol{Text-Based} tab,
1213 \uicontrol Context lists the context names in
1214 alphabetical order. Each context is the name of a QML type or a subclass of
1215 QObject.
1216 \li Upon switching to the \uicontrol{ID-Based} tab,
1217 \uicontrol Label lists the label names in
1218 alphabetical order. More info on labels can be found in \l{Grouping ID-Based Translations}.
1219 \endlist
1220
1221 \image linguist-context-view.webp {Context/Label view}
1222
1223 The following icons indicate the current translation state for each group:
1224
1225 \table
1226 \header
1227 \li State
1228 \li Icon
1229 \li Description
1230
1231 \row
1232 \li Accepted/Correct
1233 \li \inlineimage linguist-check-on.png {Check icon}
1234 \li All strings in the group have been translated, and all the
1235 translations passed the \l{Validating Translations}{validation tests}.
1236
1237 \row
1238 \li Accepted/Warnings
1239 \li \inlineimage linguist-check-warning.png {Check warning icon}
1240 \li All strings in the group have been translated or marked as translated,
1241 but at least one translation failed the validation tests.
1242 In the \uicontrol Strings view, you can see which string failed the test.
1243
1244 \row
1245 \li Not Accepted
1246 \li \inlineimage linguist-check-off.png {check off icon}
1247 \li At least one string in the group has not been translated or is not
1248 marked as translated.
1249
1250 \row
1251 \li Obsolete
1252 \li \inlineimage linguist-check-obsolete.png {check obsolete icon}
1253 \li None of the translated strings appears in the group any more. This
1254 usually means the context or label no longer exists in the application.
1255 \endtable
1256
1257 The \uicontrol Items column displays the total number of translatable strings in
1258 the group and the number of translated strings, separated by a slash (/).
1259 If the numbers are equal, all the translatable strings in the group have
1260 translations.
1261*/
1262
1263/*!
1264 \page linguist-selecting-strings.html
1265
1266 \previouspage Selecting context or label to translate
1267 \nextpage Viewing strings in context
1268
1269 \title Selecting strings to translate
1270
1271 The \uicontrol Strings view lists all the translatable strings in the
1272 current group (that is, context or label) and their translation acceptance
1273 state. Select a string to view and edit it in the translation area.
1274
1275 \image linguist-strings-view.webp {Strings view}
1276
1277 Click the icon in front of a string to change its translation acceptance
1278 state. A tick mark, green or yellow, means the string has an accepted
1279 translation. A question mark means either that the translation does not
1280 exist or you have not accepted it.
1281
1282 The following icons indicate the current translation state for each string:
1283
1284 \target String Translation States
1285
1286 \table
1287 \header
1288 \li State
1289 \li Icon
1290 \li Description
1291
1292 \row
1293 \li Accepted/Correct
1294 \li \inlineimage linguist-check-on.png {Check icon}
1295 \li The source string has a translation (possibly empty). You accepted
1296 the translation, and it passes all the \l{Validating Translations}
1297 {validation tests}. Click the icon to revoke acceptance of the
1298 translation. The state becomes \uicontrol {Not Accepted} if the string
1299 has a translation or \uicontrol {No Translation} if the translation is
1300 empty. If \c{lupdate} changes the contents of a string, its acceptance
1301 state becomes \uicontrol {Not Accepted}.
1302
1303 \row
1304 \li Accepted/Warnings
1305 \li \inlineimage linguist-check-warning.png {Check warning icon}
1306 \li You accepted the translation, but it does not pass all the validation
1307 tests. The \uicontrol Warnings view shows where it failed. If you click
1308 the icon to revoke acceptance of the translation, the state becomes
1309 \uicontrol {Validation Failures}.
1310
1311 \row
1312 \li Not Accepted
1313 \li \inlineimage linguist-check-off.png {check off icon}
1314 \li The string has a translation that passes all the validation tests, but
1315 you have not yet accepted the translation. Click the icon or press
1316 \key{Ctrl+Enter} to accept the translation. The state becomes
1317 \uicontrol {Accepted/Correct}.
1318
1319 \row
1320 \li No Translation
1321 \li \inlineimage linguist-check-empty.png {check empty icon}
1322 \li The string does not have a translation. If you click the icon to accept
1323 the empty translation, the state becomes \uicontrol {Accepted/Correct}.
1324
1325 \row
1326 \li Validation Failures
1327 \li \inlineimage linguist-danger.png {danger icon}
1328 \li The string has a translation, but the translation does not pass all the
1329 validation tests. The \uicontrol Warnings view shows the validation test
1330 failures. Click on the icon or press \key{Ctrl+Enter} to
1331 accept the translation even with validation failures. The state becomes
1332 \uicontrol {Accepted/Warnings}. Usually, you should fix the causes of the
1333 validation failures. The state will automatically become
1334 \uicontrol {Not Accepted} when you fix all failures.
1335
1336 \row
1337 \li Obsolete
1338 \li \inlineimage linguist-check-obsolete.png {check obsolete icon}
1339 \li The string is obsolete. It is no longer used in the context.
1340 See \l{Using lupdate} for instructions on how to remove obsolete
1341 messages from the file.
1342
1343 \endtable
1344*/
1345
1346/*!
1347 \page linguist-viewing-strings-in-context.html
1348
1349 \previouspage Selecting strings to translate
1350 \nextpage Reusing translations
1351
1352 \title Viewing strings in context
1353
1354 If \QL can access the source files containing the translatable strings, the
1355 \uicontrol {Sources and Forms} view shows the source context of the current
1356 string in the \uicontrol Strings view. It highlights the source code line
1357 that contains the current string. If \QL cannot find the source file, it
1358 shows the expected absolute file path.
1359
1360 If the source context shows the wrong source line, the translation file might
1361 be out of sync with the source files. For more information about how to sync
1362 the files, see \l{Using lupdate}.
1363
1364 \QD stores UI forms in special UI files (.ui). \QL attempts to show the
1365 translations in the forms.
1366*/
1367
1368/*!
1369 \page linguist-reusing-translations.html
1370
1371 \previouspage Viewing strings in context
1372 \nextpage Validating translations
1373
1374 \title Reusing translations
1375
1376 If the translated text is similar to the source text, select
1377 \uicontrol Translation > \uicontrol {Copy from source text}
1378 (or press \key{Ctrl+B}) to copy the source text into the
1379 translation area.
1380
1381 \e {Phrase books} provide a common set of translations
1382 to help ensure consistency. A phrase book is a set of source phrases, target
1383 (translated) phrases, and optional definitions. Typically, one phrase book
1384 is created per language and family of applications. Phrase books avoid
1385 duplication of effort since they contain translations for a family of
1386 applications.
1387
1388 The \uicontrol {Phrases and guesses} view displays the current string and its
1389 phrase book translations. If the current string is the same as or similar to
1390 a translated string, the view also lists the string and its translation.
1391
1392 To copy a translation from the \uicontrol {Phrases and guesses} view to the
1393 translation area, double-click it or select it and press \key Enter.
1394
1395 \section1 Batch translation
1396
1397 \image linguist-batchtranslation.png {Screenshot showing Qt Linguist batch
1398 translation window with options and phrase book selection}
1399
1400 Use the batch translation feature to automatically translate source
1401 texts that are also in a phrase book. To configure which phrase books to use
1402 in what order during the batch translation process, select \uicontrol Edit >
1403 \uicontrol {Batch Translation}. You can include only entries with no
1404 current translation and mark batch translated entries as \uicontrol Accepted.
1405
1406 \section1 Creating and editing phrase books
1407
1408 Phrase book files are human-readable XML files containing standard phrases
1409 and their translations. \QL creates and update the files. You can use them
1410 for any number of projects and applications.
1411
1412 To create a new phrase book, select \uicontrol Phrases > \uicontrol {New Phrase Book}.
1413
1414 \image linguist-phrasebookdialog.png {Screenshot of Qt Linguist phrase book editor
1415 showing source phrases with German translations}
1416
1417 To open a phrase book, select \uicontrol Phrases > \uicontrol {Open Phrase Book}, and
1418 then select the Qt phrase book file (.qph) to open.
1419
1420 To view and change open phrase books, select \uicontrol Phrases >
1421 \uicontrol {Edit Phrase Book}.
1422
1423 To add a new phrase, select \uicontrol {New Entry} (or press \key {Alt+N}) and
1424 type in a new source phrase, the translation, and an optional definition.
1425 This is useful to distinguish different translations of the same source
1426 phrase.
1427
1428 To add the translation you are working on to the current phrase book, select
1429 \uicontrol Phrases > \uicontrol {Add to Phrase Book} or press \key{Ctrl+T}. If multiple
1430 phrase books are loaded, you have to select one.
1431
1432 If you detect an error in a phrase book entry in the
1433 \uicontrol {Phrases and guesses} view, you can edit by right
1434 clicking it and selecting \uicontrol Edit. After fixing the
1435 error press \key{Enter} to leave the editing mode.
1436
1437 To delete a phrase, select it in the \uicontrol {Source phrase} list, and then
1438 select \uicontrol {Remove Entry}.
1439
1440 To print an open phrase book, select \uicontrol Phrases >
1441 \uicontrol {Print Phrase Book}.
1442*/
1443
1444/*!
1445 \page linguist-validating-translations.html
1446
1447 \previouspage Reusing translations
1448 \nextpage Translating multiple languages simultaneously
1449
1450 \title Validating translations
1451
1452 \QL provides the following validation tests for translations:
1453
1454 \list
1455 \li \e {Accelerator validation} detects translated phrases
1456 that do not have an ampersand when the source phrase does and vice
1457 versa.
1458 \li \e {Punctuation validation} detects differences in the
1459 terminating punctuation between source and translated phrases when
1460 this may be significant. For example, warns if the source phrase
1461 ends with an ellipsis, exclamation mark or question mark, and the
1462 translated phrase does not, and vice versa.
1463 \li \e {Phrases validation} detects source phrases that are
1464 also in the phrase book but whose translation differs from that
1465 in the phrase book.
1466 \li \e {Place marker validation} detects whether the same variables
1467 (like \c %1, \c %2) appear both in the source text and in the
1468 translation.
1469 \endlist
1470
1471 To switch validation tests on or off, select \uicontrol Validation or use the
1472 toolbar buttons.
1473
1474 Not accepted strings that fail validation tests are marked with the
1475 \uicontrol {Validation Failures} icon in the \uicontrol Strings view.
1476 Accepted strings are marked with \uicontrol {Accepted/Warnings}.
1477
1478 If you switch validation off and then switch it on later,
1479 \QL rechecks all phrases and marks any that fail validation.
1480
1481 The \uicontrol Warnings view lists the strings that fail the active
1482 validation tests. The first warning is also shown in the status bar
1483 at the bottom of the main window.
1484
1485 \note Only results of \e{active} validation tests are reported.
1486*/
1487
1488/*!
1489 \page linguist-translating-multiple-languages.html
1490 \target multiple languages
1491
1492 \previouspage Validating translations
1493 \nextpage AI translation
1494
1495 \title Translating multiple languages simultaneously
1496
1497 You can load and edit multiple translation files simultaneously.
1498 The following screen shot displays \e{German} and \e{French} translation
1499 files loaded.
1500
1501 \image linguist-linguist_2.webp {}
1502
1503 The translation area has color-coded text editing areas for both German and
1504 French. The \uicontrol Context/Label view and the \uicontrol Strings view have
1505 color-coded status columns for each language.
1506
1507 The \uicontrol Items column in the \uicontrol Context/Label view combines the values
1508 for both languages. If the number of translatable strings does not match the
1509 number of accepted strings, either or both languages have strings that you
1510 need to translate or accept. The \uicontrol Strings view shows the translation
1511 acceptance state of each string for each language.
1512*/
1513
1514/*!
1515 \page linguist-ai-translation.html
1516 \target ai translation
1517
1518 \previouspage Translating multiple languages simultaneously
1519 \nextpage Developers
1520
1521 \title AI translation
1522
1523 The AI Translation feature lets you automatically generate
1524translations for the open TS file using a local LLM via Ollama.
1525
1526 To use AI Translation you must first install
1527\l{https://github.com/jmorganca/ollama}{Ollama} and pull at least one model, for example:
1528
1529 \list
1530 \li \c{ollama pull gpt-oss:20b}
1531 \li \c{ollama pull 7shi/llama-translate:8b-q4_K_M}
1532 \endlist
1533
1534 Then start the Ollama server if not already started:
1535
1536 \code
1537 ollama serve
1538 \endcode
1539
1540 In Linguist, choose \uicontrol{Translation > AI Translation}
1541to open the AI Translation dialog:
1542
1543 \image linguist-ai-translation-dialog.webp {Screenshot of Qt Linguist AI translation window
1544 showing server settings and completed translations}
1545
1546 The dialog provides:
1547
1548 \list
1549 \li \uicontrol {Ollama Server}: the REST endpoint where Ollama listens
1550 (default \c http://127.0.0.1:11434).
1551 \li \uicontrol Model: drop-down of locally installed models.
1552 \li \uicontrol File: the TS file to translate.
1553 \li \uicontrol Filter (optional): limit to strings in a specific group (context or label).
1554 \li \uicontrol Translate button: start the AI translation.
1555 \li \uicontrol {Apply Translations} button: apply the translated items into the TS file.
1556 \endlist
1557
1558During translation, progress messages appear in the status bar and in the \uicontrol {Translation
1559Log}. When complete, you can check out the translated texts on the log. Upon clicking on
1560\uicontrol{Apply Translations}, AI-generated translations are inserted into the TS file.
1561
1562\note We suggest using one of OpenAI’s open-weight models, e.g., \e{gpt-oss:20b} or other
1563 LLMs trained for translation, e.g., \e{7shi/llama-translate:8b-q4_K_M}. Feel free to
1564 try other models to find the best combination of speed, quality, and resource usage.
1565*/
1566
1567/*!
1568 \page linguist-programmers.html
1569 \title Developers
1570
1571 \previouspage AI translation
1572 \nextpage TS File Format
1573
1574 \image front-coding.png {Illustration showing a code}
1575
1576 Design your application so that it can be adapted to various languages and
1577 regions without engineering changes.
1578
1579 \list
1580 \li \l{TS file format}
1581 \li \l{Text ID based translations}
1582 \li \l{Meta strings reference}
1583 \li \l{CMake Commands in Qt6 LinguistTools}{CMake commands}
1584 \li \l{Examples}
1585 \endlist
1586
1587 For more information, see also:
1588 \list
1589 \li \l {Internationalization with Qt}
1590 \li \l {Writing Source Code for Translation}
1591 \li \l {Localizing Applications}.
1592 \endlist
1593
1594 You can use Qt Creator wizard templates to create Qt widget-based projects
1595 with translation support. For more information, see
1596 \l {Qt Creator: Creating Projects}.
1597
1598 The following video shows how to internationalize and localize a simple
1599 example application:
1600
1601 \youtube xNIz78IPBu0
1602*/
1603
1604/*!
1605 \page linguist-programmers-examples.html
1606 \title Examples
1607
1608 \nextpage Developers
1609
1610 The following examples illustrate how to prepare Qt applications for
1611 translation:
1612
1613 \list
1614 \li \l{hellotr}{Hello tr()} is a C++ application that demonstrates the
1615 creation of a \l QTranslator object. It also shows the simplest use of
1616 the \c tr() function to mark user-visible source text for
1617 translation.
1618
1619 \li \l{arrowpad}{Arrow Pad} is a C++ application that demonstrates how to
1620 make the application load translations depending on the current locale.
1621 It also shows the use of the two-argument form of \c tr() which provides
1622 additional information to the translator.
1623
1624 \li \l{trollprint}{Troll Print} is a C++ application that demonstrates how
1625 to distinguish identical source text in the same context. It also shows
1626 how minimize the translator's work when an application is upgraded.
1627
1628 \li \l{Qt Quick I18N} demonstrates how to internationalize Qt Quick
1629 applications.
1630 \endlist
1631*/
1632
1633/*!
1634 \page linguist-ts-file-format.html
1635 \title TS file format
1636
1637 \previouspage Developers
1638
1639 \brief TS file format.
1640
1641 The TS file format used by \QL is described by the
1642 \l{http://www.w3.org/2001/XMLSchema}{XSD} presented below,
1643 which we include for your convenience. Be aware that the format
1644 may change in future Qt releases.
1645
1646 \quotefile ../../../shared/ts.xsd
1647
1648*/
1649
1650/*!
1651 \page linguist-id-based-i18n.html
1652 \title Text ID based translations
1653 \ingroup internationalization
1654
1655
1656 \brief Text ID based internationalization provides support for large scale
1657 projects with many target locales and many texts to translate.
1658
1659 The text ID translation mechanism is an \e {industrial strength} system for
1660 internationalization and localization. Each text in the application has a
1661 unique identifier (text ID) that you use in the source code instead of text.
1662 This makes it much easier to manage large numbers of translated texts.
1663
1664 \section1 Internationalizing with text IDs
1665
1666 When using text IDs instead of plain text, the general method of
1667 internationalizing an application is the same but the details are a bit
1668 different:
1669
1670 \list 1
1671
1672 \li The functions and macros for the text-ID-based translation system are
1673 different from the plain-text system. You use the qsTrId() function instead
1674 of qsTr(), the QT_TRID_NOOP() macro instead of QT_TR_NOOP(),
1675 and QT_TRID_N_NOOP() macro instead of QT_TR_N_NOOP()).
1676
1677 \li Use text IDs as user interface strings rather than plain text
1678 strings. For example, \c {qsTrId("id-back-not-front")}
1679
1680 \li You cannot specify a context parameter with a text ID, and therefore
1681 identically spelled words with different meanings need separate
1682 text IDs. For example, \c {qsTrId("id-back-backstep")} differentiates
1683 the back-step \e {Back} from the \c id-back-not-front \e {Back}.
1684
1685 \li Since context names are not allowed for text-ID-based translations,
1686 \QL lists the IDs in a file without context names.
1687
1688 \li The \e {engineering English} text that you see in the user interface for
1689 development builds is indicated with a \c {//%} comment. If you do not
1690 include this, the text ID is shown in the user interface. This is
1691 especially important when you have texts with parameters. The \c {//%}
1692 comment needs to include the parameters indicators in the string. For
1693 example, \c {//% "Number of files: %1"}
1694
1695 \li The \c {//:} comments that provide extra information to the translator
1696 are optional in the plain-text system. However, with the text-ID-based
1697 system, this extra information becomes essential because without it you only
1698 have the text ID and the translator might not be able to make a sensible
1699 translation from that without further context. You can use long descriptive
1700 text IDs and no comments, but comments are often easier to understand.
1701
1702 \endlist
1703
1704 The side-by-side code snippets below show a comparison of text-ID -based and
1705 plain-text-based translations:
1706
1707 \table
1708 \header
1709 \li text-ID-based
1710 \li plain-text-based
1711 \row
1712 \li
1713 \code
1714 Text {
1715 id: backTxt;
1716 //: The back of the object, not the front
1717 //% "Back"
1718 //~ Context Not related to back-stepping
1719 text: qsTrId("id-back-not-front");
1720 }
1721 \endcode
1722
1723 \li
1724 \code
1725 Text {
1726 id: backTxt;
1727 //: The back of the object, not the front
1728 //~ Context Not related to back-stepping
1729 text: qsTr("Back","Not front")
1730 }
1731 \endcode
1732 \endtable
1733
1734 \section1 Localizing with text IDs
1735
1736 Localizing with text IDs follows much the same process as for plain text.
1737
1738 You use the \l{Using lupdate}{lupdate} tool to generate the TS files where
1739 you add the translations. The source values in the translation files will be
1740 text IDs rather than plain text, and therefore you need either descriptive
1741 text IDs or good additional comments, or both to ensure that the translations
1742 are accurate.
1743
1744 The example text-ID-based user interface text from above results in the following
1745 content in the .ts file:
1746
1747 \code
1748 <message id="id-back-not-front">
1749 <source>Back</source>
1750 <extracomment>The back of the object, not the front</extracomment>
1751 <translation type="unfinished"></translation>
1752 <extra-Context>Not related to back-stepping</extra-Context>
1753 </message>
1754 \endcode
1755
1756 If there is no translation available for a given text (which is
1757 generally the case until late in development), the text ID will be shown in
1758 the user interface rather than a proper text. In order to make the application
1759 more usable for testing, you can make \c lrelease use the \e {Engineering English}
1760 source text (from the \c {//%} comments) as the translated text and mark it with
1761 some indicator, such as an exclamation mark (!), so you can see texts that
1762 are not yet translated.
1763
1764 \section2 Grouping ID-Based Translations
1765
1766 You can assign each ID-based translation a \e label to organize
1767 ID-based entries of large projects into smaller groups.
1768 To assign a \e label to an ID-based entry, add a \c{//@} comment
1769 naming the label, for example in C++:
1770 \code cpp
1771 //% "Open file"
1772 //@ FileOperations
1773 qtTrId("msg.open");
1774 \endcode
1775 Or in QML:
1776 \code qml
1777 //% "Open file"
1778 //@ FileOperations
1779 qsTrId("msg.open");
1780 \endcode
1781 When you open the TS file in \l {Qt Linguist}, the ID-based entries with
1782 the same \e label are grouped together, similar to text-based
1783 entries that are grouped by context.
1784 Any item without a \e label appears under \c{<unnamed label>}.
1785 \note Label names have no effect on lookup or uniqueness: IDs remain globally
1786 unique and can still be loaded via \c{qtTrId("msgid")} without referencing a
1787 label. The label tag is used only to improve the translator’s navigation
1788 and does not change runtime behavior.
1789
1790 \section1 CMake configuration
1791
1792 When building with CMake, use the prefix \c qml_ for .ts files.
1793 For example, \c qml_en.ts. In the CMakeLists.txt file, add the
1794 \l qt_add_translations function, where you list the *.ts files
1795 as values of \c TS_FILES, and set the value of RESOURCE_PREFIX to the
1796 URI of the main.qml file for the project followed by /i18n:
1797
1798 \badcode
1799 qt_add_translations(${CMAKE_PROJECT_NAME}
1800 TS_FILES i18n/qml_de_DE.ts i18n/qml_en_US.ts
1801 RESOURCE_PREFIX Main/i18n
1802 )
1803 \endcode
1804
1805 \section1 Advanced use with qmake
1806
1807 For projects that target a large number of locales, you can remove the
1808 TRANSLATIONS info from the .pro file and, instead, manage the translations
1809 with a separate script. The script can call \c lrelease and \c lupdate for each of
1810 the desired targets.
1811
1812 The updates could be scripted something like this:
1813
1814 \code
1815 lupdate -recursive <project-dir> -ts <project-dir>/i18n/myapp-text_en_GB.ts
1816 lupdate -recursive <project-dir> -ts <project-dir>/i18n/myapp-text_en_US.ts
1817 ...
1818 \endcode
1819
1820 The generation of the final .qm files could be scripted something like this:
1821
1822 \code
1823 lrelease <project-dir>/i18n/myapp-text_en_GB.ts
1824 lrelease <project-dir>/i18n/myapp-text_en_US.ts
1825 ...
1826 \endcode
1827
1828*/
1829
1830/*!
1831 \page linguist-meta-strings-reference.html
1832 \title Meta strings reference
1833 \ingroup internationalization
1834
1835 \previouspage Text ID based translations
1836
1837 \brief Reference guide for meta strings used in Qt's translation system.
1838
1839 Meta strings are special comments that provide additional information to
1840 lupdate and \QL for translation processing. They use specific
1841 prefixes to identify their purpose and can be used in C++, QML, and Python code.
1842
1843 \section1 Meta string syntax overview
1844
1845 Meta strings are special comments that use specific prefixes to provide lupdate
1846 with additional information about translations:
1847
1848 \table
1849 \header
1850 \li Meta String
1851 \li Purpose
1852 \li Usage
1853 \row
1854 \li \c{//:}
1855 \li Extra comment for translators
1856 \li Provides context and guidance to help translators
1857 \row
1858 \li \c{//%}
1859 \li Source text (engineering English)
1860 \li Defines display text for ID-based translations during development
1861 \row
1862 \li \c{//@}
1863 \li Label for grouping
1864 \li Organizes ID-based translations into logical groups
1865 \row
1866 \li \c{//~}
1867 \li Extra key-value metadata
1868 \li Stores additional custom information about the translation
1869 \row
1870 \li \c{// TRANSLATOR}
1871 \li Magic comment for context
1872 \li Provides context information about the class or file
1873 \endtable
1874
1875 \note The \c{//=} meta string for message ID mapping is deprecated and should not be used in new code.
1876
1877 \section1 Translator comments (//:)
1878
1879 Use \c{//:} comments to provide additional context and guidance to translators.
1880 These comments appear in the \QL translation interface and help
1881 translators understand the meaning and usage of the text.
1882
1883 \section2 C++ example
1884 \code cpp
1885 //: Button to navigate backwards in the application
1886 tr("Back");
1887
1888 //: This is a file menu item that opens an existing document.
1889 //: Keep translation short to fit in menu.
1890 tr("Open");
1891 \endcode
1892
1893 \section2 QML example
1894 \code qml
1895 Button {
1896 //: Emergency stop button - must be clearly visible
1897 text: qsTr("STOP")
1898 }
1899 \endcode
1900
1901 \section2 Python example
1902 \code python
1903 #: Button to navigate backwards in the application
1904 self.tr("Back")
1905
1906 #: This is a file menu item that opens an existing document.
1907 #: Keep translation short to fit in menu.
1908 self.tr("Open")
1909 \endcode
1910
1911 Multiple translator comments can be used for the same string and will be
1912 concatenated with newlines in the TS file.
1913
1914 \section2 TS file format
1915
1916 Translator comments appear as \c{<extracomment>} elements in the TS file:
1917
1918 \code xml
1919 <message>
1920 <source>Back</source>
1921 <extracomment>Button to navigate backwards in the application</extracomment>
1922 <translation type="unfinished"></translation>
1923 </message>
1924 \endcode
1925
1926 \section1 Source text (//%)
1927
1928 The \c{//%} meta string defines the \e{engineering English} text that appears
1929 in the user interface during development when using ID-based translations.
1930 This is essential for making the application usable before translations
1931 are complete.
1932
1933 \section2 C++ example
1934 \code cpp
1935 //% "Save Document"
1936 qtTrId("file.save");
1937
1938 //% "Found %n items"
1939 qtTrId("search.results", count);
1940 \endcode
1941
1942 \section2 QML example
1943 \code qml
1944 Text {
1945 //% "Welcome to the application"
1946 text: qsTrId("welcome.message")
1947 }
1948 \endcode
1949
1950 \section2 Important notes
1951 \list
1952 \li Include parameter placeholders (%1, %n) in the source text
1953 \li The source text should be production-ready English
1954 \li Without //% comments, the text ID itself appears in the UI
1955 \endlist
1956
1957 \section2 TS file format
1958
1959 Source text appears as the \c{<source>} element:
1960
1961 \code xml
1962 <message id="file.save">
1963 <source>Save Document</source>
1964 <translation type="unfinished"></translation>
1965 </message>
1966 \endcode
1967
1968 \section1 Labels (//@)
1969
1970 Use \c{//@} meta strings to organize ID-based translations into logical
1971 groups or categories within \QL. This is particularly useful
1972 for large projects with many translation strings.
1973
1974 \note The \c{//@} meta string is only intended for ID-based translations
1975 (qtTrId/qsTrId) and should not be used with text-based translations (tr/qsTr).
1976
1977 \section2 C++ example
1978 \code cpp
1979 //% "New Document"
1980 //@ FileOperations
1981 qtTrId("file.new");
1982
1983 //% "Print Document"
1984 //@ FileOperations
1985 qtTrId("file.print");
1986
1987 //% "Connection failed"
1988 //@ NetworkErrors
1989 qtTrId("network.error.connection");
1990 \endcode
1991
1992 \section2 QML example
1993 \code qml
1994 Button {
1995 //% "Login"
1996 //@ Authentication
1997 text: qsTrId("auth.login")
1998 }
1999 \endcode
2000
2001 \note Labels are not applicable to Python translations since Python only supports
2002 text-based translations (self.tr()) and not ID-based translations.
2003
2004 Strings with the same label appear grouped together in \QL,
2005 making it easier for translators to work on related content.
2006
2007 \section2 TS file format
2008
2009 Labels appear as a \c{label} element:
2010
2011 \code xml
2012 <message id="file.new" label="FileOperations">
2013 <source>New Document</source>
2014 <label>FileOperations</label>
2015 <translation type="unfinished"></translation>
2016 </message>
2017 \endcode
2018
2019 \section1 Extra metadata (//~)
2020
2021 The \c{//~} meta string allows you to attach arbitrary key-value metadata
2022 to translations. This can be used for custom processing or translator
2023 guidance.
2024
2025 \section2 Syntax
2026 \code
2027 //~ key value
2028 //~ key "quoted value with spaces"
2029 \endcode
2030
2031 \section2 C++ example
2032 \code cpp
2033 //% "Error"
2034 //: Critical system error dialog
2035 //~ Severity High
2036 //~ MaxLength "20"
2037 //~ Context "Error dialogs"
2038 qtTrId("system.error");
2039 \endcode
2040
2041 \section2 QML example
2042 \code qml
2043 Text {
2044 //% "Loading..."
2045 //~ Context "Progress indicators"
2046 //~ ShowDuration "true"
2047 text: qsTrId("progress.loading")
2048 }
2049 \endcode
2050
2051 \section2 Python example
2052 \code python
2053 #~ Severity High
2054 #~ Context "Error dialogs"
2055 self.tr("Critical system error")
2056 \endcode
2057
2058 \section2 TS file format
2059
2060 Extra metadata appears as \c{<extra-*>} elements in the TS file and can be
2061 processed by custom tools or translation workflows.
2062
2063 \code xml
2064 <message id="system.error">
2065 <source>Error</source>
2066 <comment>Critical system error dialog</comment>
2067 <translation type="unfinished"></translation>
2068 <extra-Severity>High</extra-Severity>
2069 <extra-MaxLength>20</extra-MaxLength>
2070 <extra-Context>Error dialogs</extra-Context>
2071 </message>
2072 \endcode
2073
2074 \section1 TRANSLATOR magic comments
2075
2076 \c{TRANSLATOR} comments provide context information about a class or
2077 source file to help translators understand where translations are used.
2078
2079 \section2 C++ example
2080 \snippet doc_src_linguist-manual.cpp 5
2081
2082 \section2 QML example
2083 \code qml
2084 // TRANSLATOR LoginDialog Login dialog for user authentication
2085 Item {
2086 Text {
2087 text: qsTr("Username")
2088 }
2089 }
2090 \endcode
2091
2092 \section2 Python example
2093 \code python
2094 # TRANSLATOR MainWindow
2095 #
2096 # Main application window containing the primary user interface.
2097 # Keep button labels concise due to space constraints.
2098 #
2099 class MainWindow(QMainWindow):
2100 def setupUi(self):
2101 self.tr("File") # translations for this context
2102 \endcode
2103
2104 \section2 TS file format
2105
2106 TRANSLATOR comment appear as a \c{<message>} elements with empty source text
2107 on the \c{<context>} element:
2108
2109 \code xml
2110 <context>
2111 <name>Main</name>
2112 <message>
2113 <source></source>
2114 <comment>LoginDialog Login dialog for user authentication</comment>
2115 <translation></translation>
2116 </message>
2117 </context>
2118 \endcode
2119
2120 \section1 Combining meta strings
2121
2122 Meta strings can be combined to provide comprehensive translation metadata:
2123
2124 \section2 Complete C++ example
2125 \code cpp
2126 //: File dialog - confirm destructive action
2127 //: This will permanently delete the selected files
2128 //% "Delete Selected Files"
2129 //@ FileOperations
2130 //~ Severity High
2131 //~ RequiresConfirmation "true"
2132 qtTrId("file.delete.confirm");
2133 \endcode
2134
2135 \section2 Complete QML example
2136 \code qml
2137 Text {
2138 //: Shows current connection status to server
2139 //: Updates automatically every few seconds
2140 //% "Connected to server"
2141 //@ NetworkStatus
2142 //~ UpdateFrequency "5000ms"
2143 //~ Color "green"
2144 text: qsTrId("status.connected")
2145 }
2146 \endcode
2147
2148 \section1 Best practices
2149
2150 \list
2151 \li Use translator comments (//:) generously to provide context
2152 \li Always include source text (//%) for ID-based translations
2153 \li Group related translations using labels (//@) in large projects
2154 \li Place meta strings immediately before the translation function call
2155 \li Keep translator comments clear and concise but informative
2156 \li Use consistent naming for labels and extra metadata keys
2157 \endlist
2158*/