Warning, /frameworks/ki18n/docs/programmers-guide.md is written in an unsupported language. File is not indexed.
0001 Programmer's Guide {#prg_guide} 0002 ================== 0003 0004 - [Introduction](#intro) 0005 - [Writing Messages](#write_i18n) 0006 - [General Messages](#gen_usage) 0007 - [Specialized Messages](#spec_usage) 0008 - [Placeholder Substitution](#subs_notes) 0009 - [Writing Good Texts](#good_text) 0010 - [Writing Good Contexts](#good_ctxt) 0011 - [Extraction-Only Macros](#i18n_noop) 0012 - [Messages before creation of Q*Application instance](#before_qapp) 0013 - [Connecting Calls to Catalogs](#link_cat) 0014 - [Connecting to Catalogs in Application Code](#link_prog) 0015 - [Connecting to Catalogs in Library Code](#link_lib) 0016 - [Connecting to Catalogs in Non-Code Files](#link_noncode) 0017 - [Handling Catalog Files](#handle_cat) 0018 - [Extracting Templates](#handle_extract) 0019 - [Placing and Installing Catalogs](#handle_install) 0020 - [Updating Catalogs](#handle_update) 0021 - [Semantic Markup](#kuit_markup) 0022 - [Defining Tags](#kuit_def_tags) 0023 - [Selecting Visual Format](#kuit_sel_fmt) 0024 - [Escaping](#kuit_escape) 0025 - [Predefined Tags](#kuit_tags) 0026 - [Predefined Entities](#kuit_ents) 0027 - [Localizing Non-Text Resources](#non_text) 0028 - [Further References](#refs) 0029 0030 <a name="intro"> 0031 0032 ## Introduction 0033 0034 *Internationalization* (i18n) is the process of preparing 0035 the source code such that the running program can receive and 0036 output user-visible information in various human languages, or, 0037 more precisely, *locales*. This is because the same language may 0038 be spoken at several places which differ in other details of relevance 0039 to the software internationalization (e.g. dialect, calendar, etc). 0040 I18n is performed by the programmer. 0041 *Localization* (l10n) is the process of adapting relevant 0042 program resources for a particular locale. 0043 L10n is performed by the translator, who is usually a native of the locale. 0044 0045 User interface text is the most prominent resource needing l10n. 0046 In the source code, there are two general approaches 0047 to writing i18n'd user-visible strings, hereafter called *messages*. 0048 In the first approach, the programmer writes symbolic identifier in place 0049 of actual message text, and then for each language there is a file, 0050 called translation *catalog*, which contains the actual text linked 0051 to the appropriate identifier. 0052 For example, in the code: 0053 0054 ~~~ 0055 QString msg = getId("out_of_disk_space"); 0056 ~~~ 0057 0058 and in the translation catalog: 0059 0060 ~~~ 0061 out_of_disk_space "There is no space left on the disk." 0062 ~~~ 0063 0064 In the second approach, the programmer writes actual text inside 0065 the source code, in an agreed upon human language, 0066 which is usually American English. Then there is a translation catalog 0067 for every *other* language, in which English and translated text of 0068 the message are linked. For example, in the code: 0069 0070 ~~~ 0071 QString msg = i18n("There is no space left on the disk."); 0072 ~~~ 0073 0074 and in the translation catalog: 0075 0076 ~~~ 0077 msgid "There is no space left on the disk." 0078 msgstr "Nema više prostora na disku." 0079 ~~~ 0080 0081 One may observe that the second approach is technically a generalization 0082 of the first approach. However, in actual use there are non-negligible 0083 differences in the i18n/l10n workflow between these approaches, 0084 and therefore they are treated as qualitatively different. 0085 0086 Both approaches -- the symbolic-identifier and the actual-text -- have 0087 some advantages and disadvantages over each other. That is why today 0088 both are in use, in software i18n in general. Within free software, 0089 though, the actual-text approach is considerably more widespread, 0090 as embodied in the GNU Gettext i18n system. Whether this is a historical 0091 accident, or due to sensibilities of people writing free software, 0092 is left to the interested reader to research. 0093 0094 The KDE Ki18n library, being built atop Gettext, provides 0095 the actual-text approach. In the following it is described 0096 how to use Ki18n, from the viewpoint of programmers and maintainers. 0097 Basic instructions are split into three parts: 0098 0099 \li The first part deals with how to write i18n messages in the code. 0100 This is the largest and the most important part, since there are 0101 many nuances to preparing quality messages for translation. 0102 Section: \ref write_i18n. 0103 0104 \li The second part describes how to connect particular translation calls 0105 with particular translation catalogs, so that the system can know 0106 in which catalogs to search for translations. 0107 In particular, there are some differences here depending on whether 0108 the piece of code is an application or a library. 0109 Section: \ref link_cat. 0110 0111 \li The third part explains how to *extract* messages from the code, 0112 in order to create the translation *template*. 0113 The template is simply a clean translation catalog (having only English 0114 part of each message), which the translator copies over and fills in 0115 the translations for a particular language. 0116 Then it is shown how and where to install translation catalogs, 0117 and how to update existing translation catalogs to newly extracted 0118 templates (after some new development has been done, causing 0119 new messages to appear, some to be removed, and some modified). 0120 Unlike in the GNU Gettext manual, here there are no dependencies or 0121 references to a particular software build system; 0122 this is left to the maintainer to choose. 0123 Section: \ref handle_cat. 0124 0125 There are also two special topics: 0126 0127 \li Some programmers like to have more structure and consistency 0128 in message texts, and for them Ki18n provides 0129 a customizable semantic markup. 0130 Section: \ref kuit_markup. 0131 0132 \li Sometimes there are program resources other than text 0133 that require localization. 0134 Ki18n provides a generic, though rudimentary solution for such cases. 0135 Section: \ref non_text. 0136 0137 0138 <a name="write_i18n"> 0139 0140 ## Writing Messages 0141 0142 Most messages can be internationalized with simple `i18n*` calls, 0143 which are described in the section \ref gen_usage. 0144 A few messages may require treatment with `ki18n*` calls, 0145 and when this is needed is described in the section \ref spec_usage. 0146 Argument substitution in messages is performed using the familiar 0147 Qt syntax `%<number>`, but there may be some differences; 0148 the section \ref subs_notes gives some notes about placeholders. 0149 Finally, guidelines for writing good messages are given 0150 in sections \ref good_text and \ref good_ctxt. 0151 0152 <a name="gen_usage"> 0153 0154 ### General Messages 0155 0156 General messages are wrapped with `i18n*` calls. 0157 These calls are *immediate*, which means that they return 0158 the final localized text (including substituted arguments) 0159 as a `QString` object, that can be passed to UI widgets. 0160 0161 The most frequent message type, a simple text without any arguments, 0162 is handled like this: 0163 0164 ~~~ 0165 QString msg = i18n("Just plain info."); 0166 ~~~ 0167 0168 The message text may contain arbitrary Unicode characters, 0169 and the source file *must* be UTF-8 encoded. 0170 Ki18n supports no other character encoding. 0171 0172 If there are some arguments to be substituted into the message, 0173 `%<number>` placeholders are put into the text at desired positions, 0174 and arguments are listed after the string: 0175 0176 ~~~ 0177 QString msg = i18n("%1 has scored %2", playerName, score); 0178 ~~~ 0179 0180 Arguments can be of any type for which there exists an overloaded 0181 `KLocalizedString::subs` method. 0182 Up to 9 arguments can be inserted in this fashion, due to the fact that 0183 `i18n` calls are realized as overloaded templates. 0184 If more than 9 arguments are needed, which is extremely rare, 0185 a `ki18n*` call (described later) must be used. 0186 0187 Sometimes a short message in English is ambiguous to translators, 0188 possibly leading to a wrong translations. 0189 Ambiguity can be resolved by providing a context string along the text, 0190 using the `i18nc` call. In it, the first argument is the context, 0191 which only the translator will see, and the second argument is the text 0192 which the user will see: 0193 0194 ~~~ 0195 QString msg = i18nc("player name - score", "%1 - %2", playerName, score); 0196 ~~~ 0197 0198 Section \ref good_ctxt gives a few pointers on when contexts are needed, 0199 and what they should contain. 0200 0201 In messages stating how many of some kind of objects there are, 0202 where the number of objects is inserted at run time, it is necessary 0203 to differentiate between *plural forms* of the text. 0204 In English there are only two forms, one for number 1 (singular) and 0205 another form for any other number (plural). 0206 In other languages this might be more complicated (more than two forms), 0207 or it might be simpler (same form for all numbers). 0208 This is handled properly by using the `i18np` plural call: 0209 0210 ~~~ 0211 QString msg = i18np("%1 image in album %2", "%1 images in album %2", 0212 numImages, albumName); 0213 ~~~ 0214 0215 The plural form is decided by the first integer-valued argument, 0216 which is `numImages` in this example. In rare cases when there are 0217 two or more integer arguments, they should be ordered carefully. 0218 0219 In QML code, due to some limitations, always the first argument 0220 will be treated as plural-deciding, so it should be an appropriate 0221 number (integer or a round double); otherwise, behavior is undefined. 0222 0223 It is also allowed to omit the plural-deciding placeholder, for example: 0224 0225 ~~~ 0226 QString msg = i18np("One image in album %2", "%1 images in album %2", 0227 numImages, albumName); 0228 ~~~ 0229 0230 or even: 0231 0232 ~~~ 0233 QString msg = i18np("One image in album %2", "More images in album %2", 0234 numImages, albumName); 0235 ~~~ 0236 0237 If the code context is such that the number is always greater than 1, 0238 the plural call must be used nevertheless. 0239 This is because in some languages there are different plural forms 0240 for different classes of numbers; in particular, the singular form 0241 may be used for numbers other than 1 (e.g. those ending in 1). 0242 0243 If a message needs both context and plural forms, this is provided by 0244 `i18ncp` call: 0245 0246 ~~~ 0247 QString msg = i18ncp("file on a person", "1 file", "%1 files", numFiles); 0248 ~~~ 0249 0250 0251 In the basic `i18n` call (no context, no plural) it is not allowed 0252 to put a literal string as the first argument for substitution. 0253 In debug mode this will even trigger a static assertion, 0254 resulting in compilation error. This serves to prevent misnamed calls: 0255 context or plural frequently needs to be added at a later point to 0256 a basic call, and at that moment the programmer may forget to update 0257 the call name from `i18n` to `i18nc/p`. 0258 0259 Furthermore, an empty string should never be wrapped with 0260 a basic `i18n` call (no `i18n("")`), 0261 because in translation catalog the message with empty text 0262 has a special meaning, and is not intended for client use. 0263 The behavior of `i18n("")` is undefined, 0264 and there will be some warnings in debug mode. 0265 0266 There is also a complement of `i18nd*` calls 0267 (`i18nd`, `i18ndc`, `i18ndp`, `i18ndcp`), 0268 which are not supposed to be used directly, 0269 but as will be explained in the section \ref link_cat. 0270 0271 <a name="spec_usage"> 0272 0273 ### Specialized Messages 0274 0275 There are some situations where `i18n*` calls are not sufficient, 0276 or are not convenient enough. 0277 One obvious case is if more than 9 arguments need to be substituted. 0278 Another case is if it would be easier to substitute arguments later on, 0279 after the line with the i18n call. 0280 For cases such as these, `ki18n*` calls can be used. 0281 These calls are *deferred*, which means that they do not return 0282 the final translated text as `QString`, but instead return 0283 a `KLocalizedString` instance which needs further treatment. 0284 Arguments are then substituted one by one using 0285 `KLocalizedString::subs` methods, and after all arguments 0286 have been substituted, the translation is finalized by one of 0287 `KLocalizedString::toString` methods (which return `QString`). 0288 For example: 0289 0290 ~~~ 0291 KLocalizedString ks; 0292 case (reportSource) { 0293 SRC_ENG: ks = ki18n("Engineering reports: %1"); break; 0294 SRC_HEL: ks = ki18n("Helm reports: %1"); break; 0295 SRC_SON: ks = ki18n("Sonar reports: %1"); break; 0296 default: ks = ki18n("General report: %1"); 0297 } 0298 QString msg = ks.subs(reportText).toString(); 0299 ~~~ 0300 0301 0302 `subs` methods do not update the `KLocalizedString` instance on which 0303 they are invoked, but return a copy of it with one argument slot filled. 0304 This allows to use `KLocalizedString` instances as a templates 0305 for constructing final texts, by supplying different arguments. 0306 0307 Another use for deferred calls is when special formatting of arguments 0308 is needed, like requesting the field width or number of decimals. 0309 `subs` methods can take these formatting parameters. 0310 In particular, arguments should not be formatted in a custom way, 0311 because `subs` methods will also take care of proper localization 0312 (e.g. use either dot or comma as decimal separator in numbers, etc): 0313 0314 ~~~ 0315 // BAD (number not localized): 0316 QString msg = i18n("Rounds: %1", myNumberFormat(n, 8)); 0317 // Good: 0318 QString msg = ki18n("Rounds: %1").subs(n, 8).toString(); 0319 ~~~ 0320 0321 0322 Like with `i18n`, there are context, plural, and context-plural 0323 variants of `ki18n:` 0324 0325 ~~~ 0326 ki18nc("No function", "None").toString(); 0327 ki18np("File found", "%1 files found").subs(n).toString(); 0328 ki18ncp("Personal file", "One file", "%1 files").subs(n).toString(); 0329 ~~~ 0330 0331 0332 `toString` methods can be used to override the global locale. 0333 To override only the language of the locale, `toString` can take 0334 a list of languages for which to look up translations 0335 (ordered by decreasing priority): 0336 0337 ~~~ 0338 QStringList myLanguages; 0339 ... 0340 QString msg = ki18n("Welcome").toString(myLanguages); 0341 ~~~ 0342 0343 The section \ref link_cat describes how to specify 0344 the translation *domain*, a canonical name for the catalog file 0345 from which `*i18n*` calls will draw translations. 0346 But `toString` can always be used to override the domain for a given call, 0347 by supplying a specific domain: 0348 0349 ~~~ 0350 QString trName = ki18n("Georgia").toString("country-names"); 0351 ~~~ 0352 0353 Relevant here is the set of `ki18nd*` calls 0354 (`ki18nd`, `ki18ndc`, `ki18ndp`, `ki18ndcp`), 0355 which can be used for the same purpose, 0356 but which are not intended to be used directly. 0357 This will also be covered in the section \ref link_cat. 0358 0359 <a name="dyn_ctxt"> 0360 0361 #### Dynamic Contexts 0362 0363 Translators are provided with the capability to script translations, 0364 such that the text changes based on arguments supplied at run time. 0365 For the most part, this feature is transparent to the programmer. 0366 However, sometimes the programmer may help in this by providing 0367 a *dynamic* context to the message, through 0368 `KLocalizedString::inContext` methods. 0369 Unlike the static context, the dynamic context changes at run time; 0370 translators have the means to fetch it and use it to script 0371 the translation properly. An example: 0372 0373 ~~~ 0374 KLocalizedString ks = ki18nc("%1 is user name; may have " 0375 "dynamic context gender=[male,female]", 0376 "%1 went offline"); 0377 if (knownUsers.contains(user) && !knownUsers[user].gender.isEmpty()) { 0378 ks = ks.inContext("gender", knownUsers[user].gender); 0379 } 0380 QString msg = ks.subs(user).toString(); 0381 ~~~ 0382 0383 Any number of dynamic contexts, with different keys, can be added like this. 0384 Normally every message with a dynamic context should also have 0385 a static context, like in the previous example, informing the translator 0386 of the available dynamic context keys and possible values. 0387 Like `subs` methods, `inContext` does not modify the parent instance, 0388 but returns a copy of it. 0389 0390 <a name="before_qapp"> 0391 0392 ### Messages before creation of Q*Application instance 0393 0394 Fetching the translated messages only works after the Q*Application 0395 instance has been created. So any code which will be executed before 0396 and which handles text that should be translated has to delay 0397 the actual lookup in the catalog (like other locale-dependent actions), 0398 in one of two ways: 0399 either by using statically initialized character arrays wrapped in 0400 `kli18n*` functions for extraction, and later making the 0401 actual `i18n*` calls (see section \ref i18n_noop); 0402 or by using `ki18n*` calls to create `KLocalizedString` instances, 0403 which do not perform immediate catalog lookup, and later fetching 0404 the actual translation through their toString() methods (see 0405 section \ref spec_usage); 0406 0407 One reason for this is that Gettext follows the standard C/POSIX locale 0408 settings. By standard on the start of a program all locale categories are 0409 fixed to the "C" locale, including the locale for the message catalog 0410 category (LC_MESSAGES). 0411 To use instead the locales specified by the environment variables, 0412 the locale values in the runtime need to be set to an empty string. 0413 This is usually done in one go for all locale categories by this call: 0414 ~~~ 0415 setlocale(LC_ALL, ""); 0416 ~~~ 0417 From this point on the locale specific environment variables 0418 "LANGUAGE", "LC_*" and "LANG" are considered for deciding which locale 0419 to use for which category. This includes Gettext when picking the 0420 message catalog to use. 0421 0422 The constructor of QCoreApplication (and thus its subclasses) does a call 0423 like that. Which means any `i18n*` calls done _after_ the creation of the 0424 QCoreApplication instance (or of its subclasses) will use a message catalog 0425 based on the locale specific environment variables, as one usually expects, 0426 But any calls _before_ will use a message catalog for the "C" locale. 0427 0428 <a name="subs_notes"> 0429 0430 ### Placeholder Substitution 0431 0432 Hopefully, most of the time `%<number>` placeholders are substituted 0433 in the way one would intuitively expect them to be. 0434 Nevertheless, some details about substitution are as follows. 0435 0436 Placeholders are substituted in one pass, so there is no need 0437 to worry about what will happen if one of the substituted arguments 0438 contains a placeholder, and another argument is substituted after it. 0439 0440 All same-numbered placeholders are substituted with the same argument. 0441 0442 Placeholders directly index arguments: they should be numbered from 1 0443 upwards, without gaps in the sequence, until each argument is indexed. 0444 Otherwise, error marks will be inserted into message at run time 0445 (when the code is compiled in debug mode), and any invalid placeholder 0446 will be left unsubstituted. 0447 The exception is the plural-deciding argument in plural calls, 0448 where it is allowed to drop its placeholder, 0449 in either the singular or the plural text. 0450 0451 If none of the arguments supplied to a plural call is integer-valued, 0452 an error mark will be inserted into the message at run time 0453 (when compiled in debug mode). 0454 0455 Integer arguments will be by default formatted as if they denote 0456 an amount, according to locale rules (thousands separation, etc.) 0457 But sometimes an integer is a numerical identifier (e.g. port number), 0458 and then it should be manually converted into `QString` beforehand 0459 to avoid treatment as amount: 0460 0461 ~~~ 0462 i18n("Listening on port %1.", QString::number(port)); 0463 ~~~ 0464 0465 0466 <a name="good_text"> 0467 0468 ### Writing Good Texts 0469 0470 When writing message texts, sometimes it is tempting to assemble text 0471 from pieces such as to have less repetition. 0472 However, such shortcuts frequently cannot work for other languages, 0473 and are almost always confusing to translators. 0474 The first rule of writing good message texts is therefore to 0475 *keep sentences together and clearly structured* 0476 (or "no word puzzles"), even at the cost of some repetition. 0477 0478 At its basic, this rule means always to use placeholders for insertion 0479 of run time arguments, rather than string concatenation. For example: 0480 0481 ~~~ 0482 // BAD: 0483 i18n("File ") + filePath + i18n(" not found."); 0484 // Good: 0485 i18n("File %1 not found.", filePath); 0486 ~~~ 0487 0488 This is rather obvious, since it also results in clearer and shorter code. 0489 But sometimes placeholders can be overused: 0490 0491 ~~~ 0492 // BAD: 0493 i18n("This contact is now %1.", 0494 isOnline ? i18n("online") : i18n("offline")); 0495 // Good: 0496 isOnline ? i18n("This contact is now online.") 0497 : i18n("This contact is now offline."); 0498 ~~~ 0499 0500 The shorter version here is bad, because the sentence structure of 0501 translation may need to change by more than the one word, 0502 and also because a less thorough translator may fail to check 0503 in which way the short messages "online" and "offline" are used. 0504 0505 If an otherwise long text needs to differ in only small part, 0506 then a reasonable solution is to split it at sentence level, 0507 but also explain the situation to translators through context: 0508 0509 ~~~ 0510 // BAD: 0511 i18n("Something very long here. This contact is now %1.", 0512 isOnline ? i18n("online") : i18n("offline")); 0513 // Good: 0514 i18nc("%1 one of the 'This contact...' messages below", 0515 "Something very long here. %1", 0516 isOnline ? i18n("This contact is now online.") 0517 : i18n("This contact is now offline.")); 0518 // BAD: 0519 i18n("Something very long here. ") 0520 + isOnline ? i18n("This contact is now online.") 0521 : i18n("This contact is now offline."); 0522 ~~~ 0523 0524 The third version above is bad because, firstly, the translator 0525 may wonder about the trailing space in the first message or 0526 simply overlook it, and secondly, there may be some cross-dependency 0527 between the translation of the long message and the short messages. 0528 In general, insertions of one message into another should *always* 0529 be accompanied by contexts, and composition-significant 0530 leading and trailing whitespace should be avoided. 0531 0532 The second basic rule of writing good texts is to 0533 *expose every user-visible text for translation*. 0534 One should *never* make assumptions of the type 0535 "this does not need translation" or "it will be same in every language". 0536 0537 One example where programmers sometimes make such assumption 0538 are compositions without any letters: 0539 0540 ~~~ 0541 // BAD: 0542 QString("%1: %2").arg(albumName, playCount); 0543 // Good: 0544 i18nc("album name: play count", "%1: %2", albumName, playCount) 0545 ~~~ 0546 0547 Here, in some languages the arrangement of whitespace will need to differ 0548 (e.g. a space may be needed before the colon as well). 0549 Letter-free compositions should also normally be equipped with context, 0550 because, for example, separation may depend on type of arguments. 0551 0552 Another example of user-visible texts sometimes wrongly omitted 0553 from i18n are proper names: 0554 0555 ~~~ 0556 // BAD: 0557 label1->setText(i18n("Written by:")); 0558 label2->setText("Roofus McBane"); 0559 // Good: 0560 label1->setText(i18n("Written by:")); 0561 label2->setText(i18n("Roofus McBane")); 0562 ~~~ 0563 0564 Proper names too may need localization, for example, transliteration 0565 when the target language uses a different writing system. 0566 This holds for proper names of people, and of anything else. 0567 0568 When it comes to text markup, like the HTML subset supported by 0569 Qt rich text processing, opinions are divided on how much of it 0570 to expose for translation. One argument goes that markup may be 0571 confusing for translators, and that exposing it increases 0572 the chance of syntactical errors in translation. 0573 This is true as such, but it should be balanced with situations where, 0574 either, the translator needs to modify the markup, 0575 or, the markup will convey some context to translator. 0576 For example, typographical modifiers should always be left in: 0577 0578 ~~~ 0579 // BAD: 0580 label->setText("<b>" + i18n("Disk almost full:") + "</b>"); 0581 // Good: 0582 label->setText(i18n("<b>Disk almost full:</b>")); 0583 ~~~ 0584 0585 because the target language may have different typographical standards 0586 (e.g. CJK languages tend to avoid boldface in text body font sizes, 0587 as it makes ideographs harder to recognize). 0588 Especially if tags are found around internal parts of the message text, 0589 it would be ungainly to hide them, e.g. by placeholder insertion. 0590 But, values to tag attributes, such as links in <tt>\<a href='...'></tt>, 0591 tags, should be inserted through placeholders 0592 (unless it is expected that translators provide localized values). 0593 In this example: 0594 0595 ~~~ 0596 // Good: 0597 i18n("<p>Preprocessing has failed.</p>" 0598 "<p>Please check your bracketed images stack.</p>" 0599 "<p>Click \"Details\" to show processing details.</p>") 0600 ~~~ 0601 0602 `<p>` tags could be avoided by splitting this message into 0603 one message per sentence, but this should not be done, because 0604 paragraphs should be translated as single units of meaning. 0605 0606 Another important point about XML-like text markup, is to try and keep it 0607 well-formed in XML sense on the level of standalone message. For example: 0608 0609 ~~~ 0610 // BAD (for translation, although fine by HTML / Qt rich text): 0611 i18n("<p>Some sentence." 0612 "<p>Another sentence."); 0613 // Good: 0614 i18n("<p>Some sentence.</p>" 0615 "<p>Another sentence.</p>"); 0616 ~~~ 0617 0618 Well-formedness is good because the most frequent error in translation 0619 in presence of markup is mistyping (or miscopying) a tag. 0620 If the original text is well-formed, a translation checker tool 0621 can require the same of translation, and signal when that is not so. 0622 The previous example of non-well-formedness was perhaps trivial; 0623 in practice, non-trivial examples usually break some other rules too 0624 (e.g. no word puzzles). 0625 0626 <a name="good_ctxt"> 0627 0628 ### Writing Good Contexts 0629 0630 The message context, given as first argument in `*i18nc` calls, 0631 is of great help to translators. Unfortunately, to a programmer it is 0632 not always clear when a context is needed, or what it should state. 0633 So, the very first rule of writing good contexts is to 0634 *listen to the translators asking for contexts*. 0635 When taking suggestions from translators, there is no need to worry if 0636 the proposed context will be sufficient for "all" languages. 0637 It is fine to simply add the information that a translator into 0638 particular language requested, and wait for translators into other 0639 languages to maybe request some other context information as well. 0640 0641 Having said this, some apriori guidelines on contexts can be followed. 0642 0643 Since in English the form of an adjective does not change based on 0644 the gender of the noun it modifies, properly translating messages which 0645 are single standalone adjectives will be impossible in many languages 0646 without a context. So, in general, every message which is a standalone 0647 adjective should have context: 0648 0649 ~~~ 0650 i18nc("new file", "New"); 0651 i18nc("default action", "Default"); 0652 ~~~ 0653 0654 0655 Lists of related items typically benefit from having the same context, 0656 since they should all be translated in the same style: 0657 0658 ~~~ 0659 i18nc("IPv4 configuration method", "Automatic (VPN)"); 0660 i18nc("IPv4 configuration method", "Automatic (VPN) addresses only"); 0661 i18nc("IPv4 configuration method", "Automatic (PPP)"); 0662 i18nc("IPv4 configuration method", "Automatic (PPP) addresses only"); 0663 ... 0664 ~~~ 0665 0666 0667 When there are placeholders in the text for which it is not clear, 0668 from the text alone, what kind of argument they represent, 0669 this should be explained in the context: 0670 0671 ~~~ 0672 i18nc("%1 old file path, %2 new file path", 0673 "Cannot move '%1' to '%2'.", oldPath, newPath); 0674 i18nc("%1 track URL, %2 artist name", 0675 "%1 (by %2)", trackUrl, artistName); 0676 ~~~ 0677 0678 0679 It is frequently suggested to state in the context the grammar category 0680 of the message text, such as "this is a verb" or "this is a noun". 0681 Since the grammar category of the translation does not have to be 0682 the same as that of the original, this kind of context provides 0683 circumstantial information at best (see the section \ref uimark_ctxt 0684 for what translators may use it to draw some real information about), 0685 and is worthless at worst. 0686 Also, due to relative absence of declension in English grammar, 0687 different programmers may have different opinion on the grammar category: 0688 the menu title "View", is it a verb or a noun? 0689 0690 <a name="uimark_ctxt"> 0691 0692 #### User Interface Markers 0693 0694 In the same way there exists a HIG (Human Interface Guidelines) document 0695 for the programmers to follow, translators should establish HIG-like 0696 convention for their language concerning the forms of UI text. 0697 Therefore, for a proper translation, the translator will need too know 0698 not only what does the message mean, but also where it figures in the UI. 0699 E.g. is the message a button label, a menu title, a tooltip, etc. 0700 0701 To this end a convention has been developed among KDE translators, 0702 which programmers can use to succinctly describe UI usage of messages. 0703 In this convention, the context string starts with an *UI marker* 0704 of the form `@<major>:<minor>`, and may be followed by any other 0705 usual context information, separated with a single space: 0706 0707 ~~~ 0708 i18nc("@action:inmenu create new file", "New"); 0709 ~~~ 0710 0711 0712 The major and minor component of the UI marker are not arbitrary, 0713 but are drawn from the following table. 0714 For each component, the superscript states the Ki18n release 0715 when the component was introduced. 0716 <table> 0717 <tr><th>Major</th><th>Minor</th><th>Description</th></tr> 0718 <tr><td><b>\@action</b><sup>5.0</sup></td><td></td> 0719 <td>Labels of clickable widgets which cause an action 0720 to be performed.</td></tr> 0721 <tr><td></td><td>:button<sup>5.0</sup></td> 0722 <td>Push buttons in windows and dialogs.</td></tr> 0723 <tr><td></td><td>:inmenu<sup>5.0</sup></td> 0724 <td>Menu entries that perform an action 0725 (as opposed e.g. to being checked).</td></tr> 0726 <tr><td></td><td>:intoolbar<sup>5.0</sup></td> 0727 <td>Toolbar buttons.</td></tr> 0728 <tr><td><b>\@title</b><sup>5.0</sup></td><td></td> 0729 <td>Text that is the title of a major UI element or 0730 a widget container.</td></tr> 0731 <tr><td></td><td>:window<sup>5.0</sup></td> 0732 <td>Title of a window or a (dockable) view/pane.</td></tr> 0733 <tr><td></td><td>:menu<sup>5.0</sup></td> 0734 <td>Menu title.</td></tr> 0735 <tr><td></td><td>:tab<sup>5.0</sup></td> 0736 <td>Tab name.</td></tr> 0737 <tr><td></td><td>:group<sup>5.0</sup></td> 0738 <td>Title to a group of widgets, like a group of checkboxes or 0739 radio buttons.</td> 0740 <tr><td></td><td>:column<sup>5.0</sup></td> 0741 <td>Column name in a table header, 0742 e.g. in a table view widget.</td></tr> 0743 <tr><td></td><td>:row<sup>5.0</sup></td> 0744 <td>Row name in a table.</td></tr> 0745 <tr><td><b>\@option</b><sup>5.0</sup></td><td></td> 0746 <td>Labels of option selection widgets, which can be enable/disabled 0747 or selected between.</td></tr> 0748 <tr><td></td><td>:check<sup>5.0</sup></td> 0749 <td>Checkbox label, also a checkable menu entry.</td></tr> 0750 <tr><td></td><td>:radio<sup>5.0</sup></td> 0751 <td>Radio button label.</td></tr> 0752 <tr><td><b>\@label</b><sup>5.0</sup></td><td></td> 0753 <td>Various widget labels which are not covered by any of 0754 \@action, \@title, or \@option.</td></tr> 0755 <tr><td></td><td>:slider<sup>5.0</sup></td> 0756 <td>Slider label.</td></tr> 0757 <tr><td></td><td>:spinbox<sup>5.0</sup></td> 0758 <td>Spinbox label.</td></tr> 0759 <tr><td></td><td>:listbox<sup>5.0</sup></td> 0760 <td>Label to a list box or combo box.</td></tr> 0761 <tr><td></td><td>:textbox<sup>5.0</sup></td> 0762 <td>Label to a text box or text edit field.</td></tr> 0763 <tr><td></td><td>:chooser<sup>5.0</sup></td> 0764 <td>Label to any special-purpose chooser widget, 0765 like color chooser, font chooser, etc.</td></tr> 0766 <tr><td><b>\@item</b><sup>5.0</sup></td><td></td> 0767 <td>Strings that are items from a range of possibilities or 0768 properties of a given type.</td></tr> 0769 <tr><td></td><td>:inmenu<sup>5.0</sup></td> 0770 <td>Item presented in menu (e.g. sort ordering, 0771 encoding name, etc).</td></tr> 0772 <tr><td></td><td>:inlistbox<sup>5.0</sup></td> 0773 <td>Item presented in a list or combo box.</td></tr> 0774 <tr><td></td><td>:intable<sup>5.0</sup></td> 0775 <td>Item presented in a table cell.</td></tr> 0776 <tr><td></td><td>:inrange<sup>5.0</sup></td> 0777 <td>End range labels, e.g. on sliders.</td></tr> 0778 <tr><td></td><td>:intext<sup>5.0</sup></td> 0779 <td>Words and short phrases which are inserted into 0780 a larger piece of text.</td></tr> 0781 <tr><td></td><td>:valuesuffix<sup>5.46</sup></td> 0782 <td>Suffix appended to a value, including any spacing 0783 (e.g. in a spinbox).</td></tr> 0784 <tr><td><b>\@info</b><sup>5.0</sup></td><td></td> 0785 <td>Any transient information for the user.</td></tr> 0786 <tr><td></td><td>:tooltip<sup>5.0</sup></td> 0787 <td>Expanded formulation of the widget's label, 0788 usually appearing automatically when the pointer 0789 hovers over the widget.</td></tr> 0790 <tr><td></td><td>:whatsthis<sup>5.0</sup></td> 0791 <td>Longer description of a widget's purpose and behavior, 0792 usually manually called up by the user.</td></tr> 0793 <tr><td></td><td>:placeholder<sup>5.46</sup></td> 0794 <td>A hint what input is expected in an input field, 0795 shown in the place of the input where there is none yet.</td></tr> 0796 <tr><td></td><td>:status<sup>5.0</sup></td> 0797 <td>A piece of text displayed in application's status view 0798 (e.g in the status bar).</td></tr> 0799 <tr><td></td><td>:progress<sup>5.0</sup></td> 0800 <td>Text describing the current step or state of an operation, 0801 possibly periodically updating.</td></tr> 0802 <tr><td></td><td>:usagetip<sup>5.0</sup></td> 0803 <td>A tip that comes up to inform the user about 0804 a certain possibility in a given context, 0805 e.g. a "tip of the day" on application startup.<br/> 0806 Deprecated synonym: :tipoftheday.</td></tr> 0807 <tr><td></td><td>:credit<sup>5.0</sup></td> 0808 <td>Contributor names and their contributions, 0809 e.g. in the about dialog.</td></tr> 0810 <tr><td></td><td>:shell<sup>5.0</sup></td> 0811 <td>A note, warning or error sent to application's text output stream 0812 (stdout, stderr) rather than shown in the UI.</td></tr> 0813 </table> 0814 If none of the minor components apply to a given message, 0815 a major component can be used standalone. 0816 For example, this would happen with a library-provided list of items 0817 without any immediate UI context (e.g. language or country names), 0818 where the appropriate UI marker would be just `@item`. 0819 0820 One way to extend the context after the UI marker, 0821 which is simple for the programmer yet can be very helpful for translators, 0822 is simply to add the text of the (technically or logically) parent widget. 0823 For example, if the action "New" is in the menu "File", then: 0824 0825 ~~~ 0826 i18nc("@action:inmenu File", "New") 0827 ~~~ 0828 0829 Or, if the item "Left" is found in the list box with 0830 the label "Vertical alignment": 0831 0832 ~~~ 0833 i18nc("@item:inlistbox Vertical alignment", "Left") 0834 ~~~ 0835 0836 0837 <a name="nocpp_ctxt"> 0838 0839 #### Adding Contexts in Non-C++ files 0840 0841 When Qt Designer is used to build the user interface, 0842 the \em -tr option of `uic` should be used to pass UI strings 0843 through Ki18n's `tr2i18n` function (see also \ref link_ui). 0844 This function is the equivalent of `i18n` or `i18nc`, 0845 based on whether the second argument is null or not. 0846 If a string in the `.ui` file has the attribute `comment=`, 0847 its value will be automatically used as the context argument. 0848 (In Qt Designer, this is the "disambiguation" property of a string.) 0849 Alternatively, strings can be passed to Ki18n's `tr2xi18n` function 0850 (see \ref kuit_markup). 0851 0852 In KXmlGui (`.rc`) and KConfigXT (`.kcfg`) files, 0853 contexts can be added through `context=` attributes to 0854 `text`, `label`, and `whatsthis` tags. 0855 0856 <a name="ctxt_extc"> 0857 0858 #### Disambiguation Context vs. Extracted Comment 0859 0860 The GNU Gettext system actually defines *two* types of context 0861 for translators. The type discussed so far, the first argument 0862 of `*i18nc*` calls, is called *disambiguation context*. 0863 The other type of context is *extracted comment*. 0864 In Ki18n, this other type of context is written as a code comment, 0865 in the line just preceding the message text, 0866 and starting with *i18n:* keyword: 0867 0868 ~~~ 0869 // i18n: This is a short text containing all letter of the alphabet, 0870 // e.g. for testing fonts. Translate with a sentence which can 0871 // serve the same purpose in your language. 0872 i18n("The quick brown fox jumps over the lazy dog"); 0873 ~~~ 0874 0875 0876 There are two main differences between disambiguation contexts and 0877 extracted comments. 0878 0879 The first difference is that extracted comments 0880 *do not separate messages* in the translation catalog. 0881 For example, such two messages equipped with extracted comments: 0882 0883 ~~~ 0884 // i18n: new file 0885 QString msg1 = i18n("New"); 0886 // i18n: new folder 0887 QString msg2 = i18n("New"); 0888 ~~~ 0889 0890 will show up in the translation catalog as a single message 0891 with aggregate comments: 0892 0893 ~~~ 0894 #. i18n: new file 0895 #. i18n: new folder 0896 msgid "New" 0897 msgstr "" 0898 ~~~ 0899 0900 The same two messages equipped with disambiguation contexts: 0901 0902 ~~~ 0903 QString msg1 = i18nc("new file", "New"); 0904 QString msg2 = i18nc("new folder", "New"); 0905 ~~~ 0906 0907 will show up in the translation catalog as two messages: 0908 0909 ~~~ 0910 msgctxt "new file" 0911 msgid "New" 0912 msgstr "" 0913 0914 msgctxt "new folder" 0915 msgid "New" 0916 msgstr "" 0917 ~~~ 0918 0919 0920 The second difference is that a change in extracted comment 0921 *does not invalidate the existing translation*, i.e. 0922 it will not force translators to revisit the message and revise 0923 the translation (see the section \ref handle_update for details 0924 on how this invalidation happens with disambiguation contexts). 0925 Thus, for example, if there is a "message freeze" 0926 before the next release of a piece of software, during which 0927 programmers must not modify messages so that translators can 0928 thoroughly complete their work, it is allowed to modify 0929 the extracted comment, but it is not allowed to modify 0930 the disambiguation context. 0931 0932 The Gettext manual suggests to use extracted comments as 0933 the default way of providing context for translators, 0934 and to use disambiguation contexts only when message separation 0935 is necessary. However, we (the people in the KDE community) 0936 suggest the opposite -- to use disambiguation context by default, 0937 and extracted comments only in special cases. 0938 This because there are two dangers associated with extracted comments: 0939 one is that programmer may fail to properly judge when two messages 0940 should be made separate for translation (and having to judge that 0941 all the time is a burden in the first place), and the other is that 0942 when the context change is such that translators really should revisit 0943 the message, they would not get any automatic signal about that. 0944 The message freeze advantage of extracted comments has not been 0945 observed to be very important. 0946 0947 One special case when to an use extracted comment is when the context 0948 is a multi-sentence text explaining the purpose of the message, 0949 and the context is unlikely to change (in its meaning). 0950 Another case is when the context lists a fixed set 0951 of possible translations ("meta-messages", by which translators 0952 influence some aspect of text formatting), which may expand in 0953 the future, as new possibilities are introduced at request of 0954 translators into new languages. 0955 0956 <a name="i18n_noop"> 0957 0958 ### Extraction-Only Functions 0959 0960 Sometimes it is convenient only to mark a message for extraction 0961 (into the catalog template, as described in \ref handle_extract), 0962 and to place the actual `i18n` call somewhere else. 0963 A typical case of this are global static initializers, 0964 where only POD types can be safely used. 0965 For this purpose `kli18n*` functions are provided. 0966 0967 The `kli18n` function is the counterpart to `*i18n` calls, 0968 and it is used like this: 0969 0970 ~~~ 0971 typedef struct 0972 { 0973 const KLazyLocalizedString description; 0974 const char *regExp; 0975 } term; 0976 0977 static const term items[] = { 0978 {kli18n("any character"), "."}, 0979 {kli18n("start of line"), "^"}, 0980 {kli18n("end of line"), "$"}, 0981 {kli18n("repeats, zero or more times"), "*"}, 0982 ... 0983 }; 0984 0985 ... 0986 0987 void populatePatternMenu (QMenu *menu) 0988 { 0989 for (uint i = 0; i < sizeof(items) / sizeof(items[0]); i++) { 0990 menu->addAction(new RegExpAction(menu, 0991 // ...actual i18n call here. 0992 items[i].description.toString(), 0993 items[i].regExp)); 0994 } 0995 } 0996 ~~~ 0997 0998 0999 The `kli18nc` macro is the counterpart to `*i18nc` calls: 1000 1001 ~~~ 1002 typedef struct 1003 { 1004 const KLazyLocalizedString abbrev; 1005 } unitDef; 1006 static const unitDef units[] = { 1007 {kli18nc("unit for 2^10 bytes", "KiB")}, 1008 {kli18nc("unit for 2^20 bytes", "MiB")}, 1009 ... 1010 } 1011 ... 1012 QString unitAbbrev = units[i].abbrev.toString(); 1013 ~~~ 1014 1015 Variants for singular/plural and with or without markup exist as well. 1016 Unlike the `I18N_NOOP` macros they replace, mixing different variants 1017 in the same message table is possible, e.g. to add a context to a few 1018 messages when necessary. 1019 1020 1021 <a name="link_cat"> 1022 1023 ## Connecting Calls to Catalogs 1024 1025 Every `i18n` call must look for translations in exactly 1026 one translation catalog for a given language of translation. 1027 For this purpose, a group of catalogs which have the same source text 1028 but translations into different languages, is identified by 1029 a unique canonical name, called the *domain*. 1030 Therefore, every `i18n` call must be connected to a domain. 1031 This connection is established differently for applications 1032 and libraries, though the difference is only for convenience: if desired, 1033 the more verbose library method can be used for application code as well. 1034 1035 <a name="link_prog"> 1036 1037 ### Connecting to Catalogs in Application Code 1038 1039 All `*i18n*` calls in an application can be connected 1040 to a single domain by calling the static 1041 `KLocalizedString::setApplicationDomain` method with 1042 the domain as the argument: 1043 1044 ~~~ 1045 #include <klocalizedstring.h> 1046 1047 ... 1048 1049 int main (int argc, char *argv[]) 1050 { 1051 ... 1052 KLocalizedString::setApplicationDomain("fooapp"); 1053 ... 1054 } 1055 ~~~ 1056 1057 This call must be made in the code before any `i18n` call takes place, 1058 and right after creating the instance of `QCoreApplication` or one 1059 of its subclasses. `ki18n` calls can still be made before, but the 1060 respective `KLocalizedString::toString()` has to be delayed to after that. 1061 1062 This is all there is to connecting calls and catalogs application's 1063 C++ source files. However, there may also be some non-code files 1064 that need connecting, and how to do this is some typical non-code 1065 files is described in the section \ref link_noncode. 1066 1067 <a name="link_lib"> 1068 1069 ### Connecting to Catalogs in Library Code 1070 1071 `i18n` calls in libraries must be strictly connected to library's 1072 own translation domain no matter how the library is used, 1073 and this should be fully transparent to the library's client. 1074 In particular, if the client does not use Ki18n for internationalization 1075 of its own messages, library translation must still work as expected. 1076 Therefore, in library code, the call-domain connection is established 1077 in this way: 1078 1079 ~~~ 1080 #define TRANSLATION_DOMAIN "foolib" 1081 #include <klocalizedstring.h> 1082 1083 ... 1084 1085 void some_library_function () 1086 { 1087 ... 1088 QString msg = i18n("Greetings from Foolib!"); 1089 ... 1090 } 1091 ~~~ 1092 1093 The definition of `TRANSLATION_DOMAIN` triggers 1094 the domain-specialization macro in `klocalizedstring.h`. 1095 It routes all `*i18n*` calls to their `*i18nd*` counterparts, 1096 which take the domain as their first argument. 1097 The `i18n` call from this example will thus expand into: 1098 1099 ~~~ 1100 QString msg = i18nd("foolib", "Greetings from Foolib!"); 1101 ~~~ 1102 1103 1104 It is possible to use `*i18nd*` calls explicitly, 1105 but there should be no need for that. 1106 If there are any messages that should draw translations 1107 from a special domain, it is better style-wise to use the 1108 `ki18n("...").toString(domain)` construct. 1109 1110 Definition of `TRANSLATION_DOMAIN` can be put into 1111 a private header file of the library, so that it does not have 1112 to be repeated at multiple locations. 1113 If there are some `i18n` calls in a *public* header file, 1114 definition of `TRANSLATION_DOMAIN` would propagate 1115 into and affect the application client code that uses Ki18n too. 1116 This is prevented by adding the following lines somewhere 1117 after the last `i18n` call in the public header: 1118 1119 ~~~ 1120 #undef TRANSLATION_DOMAIN 1121 #include <klocalizedstring.h> 1122 ~~~ 1123 1124 This will undefine all expansions of `*i18n*` into `*i18nd*`, 1125 leaving the client's environment clean. 1126 If instead the public header contains only `kli18n*` function calls, 1127 defining `TRANSLATION_DOMAIN` is unnecessary in the first place, 1128 since actual `i18n` calls happen somewhere else. 1129 1130 <a name="link_noncode"> 1131 1132 ### Connecting to Catalogs in Non-Code Files 1133 1134 Both KDE applications and libraries can include some non-code files 1135 which contain messages that need to be connected to a translation domain. 1136 This can be the same domain where messages from C++ code are found, 1137 or another domain, whatever seems more appropriate. 1138 In principle, each type of non-code file requires its own connection 1139 mechanism, and here it is explained how this works for 1140 typical types of non-code files found in KDE sources. 1141 1142 It is assumed in the following that all messages in the non-code file 1143 are connected to the single domain. In other words, the connection 1144 is specified on the file level rather than on the message level. 1145 1146 <a name="link_ui"> 1147 1148 #### Qt Designer (.ui) files 1149 1150 First, to have UI strings from `.ui` file passed through Ki18n, 1151 `uic` is run with `-tr tr2i18n`. This will replace all 1152 native Qt `tr` calls with Ki18n's `tr2i18n` calls 1153 in the resulting header file. 1154 Then, the generated header file needs to be post-processed 1155 to fix empty messages and include `klocalizedstring.h`. 1156 At this point, the `TRANSLATION_DOMAIN` can be defined just like 1157 in static C++ files. 1158 1159 If CMake is used as the build system, a macro that performs 1160 all of the above is provided (`ki18n_wrap_ui`). 1161 Otherwise, one could use a shell snippet such as this: 1162 1163 ~~~ 1164 domain=fooapp 1165 uifile=fooconfpage.ui 1166 uihfile=$uifile.h 1167 uic -tr tr2i18n $uifile -o $uihfile 1168 sed -i 's/tr2i18n("")/QString()/g' $uihfile 1169 sed -i 's/tr2i18n("", "")/QString()/g' $uihfile 1170 sed -i "1i\#define TRANSLATION_DOMAIN \"$domain\"\n#include <klocalizedstring.h>" $uihfile 1171 ~~~ 1172 1173 1174 If strings contain KUIT markup (section \ref kuit_markup), 1175 `tr2i18n` in the lines above should be replaced with `tr2xi18n`. 1176 1177 <a name="link_rc"> 1178 1179 #### KXmlGui (.rc) files 1180 1181 Since `.rc` files are interpreted at runtime, 1182 the translation domain connection is established simply 1183 by adding the `translationDomain` attribute to the top element: 1184 1185 ~~~ 1186 <!DOCTYPE gui SYSTEM "kpartgui.dtd"> 1187 <gui name="foolib_part" version="55" translationDomain="foolib"> 1188 ... 1189 ~~~ 1190 1191 If the `.rc` file belongs to application rather than library source, 1192 it is not necessary to set `translationDomain`. If not set, 1193 translations will be looked up in the domain set with 1194 `KLocalizedString::setApplicationDomain` call in the code. 1195 1196 If strings contain KUIT markup (section \ref kuit_markup), 1197 additionally the attribute `translationMarkup="true"` should be set. 1198 1199 <a name="link_kcfg"> 1200 1201 #### KConfigXT (.kcfg) files 1202 1203 Instructions for building the configuration code from a `.kcfg` file 1204 are contained in the `.kcfgc` file of the same base name; 1205 `kconfig_compiler` is invoked with both files as arguments. 1206 Then, the domain connection is established simply by adding 1207 the `TranslationSystem` and `TranslationDomain` fields in 1208 the `.kcfgc` file, to select Ki18n as the translation system 1209 and the appropriate translation domain: 1210 1211 ~~~ 1212 File=foolib.kcfg 1213 ... 1214 TranslationSystem=kde 1215 TranslationDomain=foolib 1216 ~~~ 1217 1218 If the `.kcfg` file is part of an application rather than a library, 1219 the `TranslationDomain` field can be omitted in order 1220 to have messages looked up in the domain set by 1221 `KLocalizedString::setApplicationDomain` call in the code. 1222 1223 If strings contain KUIT markup (section \ref kuit_markup), 1224 additionally the field `TranslationMarkup=true` should be set. 1225 1226 <a name="handle_cat"> 1227 1228 ## Handling Catalog Files 1229 1230 For translators to start working, one or more translation catalog files 1231 should be prepared, based on the `i18n` calls in the source code. 1232 The procedure to do this is called *extraction* of messages. 1233 Extraction produces empty catalog files, called *templates*. 1234 These files are in the PO format, and have `.pot` extension. 1235 Section \ref handle_extract explains how to perform extraction. 1236 1237 Once templates are ready, a translators make copies of them, 1238 with `.po` extension, and start filling them out with translations 1239 into respective languages. 1240 When translation is done, the translated catalog is committed 1241 into the source code repository. 1242 The build system is set up to install translated catalogs. 1243 Section \ref handle_install provides necessary steps for this. 1244 1245 After some development has passed, the source repository will 1246 contain many translated catalogs which are out of date with 1247 respect to latest catalog templates. 1248 Of course, translators do not have to start translating from scratch, 1249 but there are specialized tools to carry over as much of existing 1250 translation as possible, so that only new and modified texts 1251 need to be considered. 1252 Section \ref handle_update shows how this is done. 1253 1254 A usual application or a library has one translation catalog, 1255 but there can be more if there is higher modularity of the source. 1256 The following subsections refer to a single catalog wherever 1257 the extension to case with multiple catalogs is obvious, 1258 and mention multiple catalogs only where necessary. 1259 1260 <a name="handle_extract"> 1261 1262 ### Extracting Templates 1263 1264 The primary tool for collecting texts from `i18n` calls and 1265 writing out the catalog template is `xgettext`, 1266 from the official Gettext tools package. 1267 `xgettext` supports many programming languages and sublanguage 1268 environments, among which naturally C++ and Ki18n specifically. 1269 1270 The extraction process from source code files is thus simple: 1271 `xgettext` runs with appropriate options over all files, 1272 and it writes out the catalog template. 1273 For the moment masking the complete list of options as `$EXTOPTS`, 1274 `xgettext` can be run for example like this at the top of Fooapp 1275 source to create the catalog template `fooapp.pot`: 1276 1277 ~~~ 1278 find -name \*.cpp -o -name \*.h -o -name \*.qml | sort \ 1279 | xargs xgettext $EXTOPTS -o fooapp.pot 1280 ~~~ 1281 1282 Or, a list of source files that should be extracted from can be 1283 assembled separately and fed to `xgettext:` 1284 1285 ~~~ 1286 # ...create sources.list... 1287 xgettext $EXTOPTS -f sources.list -o fooapp.pot 1288 ~~~ 1289 1290 One may want to assemble the list of source files by hand 1291 or semi-automatically in order to prioritize the order of translation 1292 (messages from most important files appearing first in the catalog), 1293 to exclude some portions of the source tree from extraction, and so on. 1294 1295 `$EXTOPTS` that cover everything from Ki18n, and some generalities, 1296 should look like this: 1297 1298 ~~~ 1299 --c++ --kde \ 1300 --from-code=UTF-8 \ 1301 -c i18n \ 1302 -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 \ 1303 -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \ 1304 -kkli18n:1 -kkli18nc:1c,2 -kkli18np:1,2 -kkli18ncp:1c,2,3 \ 1305 -kI18N_NOOP:1 -kI18NC_NOOP:1c,2 \ 1306 --copyright-holder=<author-of-original-text> \ 1307 --msgid-bugs-address=<where-to-report-errors-in-original-text> 1308 ~~~ 1309 1310 `--c++ --kde` options tell `xgettext` that source files 1311 are C++ with Ki18n. `--from-code=UTF-8` specifies the encoding 1312 of source files to be UTF-8, which must be so for Ki18n. 1313 `-c i18n` states that comments for extraction start with given 1314 keyword (`// i18n: ...`). 1315 The series of `-k` options informs `xgettext` of all possible 1316 translation call names and which of their arguments to extract. 1317 Finally, options `--copyright-holder` and 1318 `--msgid-bugs-address` automatically write 1319 the corresponding information into the catalog at proper place. 1320 If there are semantic markup calls in the code (section \ref kuit_markup), 1321 the following `-k` options should be added as well: 1322 1323 ~~~ 1324 -kxi18n:1 -kxi18nc:1c,2 -kxi18np:1,2 -kxi18ncp:1c,2,3 \ 1325 -kkxi18n:1 -kkxi18nc:1c,2 -kkxi18np:1,2 -kkxi18ncp:1c,2,3 \ 1326 -kklxi18n:1 -kklxi18nc:1c,2 -kklxi18np:1,2 -kklxi18ncp:1c,2,3 \ 1327 ~~~ 1328 1329 1330 `xgettext` unfortunately cannot be directly used to extract messages 1331 from the usual XML files appearing in Qt and KDE sources -- 1332 Designer (`.ui`), KXmlGui (`.rc`) and KConfigXT (`.kcfg`) files. 1333 Therefore the `kdesdk` package provides the `extractrc` script, 1334 which extracts XML messages as dummy `i18n` calls into a dummy C++ file, 1335 This file can then be included into the list of files for `xgettext` run. 1336 The usual invocation of `extractrc` is: 1337 1338 ~~~ 1339 find -name \*.ui -o -name \*.rc -o -name \*.kcfg | sort \ 1340 | extractrc > rc.cpp 1341 # ...run xgettext with rc.cpp included in source files... 1342 rm rc.cpp 1343 ~~~ 1344 1345 1346 If the catalog being extracted is an application catalog, 1347 i.e. given as `KLocalizedString::setApplicationDomain` in the code, 1348 it should contain two meta-messages for translation credits 1349 which will be shown by `KAboutApplicationDialog`. 1350 These messages are also written as dummy `i18n` calls, 1351 usually into the same dummy C++ file with XML messages, 1352 with the following context and text: 1353 1354 ~~~ 1355 echo 'i18nc("NAME OF TRANSLATORS", "Your names");' >> rc.cpp 1356 echo 'i18nc("EMAIL OF TRANSLATORS", "Your emails");' >> rc.cpp 1357 ~~~ 1358 1359 1360 The extraction command sequence can be written down as a small script, 1361 to be run periodically by the maintainer, 1362 or it can be integrated into the build system. 1363 1364 For the code residing in the official KDE repositories 1365 a special form of the extraction script is mandated. 1366 This enables automatic overnight template extraction and feeding 1367 into dedicated translation section of KDE repositories. 1368 Details can be found at 1369 <a href="http://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems">KDE Techbase</a>. 1370 1371 <a name="handle_install"> 1372 1373 ### Placing and Installing Catalogs 1374 1375 For an application or a library which uses a single catalog, 1376 the usual organization of catalogs in the source tree is this: 1377 1378 ~~~ 1379 fooapp/ 1380 src/ 1381 doc/ 1382 po/ 1383 fooapp.pot 1384 aa.po 1385 bb.po 1386 cc.po 1387 ... 1388 ~~~ 1389 1390 Here translated catalog files are named by their language codes 1391 (`aa`, `bb`, `cc`...). 1392 In case of multiple catalogs, one directory per catalog can be created 1393 under the `po/` directory: 1394 1395 ~~~ 1396 fooapp/ 1397 src/ 1398 lib 1399 doc/ 1400 po/ 1401 fooapp/ 1402 fooapp.pot 1403 aa.po 1404 bb.po 1405 ... 1406 foolib/ 1407 foolib.pot 1408 aa.po 1409 bb.po 1410 ... 1411 ~~~ 1412 1413 An alternative organization is to have one directory per language, 1414 and name catalog files by the translation domain. 1415 In multiple catalog situation this would look like: 1416 1417 ~~~ 1418 fooapp/ 1419 src/ 1420 lib 1421 doc/ 1422 po/ 1423 templates/ 1424 fooapp.pot 1425 foolib.pot 1426 aa/ 1427 fooapp.po 1428 foolib.po 1429 bb/ 1430 fooapp.po 1431 foolib.po 1432 ... 1433 ~~~ 1434 1435 1436 Catalog templates are fully derived files, and therefore 1437 some maintainers do not like to keep them inside the repository. 1438 In that case, at least the tarball should contain the templates 1439 (i.e. they should be generated at packaging time), 1440 so that translators have somewhere to get them from. 1441 Another possibility is to upload the template to 1442 a *translation hub* (such as 1443 <a href="https://www.transifex.com/">Transifex</a>), 1444 which translators can use to upload translated catalogs back, 1445 and usually for some other features as well (assignment, review, etc). 1446 1447 If the code resides in an official KDE repository, neither templates 1448 nor translated catalogs are kept inside the source tree. 1449 Instead, translated catalogs are fetched from an appropriate place 1450 when tarball is made, using a script provided for that purpose. 1451 Details can be found at 1452 <a href="http://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems">KDE Techbase</a>. 1453 1454 No matter how the catalog files are named and organized inside 1455 the distribution tarball, they must be installed in exactly one way. 1456 The base name of the installed catalog must be their translation domain, 1457 and if the package is installed into `$PREFIX`, the installed directory 1458 tree must look like as follows: 1459 1460 ~~~ 1461 $PREFIX/ 1462 share/ 1463 locales/ 1464 aa/ 1465 LC_MESSAGES/ 1466 fooapp.mo 1467 foolib.mo 1468 bb/ 1469 LC_MESSAGES/ 1470 fooapp.mo 1471 foolib.mo 1472 ... 1473 ~~~ 1474 1475 Given that these directories are shared with other packages 1476 in the same prefix, by Gettext convention translation domains 1477 must be unique (like package names are). 1478 1479 MO files are the compiled version of PO files, and they are produced 1480 using Gettext's `msgfmt` command: 1481 1482 ~~~ 1483 msgfmt $SRCDIR/po/fooapp/aa.po -o $BUILDDIR/mo/aa/fooapp.mo 1484 ~~~ 1485 1486 Compilation and installation of catalogs should naturally be integrated 1487 into the build system. In case <a href="http://www.cmake.org/">CMake</a> 1488 is used, KDE provides CMake macros for this purpose. 1489 1490 <a name="handle_transcript"> 1491 1492 #### Placing and Installing Scripting Modules 1493 1494 Since Ki18n provides a run-time scripting capability for translators, 1495 some translators may also write the scripting module corresponding 1496 to the catalog. 1497 A scripting module is a directory named like the translation domain, 1498 and at least one JavaScript file inside, also with the same base name 1499 as the translation domain. 1500 1501 Scripting modules can be placed like this in the source tree: 1502 1503 ~~~ 1504 fooapp/ 1505 po/ 1506 fooapp.pot 1507 aa.po 1508 aa/ 1509 fooapp.js 1510 ... 1511 bb.po 1512 ... 1513 ~~~ 1514 1515 or in the per-language directory variant: 1516 1517 ~~~ 1518 fooapp/ 1519 po/ 1520 templates/ 1521 fooapp.pot 1522 aa/ 1523 fooapp.po 1524 fooapp/ 1525 fooapp.js 1526 ... 1527 bb/ 1528 fooapp.po 1529 ... 1530 ~~~ 1531 1532 1533 The installation location for scripting modules is like that for catalogs, 1534 only using `LC_SCRIPTS/` directory instead of `LC_MESSAGES/`: 1535 1536 ~~~ 1537 $PREFIX/ 1538 share/ 1539 locales/ 1540 aa/ 1541 LC_SCRIPTS/ 1542 fooapp/ 1543 fooapp.js 1544 ... 1545 ~~~ 1546 1547 1548 When a translator inquires about adding a scripting module, 1549 or sends one in, the maintainer should check with the translator 1550 if perhaps the functions provided by the module are more widely 1551 applicable. If that is the case, they should rather become part of 1552 Ki18n's own scripting module, because then they will be accessible 1553 to all Ki18n-based translations in the given language. 1554 1555 <a name="handle_update"> 1556 1557 ### Updating Catalogs 1558 1559 When new catalog template is extracted after some development 1560 has been done, existing translation should be updated against it. 1561 This is called *merging* with template, and it is performed 1562 by Gettext's `msgmerge` command. 1563 There are some merging options that can be examined here, 1564 but generally the best invocation of `msgmerge` is this: 1565 1566 ~~~ 1567 msgmerge --update --backup=none --previous aa.po fooapp.pot 1568 ~~~ 1569 1570 Options `--update --backup=none` mean to update the catalog 1571 in place, and not to make a backup file. Option `--previous` 1572 puts some additional information into every modified message, 1573 that translation editing tools can use to show to the translator 1574 all changes in the text. 1575 This command should be run once for every existing translation catalog. 1576 1577 One thing to keep in mind is that a change in the context string 1578 of a message in the code (i.e. the first argument to `*i18nc*` calls), 1579 including adding or removing one, will also register as 1580 a modified message in the merged catalog. 1581 This will require that translators revisit it, which is exactly as 1582 intended: if the context has changed, especially if it was added, 1583 some changes in translation may be needed. 1584 However, this means that when a "message freeze" is declared so that 1585 translators can complete updating translations without disruption, 1586 contexts fall under same rules as text. 1587 1588 There are a few possibilities for who and when should perform merging. 1589 For example, the maintainer can write a script that at the same time 1590 extracts the template and merges all catalogs, and run it periodically, 1591 committing updated catalogs to the repository for translators to pick up. 1592 This could even be integrated into the build system. 1593 Some maintainers do not like committing automatic changes, 1594 and instead expect translators to run the extraction-merging script 1595 for the language they maintain, update the translation, 1596 and commit only that updated catalog. This solution is cleaner with 1597 respect to repository history, but it may burden translators. 1598 1599 When operating in an official KDE repository, maintainers do not 1600 have to deal with merging at all. The server-side automation which 1601 automatically extracts templates and provides them to translators, 1602 also performs merging. So the maintainer is left only to pick up 1603 whatever are the latest catalogs when making a tarball. 1604 1605 1606 <a name="kuit_markup"> 1607 1608 ## Semantic Markup 1609 1610 When composing user-interface text, some programmers ponder about 1611 the typographical conventions to use in certain contexts. 1612 For example, when a file name is inserted into the text, 1613 some typographical solutions that can be used are: 1614 1615 ~~~ 1616 i18n("Cannot open %1 for reading.", filePath); 1617 i18n("Cannot open '%1' for reading.", filePath); 1618 i18n("Cannot open \"%1\" for reading.", filePath); 1619 ~~~ 1620 1621 For the Qt widgets that have rich text capability, 1622 exposed as subset of HTML tags, additional solutions include: 1623 1624 ~~~ 1625 i18n("Cannot open <b>%1</b> for reading.", filePath); 1626 i18n("Cannot open <i>%1</i> for reading.", filePath); 1627 i18n("Cannot open <tt>%1</tt> for reading.", filePath); 1628 ~~~ 1629 1630 The problem here is not so much to decide on one solution, as it is 1631 to follow it consistently through time and between contributors. 1632 One may also want to use two solutions, one in places where only 1633 plain text is allowed, and another where rich text is available. 1634 Wouldn't it then be easier to write everywhere: 1635 1636 ~~~ 1637 xi18n("Cannot open <filename>%1</filename> for reading.", filePath); 1638 ~~~ 1639 1640 and have it automatically resolve into plain or rich text according to 1641 the UI context, using formatting patterns defined at one place? 1642 This approach is called *semantic* markup, because the author 1643 marks parts of the text according to what they *represent*. 1644 1645 Ki18n implements such a semantic markup, 1646 called KUIT (KDE User Interface Text). 1647 It is accessed through the series of `xi18n*` and `kxi18n*` calls, 1648 which are the KUIT-aware counterparts of `i18n*` and `ki18n*` calls. 1649 Ordinary and KUIT-aware calls can be freely mixed within 1650 a given body of code. 1651 1652 KUIT defines a number of semantic tags that are frequently of use, 1653 as listed in the section \ref kuit_tags. 1654 But, KUIT also allows the programmer to define custom tags, 1655 as well as to change visual formatting patterns for predefined tags. 1656 This capability should lessen one important issue of semantic markups: 1657 when the author is forced to choose between several tags 1658 none of which exactly fits the desired meaning; 1659 with KUIT, the author can simply define a custom tag in that case. 1660 1661 <a name="kuit_def_tags"> 1662 1663 ### Defining Tags 1664 1665 Tags are defined and redefined per translation domain, so that changes 1666 will not affect markup resolution in any other domain. 1667 Changes are performed through the `KuitSetup` object associated 1668 with the domain, as returned by the `Kuit::setupForDomain` method. 1669 A tag is defined (or redefined) by defining (or redefining) 1670 its formatting patterns, with one call to `KuitSetup::setTagPattern` 1671 for each desired combination of tag name, attribute names, 1672 and visual format. 1673 Here is an example of defining the tag `<player>`, 1674 which has an optional attribute `color=`, 1675 on the domain `foogame`: 1676 1677 ~~~ 1678 KuitSetup *ks = Kuit::setupForDomain("foogame"); 1679 QString tagName; 1680 QStringList attribNames; 1681 1682 tagName = "player"; 1683 attribNames.clear() 1684 ks->setTagPattern(tagName, attribNames, Kuit::PlainText, 1685 ki18nc("tag-format-pattern <player> plain", 1686 "'%1'")); 1687 ks->setTagPattern(tagName, attribNames, Kuit::RichText, 1688 ki18nc("tag-format-pattern <player> rich", 1689 "<b>%1</b>")); 1690 attribNames.append("color"); 1691 ks->setTagPattern(tagName, attribNames, Kuit::RichText, 1692 ki18nc("tag-format-pattern <player color= > rich", 1693 "<font color='%2'><b>%1</b></font>")); 1694 ~~~ 1695 1696 The first two `setTagPattern` calls set up resolution of 1697 `<player>` without attributes, into plain and rich text. 1698 The third call sets up resolution for `<player color="...">`, 1699 but only into rich text; since a plain text pattern is not defined 1700 for this tag-attribute combination, it will fall back to basic 1701 `<player>` plain text pattern. 1702 A fallback is always defined, the elementary fallback being a no-op, 1703 where tag is simply removed. 1704 Formatting patterns must be wrapped for translation too, 1705 since translators may need to tweak them; 1706 *ordinary* (not markup-aware) `ki18nc` calls must be used here, 1707 since patterns themselves are not KUIT markup. 1708 The `%1` placeholder in the pattern will be replaced by 1709 the text wrapped with the tag, and `%2` and upwards with 1710 attribute values, in the order of appearance in attribute names list. 1711 1712 If a simple substitution pattern is insufficient for formatting, 1713 additionally a formatting function of type `Kuit::TagFormatter` 1714 can be given. The result of this function is substituted into the pattern; 1715 alternatively an empty pattern can be given (as `KLocalizedString()`), 1716 in which case the result is used directly, no substitution is performed. 1717 The formatting function also receives the current element path, 1718 so that the resolution can depend on the markup tree context if needed. 1719 Anything in the function that may need translator input 1720 should be appropriately exposed through `i18nc*` or `ki18nc*` calls. 1721 1722 In the section \ref kuit_tags it is stated that every KUIT tag 1723 is classified either as a phrase tag or as a structuring tag, 1724 and explained what that means for processing. 1725 A newly defined tag is by default a phrase tag; 1726 method `KuitSetup::setTagClass` can be used to change its class: 1727 1728 ~~~ 1729 tagName = "list2"; 1730 ks->setTagPattern(tagName, ...); 1731 ks->setTagClass(tagName, Kuit::StructTag); 1732 ~~~ 1733 1734 1735 In a library, changes to the KUIT setup may need to be private, 1736 applicable only in library's own domain, but they may also need 1737 to be public, applicable in clients' domains. 1738 For changes that should be public, the library should define 1739 a public function which takes the domain as the argument 1740 and performs all the changes on that domain: 1741 1742 ~~~ 1743 void updateKuitSetup (const char *domain) 1744 { 1745 KuitSetup *ks = Kuit::setupForDomain(domain); 1746 .... 1747 } 1748 ~~~ 1749 1750 The client code should then call this function in its initialization. 1751 1752 <a name="kuit_sel_fmt"> 1753 1754 ### Selecting Visual Format 1755 1756 The target visual format for any given `xi18n` call can be selected 1757 in two ways. 1758 1759 The primary way is by UI markers in the message context, 1760 which were described in the section \ref uimark_ctxt. 1761 Every `@<major>:<minor>` marker combination has 1762 a default target visual format assigned, as follows: 1763 <table> 1764 <tr><th>UI Marker</th> 1765 <th>Visual Format</th></tr> 1766 <tr><td>(none)</td> 1767 <td>plain</td></tr> 1768 <tr><td>\@action:\<any\></td> 1769 <td>plain</td></tr> 1770 <tr><td>\@title:\<any\></td> 1771 <td>plain</td></tr> 1772 <tr><td>\@option:\<any\></td> 1773 <td>plain</td></tr> 1774 <tr><td>\@label:\<any\></td> 1775 <td>plain</td></tr> 1776 <tr><td>\@item:\<any\></td> 1777 <td>plain</td></tr> 1778 <tr><td>\@info, \@info:tooltip, \@info:whatsthis, \@info:usagetip</td> 1779 <td>rich</td></tr> 1780 <tr><td>\@info:status, \@info:progress, \@info:credit</td> 1781 <td>plain</td></tr> 1782 <tr><td>\@info:shell</td> 1783 <td>term</td></tr> 1784 </tr> 1785 </table> 1786 Target visual formats associated with UI markers can be changed using 1787 the `KUITSetup::setFormatForMarker` method: 1788 1789 ~~~ 1790 KuitSetup *ks = Kuit::setupForDomain("fooapp"); 1791 // Set standalone @info (no minor component) to plain text: 1792 ks->setFormatForMarker("@info", Kuit::PlainText); 1793 // Set @info:tooltip to rich text: 1794 ks->setFormatForMarker("@info:tooltip", Kuit::RichText); 1795 // Set all @info:<minor> to plain text: 1796 ks->setFormatForMarker("@info:", Kuit::PlainText); 1797 ~~~ 1798 1799 1800 The second way to select the visual format is by using a `kxi18n*` call, 1801 and passing the format type to the `toString` method: 1802 1803 ~~~ 1804 kxi18nc("@info", "Logging paused.").toString(Kuit::PlainText); 1805 ~~~ 1806 1807 This will override any format implied by the UI marker if present. 1808 1809 If a library is making modifications in visual format association 1810 with UI markers, and these changes should be available to clients, 1811 the same approach as in the section \ref kuit_def_tags should be used. 1812 1813 <a name="kuit_escape"> 1814 1815 ### Escaping 1816 1817 While for `*i18n*` calls it was advised to keep each message text 1818 well-formed by itself with respect to Qt rich text markup, 1819 for `*xi18n*` calls well-formedness is mandatory. 1820 This means that markup-significant characters in plain-looking text 1821 need to be escaped, using standard XML entities: 1822 1823 ~~~ 1824 xi18n("Installed Fooapp too old, need release >= 2.1.8."); 1825 xi18n("Set <themeId> as theme on startup"); 1826 ~~~ 1827 1828 The exception is the ampersand (&) character, which in XML denotes 1829 the start of an entity, but in Qt denotes the accelerator marker. 1830 Therefore it is necessary to escape ampersand as `&` 1831 only when it is in position which would result in valid entity syntax: 1832 1833 ~~~ 1834 // Escaping not needed because not in entity-like position: 1835 xi18n("Remove &all entries"); 1836 // Escaping not needed for the same reason wrt. markup, 1837 // but ampersand doubled to escape it wrt. Qt accelerator marker: 1838 xi18n("Look && Feel"); 1839 // Escaping wrt. markup necessary: 1840 xi18n("Delete &everything; see if I care!"); 1841 ~~~ 1842 1843 The example for necessary escaping above is rather artificial, 1844 because in practice it is unlikely for ampersand to appear 1845 in entity-like position while not actually starting an entity. 1846 1847 To assure the validity of markup when arguments are inserted into 1848 `xi18n`-wrapped text, all markup-significant characters 1849 in string arguments are automatically escaped. 1850 For example, this works as expected: 1851 1852 ~~~ 1853 QString filePath("assignment03-<yourname>.txt"); 1854 QString msg1 = kxi18n("Delete <filename>%1</filename>?", filePath) 1855 .toString(Kuit::PlainText); 1856 // msg1 == "Delete 'assignment03-<yourname>.txt'?" 1857 QString msg2 = kxi18n("Delete <filename>%1</filename>?", filePath) 1858 .toString(Kuit::RichText); 1859 // msg2 == "Delete `assignment03-<yourname>.txt`?" 1860 ~~~ 1861 1862 But, how then to compose a text where the arguments too should 1863 contain some KUIT markup? This is done by using non-finalization 1864 `kxi18n*` call to translate the argument text, and passing 1865 the returned `KLocalizedString` object directly as argument: 1866 1867 ~~~ 1868 KLocalizedString stateDesc = kxi18n( 1869 "On <emphasis>indefinite</emphasis> hold."); 1870 QString msg = xi18nc("@info", 1871 "<para>Task state:</para>" 1872 "<para>%1</para>", stateDesc); 1873 // msg == "<p>Task state:</p>" 1874 // "<p>On <i>indefinite</i> hold.</p>" 1875 ~~~ 1876 1877 If the argument and the text have different visual formats implied by 1878 their UI markers, the outermost format overrides inner formats. 1879 1880 <a name="kuit_tags"> 1881 1882 ### Predefined Tags 1883 1884 All KUIT tags belong to one of the two classes: 1885 - phrase tags, which describe parts of sentences or whole sentences 1886 inserted into running text; 1887 - structuring tags, which split text into paragraph-level blocks. 1888 1889 A text without any structuring tags is considered equivalent of 1890 one paragraph or sub-paragraph sentence or phrase. 1891 If at least one structuring tag appears in the text, 1892 then the text is considered multi-paragraph, 1893 and no content may appear outside of structuring tags. 1894 For example: 1895 1896 ~~~ 1897 // Good: 1898 i18nc("@info", 1899 "You can configure the history sidebar here."); 1900 // BAD: 1901 xi18nc("@info", 1902 "<title>History Sidebar</title>" 1903 "You can configure the history sidebar here."); 1904 // Good: 1905 xi18nc("@info", 1906 "<title>History Sidebar</title>" 1907 "<para>You can configure the history sidebar here.</para>"); 1908 ~~~ 1909 1910 1911 The current set of predefined tags is presented below. 1912 For each tag the following information is stated: 1913 the tag name (in superscript: Ki18n release of first appearance), 1914 available attributes (in superscript: \em * if mandatory, 1915 Ki18n release of first appearance), 1916 admissible subtags, and description. 1917 1918 <table> 1919 <tr><th> 1920 Phrase Tags 1921 </th></tr> 1922 <tr><td> 1923 <b>\<application\></b><sup>5.0</sup><br/> 1924 Name of an application. 1925 1926 ~~~ 1927 xi18nc("@action:inmenu", 1928 "Open with <application>%1</application>", appName); 1929 ~~~ 1930 1931 </td></tr> 1932 <tr><td> 1933 <b>\<bcode\></b><sup>5.0</sup><br/> 1934 Line-breaking body of code, for short code or output listings. 1935 1936 ~~~ 1937 xi18nc("@info:whatsthis", 1938 "You can try the following snippet:<bcode>" 1939 "\\begin{equation}\n" 1940 " C_{x_i} = \\frac{C_z^2}{e \\pi \\lambda}\n" 1941 "\\end{equation}\n" 1942 "</bcode>"); 1943 ~~~ 1944 1945 </td></tr> 1946 <tr><td> 1947 <b>\<command\></b><sup>5.0</sup><br/> 1948 <i>Attributes:</i> section=<sup>5.0</sup><br/> 1949 Name of a shell command, system call, signal, etc. 1950 Its man section can be given with the `section=` attribute. 1951 1952 ~~~ 1953 xi18nc("@info", 1954 "This will call <command>%1</command> internally.", cmdName); 1955 xi18nc("@info", 1956 "Consult the man entry of " 1957 "<command section='1'>%1</command>", cmdName); 1958 ~~~ 1959 1960 </td></tr> 1961 <tr><td> 1962 <b>\<email\></b><sup>5.0</sup><br/> 1963 <i>Attributes:</i> address=<sup>5.0</sup><br/> 1964 Email address. 1965 Without attributes, the tag text is the address. 1966 If the address is explicitly given with the `address=` attribute, 1967 the tag text is the name or description attached to the address. 1968 In rich text, the phrase will be hyperlinked. 1969 1970 ~~~ 1971 xi18nc("@info", 1972 "Send bug reports to <email>%1</email>.", emailNull); 1973 xi18nc("@info", 1974 "Send praises to <email address='%1'>the author</email>.", emailMy); 1975 ~~~ 1976 1977 </td></tr> 1978 <tr><td> 1979 <b>\<emphasis\></b><sup>5.0</sup><br/> 1980 <i>Attributes:</i> strong=<sup>5.0</sup><br/> 1981 Emphasized word or phrase in the text. 1982 For strong emphasis, attribute `strong=` 1983 can be set to `[1|true|yes]`. 1984 </td></tr> 1985 <tr><td> 1986 <b>\<envar\></b><sup>5.0</sup><br/> 1987 Environment variable. 1988 A `$`-sign will be prepended automatically in formatted text. 1989 1990 ~~~ 1991 xi18nc("@info", 1992 "Assure that <envar>PATH</envar> is properly set."); 1993 ~~~ 1994 1995 </td></tr> 1996 <tr><td> 1997 <b>\<filename\></b><sup>5.0</sup><br/> 1998 <i>Subtags:</i> \<envar\>, \<placeholder\><br/> 1999 File or folder name or path. 2000 Slash (/) should be used as path separator, and it will be converted 2001 into native separator for the underlying platform. 2002 2003 ~~~ 2004 xi18nc("@info", "Cannot read <filename>%1</filename>.", filePath); 2005 xi18nc("@info", 2006 "<filename><envar>HOME</envar>/.foorc</filename> " 2007 "does not exist."); 2008 ~~~ 2009 </td></tr> 2010 <tr><td> 2011 <b>\<icode\></b><sup>5.0</sup><br/> 2012 <i>Subtags:</i> \<envar\>, \<placeholder\><br/> 2013 Inline code, like a shell command line. 2014 2015 ~~~ 2016 xi18nc("@info:tooltip", 2017 "Execute <icode>svn merge</icode> on selected revisions."); 2018 ~~~ 2019 2020 </td></tr> 2021 <tr><td> 2022 <b>\<interface\></b><sup>5.0</sup><br/> 2023 Path to a graphical user interface element. 2024 If a path of UI elements is needed, 2025 elements should be separated with `|` or `->`, 2026 which will be converted into the canonical separator. 2027 2028 ~~~ 2029 xi18nc("@info:whatsthis", 2030 "If you make a mistake, click " 2031 "<interface>Reset</interface> to start again."); 2032 xi18nc("@info:whatsthis", 2033 "The line colors can be changed under " 2034 "<interface>Settings->Visuals</interface>."); 2035 ~~~ 2036 2037 </td></tr> 2038 <tr><td> 2039 <b>\<link\></b><sup>5.0</sup><br/> 2040 <i>Attributes:</i> url=<sup>5.0</sup><br/> 2041 Link to a URL-addressable resource. 2042 Without attributes, the tag text is the URL; 2043 alternatively, the URL can be given by `url=` attribute, 2044 and then the text serves as description. 2045 Separate URL and description are preferred if applicable. 2046 The phrase will be hyperlinked in rich text. 2047 2048 ~~~ 2049 xi18nc("@info:tooltip", 2050 "Go to <link>%1</link> website.", urlKDE); 2051 xi18nc("@info:tooltip", 2052 "Go to the <link url='%1'>KDE website</link>.", urlKDE); 2053 ~~~ 2054 2055 </td></tr> 2056 <tr><td> 2057 <b>\<message\></b><sup>5.0</sup><br/> 2058 <i>Subtags:</i> all phrase tags<br/> 2059 An external message inserted into the text. 2060 2061 ~~~ 2062 xi18nc("@info", 2063 "The fortune cookie says: <message>%1</message>", cookieText); 2064 ~~~ 2065 2066 </td></tr> 2067 <tr><td> 2068 <b>\<nl\></b><sup>5.0</sup><br/> 2069 Line break. 2070 2071 ~~~ 2072 xi18nc("@info", 2073 "The server replied:<nl/>" 2074 "<message>%1</message>", serverReply); 2075 ~~~ 2076 2077 </td></tr> 2078 <tr><td> 2079 <b>\<note\></b><sup>5.0</sup><br/> 2080 <i>Attributes:</i> label=<sup>5.0</sup><br/> 2081 <i>Subtags:</i> all phrase tags<br/> 2082 The sentence is a side note related to the topic. 2083 Prefix "Note:" will be added automatically; 2084 another prefix can be set with attribute `label=`. 2085 2086 ~~~ 2087 xi18nc("@info", 2088 "Probably the best known of all duck species is the Mallard. " 2089 "It breeds throughout the temperate areas around the world. " 2090 "<note>Most domestic ducks are derived from Mallard.</note>"); 2091 ~~~ 2092 2093 </tr></td> 2094 <tr><td> 2095 <b>\<placeholder\></b><sup>5.0</sup><br/> 2096 A placeholder text. 2097 It could be something which the user should replace with actual text, 2098 or a generic item in a list. 2099 2100 ~~~ 2101 xi18nc("@info", 2102 "Replace <placeholder>name</placeholder> with your name."); 2103 xi18nc("@item:inlistbox", 2104 "<placeholder>All images</placeholder>"); 2105 ~~~ 2106 2107 </td></tr> 2108 <tr><td> 2109 <b>\<shortcut\></b><sup>5.0</sup><br/> 2110 Combination of keyboard keys to press. 2111 Key names should be separated by "+" or "-", 2112 and the shortcut will be converted into canonical form. 2113 2114 ~~~ 2115 xi18nc("@info:whatsthis", 2116 "Cycle through layouts using <shortcut>Alt+Space</shortcut>."); 2117 ~~~ 2118 2119 </td></tr> 2120 <tr><td> 2121 <b>\<warning\></b><sup>5.0</sup><br/> 2122 <i>Attributes:</i> label=<sup>5.0</sup><br/> 2123 <i>Subtags:</i> all phrase tags<br/> 2124 The sentence is a warning. 2125 Prefix "Warning:" will be added automatically; 2126 another prefix can be set with attribute `label=`. 2127 2128 ~~~ 2129 xi18nc("@info", 2130 "Really delete this key? " 2131 "<warning>This cannot be undone.</warning>"); 2132 ~~~ 2133 2134 </tr></td> 2135 <tr><th> 2136 Structuring Tags 2137 </th></tr> 2138 <tr><td> 2139 <b>\<item\></b><sup>5.0</sup><br/> 2140 <i>Subtags:</i> all phrase tags<br/> 2141 A list item. 2142 </tr></td> 2143 <tr><td> 2144 <b>\<list\></b><sup>5.0</sup><br/> 2145 <i>Subtags:</i> \<item\><br/> 2146 List of items. 2147 List is considered an element of the paragraph, 2148 so `<list>` tags must be inside `<para>` tags. 2149 </tr></td> 2150 <tr><td> 2151 <b>\<para\></b><sup>5.0</sup><br/> 2152 <i>Subtags:</i> all phrase tags, \<list\><br/> 2153 One paragraph of text. 2154 </tr></td> 2155 <tr><td> 2156 <b>\<subtitle\></b><sup>5.0</sup><br/> 2157 <i>Subtags:</i> all phrase tags<br/> 2158 The subtitle of the text. Must come after `<title>`. 2159 </tr></td> 2160 <tr><td> 2161 <b>\<title\></b><sup>5.0</sup><br/> 2162 <i>Subtags:</i> all phrase tags<br/> 2163 The title of the text. 2164 Must be the first tag in the text if present. 2165 </tr></td> 2166 </table> 2167 2168 The criteria for adding new tags to the predefined set, 2169 particularly new phrase tags, are not very strict. 2170 If the tag is clearly useful to a class of applications, 2171 of which more than one are known to use Ki18n, 2172 it is reasonable to add it here. 2173 Adding synonymous tag names is also fine, where one finds that 2174 the original name is not sufficiently discoverable, 2175 or that it is too verbose for the given frequency of use. 2176 2177 <a name="kuit_ents"> 2178 2179 ### Predefined Entities 2180 2181 KUIT defines a fixed set of XML entities, which means that unlike tags, 2182 entities cannot be added to, nor their character expansions changed. 2183 The standard XML entities are: 2184 <table> 2185 <tr><th>Entity</th><th>Expansion</th></tr> 2186 <tr><td><b>\<</b></td><td>less-than (`<`)</td></tr> 2187 <tr><td><b>\></b></td><td>greater-than (`>`)</td></tr> 2188 <tr><td><b>\&</b></td><td>ampersand (`&`)</td></tr> 2189 <tr><td><b>\'</b></td><td>single quote (`'`)</td></tr> 2190 <tr><td><b>\"</b></td><td>double quote (`"`)</td></tr> 2191 </table> 2192 The `&apos;` and `&quot;` are really needed only 2193 within attribute values (and even there they can be avoided 2194 by choosing the opposite quote sign for quoting the attribute value). 2195 2196 Additional entities are (Ki18n release where they were introduced 2197 given in superscript): 2198 <table> 2199 <tr><th>Entity</th><th>Expansion</th></tr> 2200 <tr> 2201 <td><b>\ </b><sup>5.0</sup></td> 2202 <td></td>non-breaking space (` `) 2203 </tr> 2204 </table> 2205 2206 The reason for not allowing custom entities 2207 can be demonstrated by the following example. 2208 An application programmer may think of defining the entity 2209 `&appname;`, which would be used everywhere in text in place of 2210 the actual application name. In that way, seemingly, it would be easy 2211 to play with various names or spellings without disrupting translations. 2212 The problem, however, is that in many languages the structure of 2213 the sentence depends on the grammar properties of the particular name 2214 (e.g. its grammar gender or number), and conversely, the name may 2215 need modification according to sentence structure (e.g. by grammar case). 2216 Thus, custom entities are not allowed because 2217 they are misused too easily. 2218 If something *really* needs to be inserted verbatim into text, 2219 argument substitution is always at hand. 2220 2221 2222 <a name="non_text"> 2223 2224 ## Localizing Non-Text Resources 2225 2226 It sometimes happens that a non-textual application resource 2227 needs localization. The most frequent example are images 2228 that contain some text, like splash screens. 2229 Ki18n also provides a rudimentary facility for this situation, 2230 the `KLocalizedString::localizedFilePath` static method. 2231 When called with a resource file path as the argument, 2232 this method will check what are the active languages, 2233 and look if there exists a localized version of the resource at path 2234 `<original-parent-dir>/l10n/<language>/<original-basename>`. 2235 For example, if the active language is `aa`, and a candidate image 2236 for localization is installed as: 2237 2238 ~~~ 2239 $PREFIX/share/fooapp/splash.png 2240 ~~~ 2241 2242 then a call to 2243 2244 ~~~ 2245 QString splashPath = QStandardPaths::locate( 2246 QStandardPaths::GenericDataLocation, "splash.png"); 2247 splashPath = KLocalizedString::localizedFilePath(splashPath); 2248 ~~~ 2249 2250 will check if there exist the file 2251 2252 ~~~ 2253 $PREFIX/share/fooapp/l10n/aa/splash.png 2254 ~~~ 2255 2256 and return that path if it does, or else the original path. 2257 2258 Some KDE libraries will call `KLocalizedString::localizedFilePath` 2259 on their own behind the scene, for resources that may need localization 2260 but whose paths are not directly manipulated in application sources. 2261 An example here are icons handled through `KIcon` class, 2262 which are referred to in the code only by the icon name. 2263 2264 2265 <a name="refs"> 2266 2267 ## Further References 2268 2269 For details about the format of translation catalogs (PO) 2270 and various Gettext tools, the first stop is the 2271 <a href="http://www.gnu.org/software/gettext/manual/gettext.html"> 2272 Gettext manual</a>. 2273 2274 <a href="http://techbase.kde.org/">KDE Techbase</a> contains a 2275 <a href="http://techbase.kde.org/Development/Tutorials/Localization"> 2276 series of tutorials</a> on preparing the KDE code for localization, 2277 and on the internationalization process in general. 2278