1Programmer's Guide {#prg_guide} 2================== 3 4- [Introduction](#intro) 5- [Writing Messages](#write_i18n) 6 - [General Messages](#gen_usage) 7 - [Specialized Messages](#spec_usage) 8 - [Placeholder Substitution](#subs_notes) 9 - [Writing Good Texts](#good_text) 10 - [Writing Good Contexts](#good_ctxt) 11 - [Extraction-Only Macros](#i18n_noop) 12 - [Messages before creation of Q*Application instance](#before_qapp) 13- [Connecting Calls to Catalogs](#link_cat) 14 - [Connecting to Catalogs in Application Code](#link_prog) 15 - [Connecting to Catalogs in Library Code](#link_lib) 16 - [Connecting to Catalogs in Non-Code Files](#link_noncode) 17- [Handling Catalog Files](#handle_cat) 18 - [Extracting Templates](#handle_extract) 19 - [Placing and Installing Catalogs](#handle_install) 20 - [Updating Catalogs](#handle_update) 21- [Semantic Markup](#kuit_markup) 22 - [Defining Tags](#kuit_def_tags) 23 - [Selecting Visual Format](#kuit_sel_fmt) 24 - [Escaping](#kuit_escape) 25 - [Predefined Tags](#kuit_tags) 26 - [Predefined Entities](#kuit_ents) 27- [Localizing Non-Text Resources](#non_text) 28- [Further References](#refs) 29 30<a name="intro"> 31 32## Introduction 33 34*Internationalization* (i18n) is the process of preparing 35the source code such that the running program can receive and 36output user-visible information in various human languages, or, 37more precisely, *locales*. This is because the same language may 38be spoken at several places which differ in other details of relevance 39to the software internationalization (e.g. dialect, calendar, etc). 40I18n is performed by the programmer. 41*Localization* (l10n) is the process of adapting relevant 42program resources for a particular locale. 43L10n is performed by the translator, who is usually a native of the locale. 44 45User interface text is the most prominent resource needing l10n. 46In the source code, there are two general approaches 47to writing i18n'd user-visible strings, hereafter called *messages*. 48In the first approach, the programmer writes symbolic identifier in place 49of actual message text, and then for each language there is a file, 50called translation *catalog*, which contains the actual text linked 51to the appropriate identifier. 52For example, in the code: 53 54~~~ 55QString msg = getId("out_of_disk_space"); 56~~~ 57 58and in the translation catalog: 59 60~~~ 61out_of_disk_space "There is no space left on the disk." 62~~~ 63 64In the second approach, the programmer writes actual text inside 65the source code, in an agreed upon human language, 66which is usually American English. Then there is a translation catalog 67for every *other* language, in which English and translated text of 68the message are linked. For example, in the code: 69 70~~~ 71QString msg = i18n("There is no space left on the disk."); 72~~~ 73 74and in the translation catalog: 75 76~~~ 77msgid "There is no space left on the disk." 78msgstr "Nema više prostora na disku." 79~~~ 80 81One may observe that the second approach is technically a generalization 82of the first approach. However, in actual use there are non-negligible 83differences in the i18n/l10n workflow between these approaches, 84and therefore they are treated as qualitatively different. 85 86Both approaches -- the symbolic-identifier and the actual-text -- have 87some advantages and disadvantages over each other. That is why today 88both are in use, in software i18n in general. Within free software, 89though, the actual-text approach is considerably more widespread, 90as embodied in the GNU Gettext i18n system. Whether this is a historical 91accident, or due to sensibilities of people writing free software, 92is left to the interested reader to research. 93 94The KDE Ki18n library, being built atop Gettext, provides 95the actual-text approach. In the following it is described 96how to use Ki18n, from the viewpoint of programmers and maintainers. 97Basic instructions are split into three parts: 98 99\li The first part deals with how to write i18n messages in the code. 100 This is the largest and the most important part, since there are 101 many nuances to preparing quality messages for translation. 102 Section: \ref write_i18n. 103 104\li The second part describes how to connect particular translation calls 105 with particular translation catalogs, so that the system can know 106 in which catalogs to search for translations. 107 In particular, there are some differences here depending on whether 108 the piece of code is an application or a library. 109 Section: \ref link_cat. 110 111\li The third part explains how to *extract* messages from the code, 112 in order to create the translation *template*. 113 The template is simply a clean translation catalog (having only English 114 part of each message), which the translator copies over and fills in 115 the translations for a particular language. 116 Then it is shown how and where to install translation catalogs, 117 and how to update existing translation catalogs to newly extracted 118 templates (after some new development has been done, causing 119 new messages to appear, some to be removed, and some modified). 120 Unlike in the GNU Gettext manual, here there are no dependencies or 121 references to a particular software build system; 122 this is left to the maintainer to choose. 123 Section: \ref handle_cat. 124 125There are also two special topics: 126 127\li Some programmers like to have more structure and consistency 128 in message texts, and for them Ki18n provides 129 a customizable semantic markup. 130 Section: \ref kuit_markup. 131 132\li Sometimes there are program resources other than text 133 that require localization. 134 Ki18n provides a generic, though rudimentary solution for such cases. 135 Section: \ref non_text. 136 137 138<a name="write_i18n"> 139 140## Writing Messages 141 142Most messages can be internationalized with simple `i18n*` calls, 143which are described in the section \ref gen_usage. 144A few messages may require treatment with `ki18n*` calls, 145and when this is needed is described in the section \ref spec_usage. 146Argument substitution in messages is performed using the familiar 147Qt syntax `%<number>`, but there may be some differences; 148the section \ref subs_notes gives some notes about placeholders. 149Finally, guidelines for writing good messages are given 150in sections \ref good_text and \ref good_ctxt. 151 152<a name="gen_usage"> 153 154### General Messages 155 156General messages are wrapped with `i18n*` calls. 157These calls are *immediate*, which means that they return 158the final localized text (including substituted arguments) 159as a `QString` object, that can be passed to UI widgets. 160 161The most frequent message type, a simple text without any arguments, 162is handled like this: 163 164~~~ 165QString msg = i18n("Just plain info."); 166~~~ 167 168The message text may contain arbitrary Unicode characters, 169and the source file *must* be UTF-8 encoded. 170Ki18n supports no other character encoding. 171 172If there are some arguments to be substituted into the message, 173`%<number>` placeholders are put into the text at desired positions, 174and arguments are listed after the string: 175 176~~~ 177QString msg = i18n("%1 has scored %2", playerName, score); 178~~~ 179 180Arguments can be of any type for which there exists an overloaded 181`KLocalizedString::subs` method. 182Up to 9 arguments can be inserted in this fashion, due to the fact that 183`i18n` calls are realized as overloaded templates. 184If more than 9 arguments are needed, which is extremely rare, 185a `ki18n*` call (described later) must be used. 186 187Sometimes a short message in English is ambiguous to translators, 188possibly leading to a wrong translations. 189Ambiguity can be resolved by providing a context string along the text, 190using the `i18nc` call. In it, the first argument is the context, 191which only the translator will see, and the second argument is the text 192which the user will see: 193 194~~~ 195QString msg = i18nc("player name - score", "%1 - %2", playerName, score); 196~~~ 197 198Section \ref good_ctxt gives a few pointers on when contexts are needed, 199and what they should contain. 200 201In messages stating how many of some kind of objects there are, 202where the number of objects is inserted at run time, it is necessary 203to differentiate between *plural forms* of the text. 204In English there are only two forms, one for number 1 (singular) and 205another form for any other number (plural). 206In other languages this might be more complicated (more than two forms), 207or it might be simpler (same form for all numbers). 208This is handled properly by using the `i18np` plural call: 209 210~~~ 211QString msg = i18np("%1 image in album %2", "%1 images in album %2", 212 numImages, albumName); 213~~~ 214 215The plural form is decided by the first integer-valued argument, 216which is `numImages` in this example. In rare cases when there are 217two or more integer arguments, they should be ordered carefully. 218 219In QML code, due to some limitations, always the first argument 220will be treated as plural-deciding, so it should be an appropriate 221number (integer or a round double); otherwise, behavior is undefined. 222 223It is also allowed to omit the plural-deciding placeholder, for example: 224 225~~~ 226QString msg = i18np("One image in album %2", "%1 images in album %2", 227 numImages, albumName); 228~~~ 229 230or even: 231 232~~~ 233QString msg = i18np("One image in album %2", "More images in album %2", 234 numImages, albumName); 235~~~ 236 237If the code context is such that the number is always greater than 1, 238the plural call must be used nevertheless. 239This is because in some languages there are different plural forms 240for different classes of numbers; in particular, the singular form 241may be used for numbers other than 1 (e.g. those ending in 1). 242 243If a message needs both context and plural forms, this is provided by 244`i18ncp` call: 245 246~~~ 247QString msg = i18ncp("file on a person", "1 file", "%1 files", numFiles); 248~~~ 249 250 251In the basic `i18n` call (no context, no plural) it is not allowed 252to put a literal string as the first argument for substitution. 253In debug mode this will even trigger a static assertion, 254resulting in compilation error. This serves to prevent misnamed calls: 255context or plural frequently needs to be added at a later point to 256a basic call, and at that moment the programmer may forget to update 257the call name from `i18n` to `i18nc/p`. 258 259Furthermore, an empty string should never be wrapped with 260a basic `i18n` call (no `i18n("")`), 261because in translation catalog the message with empty text 262has a special meaning, and is not intended for client use. 263The behavior of `i18n("")` is undefined, 264and there will be some warnings in debug mode. 265 266There is also a complement of `i18nd*` calls 267(`i18nd`, `i18ndc`, `i18ndp`, `i18ndcp`), 268which are not supposed to be used directly, 269but as will be explained in the section \ref link_cat. 270 271<a name="spec_usage"> 272 273### Specialized Messages 274 275There are some situations where `i18n*` calls are not sufficient, 276or are not convenient enough. 277One obvious case is if more than 9 arguments need to be substituted. 278Another case is if it would be easier to substitute arguments later on, 279after the line with the i18n call. 280For cases such as these, `ki18n*` calls can be used. 281These calls are *deferred*, which means that they do not return 282the final translated text as `QString`, but instead return 283a `KLocalizedString` instance which needs further treatment. 284Arguments are then substituted one by one using 285`KLocalizedString::subs` methods, and after all arguments 286have been substituted, the translation is finalized by one of 287`KLocalizedString::toString` methods (which return `QString`). 288For example: 289 290~~~ 291KLocalizedString ks; 292case (reportSource) { 293 SRC_ENG: ks = ki18n("Engineering reports: %1"); break; 294 SRC_HEL: ks = ki18n("Helm reports: %1"); break; 295 SRC_SON: ks = ki18n("Sonar reports: %1"); break; 296 default: ks = ki18n("General report: %1"); 297} 298QString msg = ks.subs(reportText).toString(); 299~~~ 300 301 302`subs` methods do not update the `KLocalizedString` instance on which 303they are invoked, but return a copy of it with one argument slot filled. 304This allows to use `KLocalizedString` instances as a templates 305for constructing final texts, by supplying different arguments. 306 307Another use for deferred calls is when special formatting of arguments 308is needed, like requesting the field width or number of decimals. 309`subs` methods can take these formatting parameters. 310In particular, arguments should not be formatted in a custom way, 311because `subs` methods will also take care of proper localization 312(e.g. use either dot or comma as decimal separator in numbers, etc): 313 314~~~ 315// BAD (number not localized): 316QString msg = i18n("Rounds: %1", myNumberFormat(n, 8)); 317// Good: 318QString msg = ki18n("Rounds: %1").subs(n, 8).toString(); 319~~~ 320 321 322Like with `i18n`, there are context, plural, and context-plural 323variants of `ki18n:` 324 325~~~ 326ki18nc("No function", "None").toString(); 327ki18np("File found", "%1 files found").subs(n).toString(); 328ki18ncp("Personal file", "One file", "%1 files").subs(n).toString(); 329~~~ 330 331 332`toString` methods can be used to override the global locale. 333To override only the language of the locale, `toString` can take 334a list of languages for which to look up translations 335(ordered by decreasing priority): 336 337~~~ 338QStringList myLanguages; 339... 340QString msg = ki18n("Welcome").toString(myLanguages); 341~~~ 342 343The section \ref link_cat describes how to specify 344the translation *domain*, a canonical name for the catalog file 345from which `*i18n*` calls will draw translations. 346But `toString` can always be used to override the domain for a given call, 347by supplying a specific domain: 348 349~~~ 350QString trName = ki18n("Georgia").toString("country-names"); 351~~~ 352 353Relevant here is the set of `ki18nd*` calls 354(`ki18nd`, `ki18ndc`, `ki18ndp`, `ki18ndcp`), 355which can be used for the same purpose, 356but which are not intended to be used directly. 357This will also be covered in the section \ref link_cat. 358 359<a name="dyn_ctxt"> 360 361#### Dynamic Contexts 362 363Translators are provided with the capability to script translations, 364such that the text changes based on arguments supplied at run time. 365For the most part, this feature is transparent to the programmer. 366However, sometimes the programmer may help in this by providing 367a *dynamic* context to the message, through 368`KLocalizedString::inContext` methods. 369Unlike the static context, the dynamic context changes at run time; 370translators have the means to fetch it and use it to script 371the translation properly. An example: 372 373~~~ 374KLocalizedString ks = ki18nc("%1 is user name; may have " 375 "dynamic context gender=[male,female]", 376 "%1 went offline"); 377if (knownUsers.contains(user) && !knownUsers[user].gender.isEmpty()) { 378 ks = ks.inContext("gender", knownUsers[user].gender); 379} 380QString msg = ks.subs(user).toString(); 381~~~ 382 383Any number of dynamic contexts, with different keys, can be added like this. 384Normally every message with a dynamic context should also have 385a static context, like in the previous example, informing the translator 386of the available dynamic context keys and possible values. 387Like `subs` methods, `inContext` does not modify the parent instance, 388but returns a copy of it. 389 390<a name="before_qapp"> 391 392### Messages before creation of Q*Application instance 393 394Fetching the translated messages only works after the Q*Application 395instance has been created. So any code which will be executed before 396and which handles text that should be translated has to delay 397the actual lookup in the catalog (like other locale-dependent actions), 398in one of two ways: 399either by using statically initialized character arrays wrapped in 400`kli18n*` functions for extraction, and later making the 401actual `i18n*` calls (see section \ref i18n_noop); 402or by using `ki18n*` calls to create `KLocalizedString` instances, 403which do not perform immediate catalog lookup, and later fetching 404the actual translation through their toString() methods (see 405section \ref spec_usage); 406 407One reason for this is that Gettext follows the standard C/POSIX locale 408settings. By standard on the start of a program all locale categories are 409fixed to the "C" locale, including the locale for the message catalog 410category (LC_MESSAGES). 411To use instead the locales specified by the environment variables, 412the locale values in the runtime need to be set to an empty string. 413This is usually done in one go for all locale categories by this call: 414~~~ 415setlocale(LC_ALL, ""); 416~~~ 417From this point on the locale specific environment variables 418"LANGUAGE", "LC_*" and "LANG" are considered for deciding which locale 419to use for which category. This includes Gettext when picking the 420message catalog to use. 421 422The constructor of QCoreApplication (and thus its subclasses) does a call 423like that. Which means any `i18n*` calls done _after_ the creation of the 424QCoreApplication instance (or of its subclasses) will use a message catalog 425based on the locale specific environment variables, as one usually expects, 426But any calls _before_ will use a message catalog for the "C" locale. 427 428<a name="subs_notes"> 429 430### Placeholder Substitution 431 432Hopefully, most of the time `%<number>` placeholders are substituted 433in the way one would intuitively expect them to be. 434Nevertheless, some details about substitution are as follows. 435 436Placeholders are substituted in one pass, so there is no need 437to worry about what will happen if one of the substituted arguments 438contains a placeholder, and another argument is substituted after it. 439 440All same-numbered placeholders are substituted with the same argument. 441 442Placeholders directly index arguments: they should be numbered from 1 443upwards, without gaps in the sequence, until each argument is indexed. 444Otherwise, error marks will be inserted into message at run time 445(when the code is compiled in debug mode), and any invalid placeholder 446will be left unsubstituted. 447The exception is the plural-deciding argument in plural calls, 448where it is allowed to drop its placeholder, 449in either the singular or the plural text. 450 451If none of the arguments supplied to a plural call is integer-valued, 452 an error mark will be inserted into the message at run time 453 (when compiled in debug mode). 454 455Integer arguments will be by default formatted as if they denote 456an amount, according to locale rules (thousands separation, etc.) 457But sometimes an integer is a numerical identifier (e.g. port number), 458and then it should be manually converted into `QString` beforehand 459to avoid treatment as amount: 460 461~~~ 462i18n("Listening on port %1.", QString::number(port)); 463~~~ 464 465 466<a name="good_text"> 467 468### Writing Good Texts 469 470When writing message texts, sometimes it is tempting to assemble text 471from pieces such as to have less repetition. 472However, such shortcuts frequently cannot work for other languages, 473and are almost always confusing to translators. 474The first rule of writing good message texts is therefore to 475*keep sentences together and clearly structured* 476(or "no word puzzles"), even at the cost of some repetition. 477 478At its basic, this rule means always to use placeholders for insertion 479of run time arguments, rather than string concatenation. For example: 480 481~~~ 482// BAD: 483i18n("File ") + filePath + i18n(" not found."); 484// Good: 485i18n("File %1 not found.", filePath); 486~~~ 487 488This is rather obvious, since it also results in clearer and shorter code. 489But sometimes placeholders can be overused: 490 491~~~ 492// BAD: 493i18n("This contact is now %1.", 494 isOnline ? i18n("online") : i18n("offline")); 495// Good: 496isOnline ? i18n("This contact is now online.") 497 : i18n("This contact is now offline."); 498~~~ 499 500The shorter version here is bad, because the sentence structure of 501translation may need to change by more than the one word, 502and also because a less thorough translator may fail to check 503in which way the short messages "online" and "offline" are used. 504 505If an otherwise long text needs to differ in only small part, 506then a reasonable solution is to split it at sentence level, 507but also explain the situation to translators through context: 508 509~~~ 510// BAD: 511i18n("Something very long here. This contact is now %1.", 512 isOnline ? i18n("online") : i18n("offline")); 513// Good: 514i18nc("%1 one of the 'This contact...' messages below", 515 "Something very long here. %1", 516 isOnline ? i18n("This contact is now online.") 517 : i18n("This contact is now offline.")); 518// BAD: 519 i18n("Something very long here. ") 520+ isOnline ? i18n("This contact is now online.") 521 : i18n("This contact is now offline."); 522~~~ 523 524The third version above is bad because, firstly, the translator 525may wonder about the trailing space in the first message or 526simply overlook it, and secondly, there may be some cross-dependency 527between the translation of the long message and the short messages. 528In general, insertions of one message into another should *always* 529be accompanied by contexts, and composition-significant 530leading and trailing whitespace should be avoided. 531 532The second basic rule of writing good texts is to 533*expose every user-visible text for translation*. 534One should *never* make assumptions of the type 535"this does not need translation" or "it will be same in every language". 536 537One example where programmers sometimes make such assumption 538are compositions without any letters: 539 540~~~ 541// BAD: 542QString("%1: %2").arg(albumName, playCount); 543// Good: 544i18nc("album name: play count", "%1: %2", albumName, playCount) 545~~~ 546 547Here, in some languages the arrangement of whitespace will need to differ 548(e.g. a space may be needed before the colon as well). 549Letter-free compositions should also normally be equipped with context, 550because, for example, separation may depend on type of arguments. 551 552Another example of user-visible texts sometimes wrongly omitted 553from i18n are proper names: 554 555~~~ 556// BAD: 557label1->setText(i18n("Written by:")); 558label2->setText("Roofus McBane"); 559// Good: 560label1->setText(i18n("Written by:")); 561label2->setText(i18n("Roofus McBane")); 562~~~ 563 564Proper names too may need localization, for example, transliteration 565when the target language uses a different writing system. 566This holds for proper names of people, and of anything else. 567 568When it comes to text markup, like the HTML subset supported by 569Qt rich text processing, opinions are divided on how much of it 570to expose for translation. One argument goes that markup may be 571confusing for translators, and that exposing it increases 572the chance of syntactical errors in translation. 573This is true as such, but it should be balanced with situations where, 574either, the translator needs to modify the markup, 575or, the markup will convey some context to translator. 576For example, typographical modifiers should always be left in: 577 578~~~ 579// BAD: 580label->setText("<b>" + i18n("Disk almost full:") + "</b>"); 581// Good: 582label->setText(i18n("<b>Disk almost full:</b>")); 583~~~ 584 585because the target language may have different typographical standards 586(e.g. CJK languages tend to avoid boldface in text body font sizes, 587as it makes ideographs harder to recognize). 588Especially if tags are found around internal parts of the message text, 589it would be ungainly to hide them, e.g. by placeholder insertion. 590But, values to tag attributes, such as links in <tt>\<a href='...'></tt>, 591tags, should be inserted through placeholders 592(unless it is expected that translators provide localized values). 593In this example: 594 595~~~ 596// Good: 597i18n("<p>Preprocessing has failed.</p>" 598 "<p>Please check your bracketed images stack.</p>" 599 "<p>Click \"Details\" to show processing details.</p>") 600~~~ 601 602`<p>` tags could be avoided by splitting this message into 603one message per sentence, but this should not be done, because 604paragraphs should be translated as single units of meaning. 605 606Another important point about XML-like text markup, is to try and keep it 607well-formed in XML sense on the level of standalone message. For example: 608 609~~~ 610// BAD (for translation, although fine by HTML / Qt rich text): 611i18n("<p>Some sentence." 612 "<p>Another sentence."); 613// Good: 614i18n("<p>Some sentence.</p>" 615 "<p>Another sentence.</p>"); 616~~~ 617 618Well-formedness is good because the most frequent error in translation 619in presence of markup is mistyping (or miscopying) a tag. 620If the original text is well-formed, a translation checker tool 621can require the same of translation, and signal when that is not so. 622The previous example of non-well-formedness was perhaps trivial; 623in practice, non-trivial examples usually break some other rules too 624(e.g. no word puzzles). 625 626<a name="good_ctxt"> 627 628### Writing Good Contexts 629 630The message context, given as first argument in `*i18nc` calls, 631is of great help to translators. Unfortunately, to a programmer it is 632not always clear when a context is needed, or what it should state. 633So, the very first rule of writing good contexts is to 634*listen to the translators asking for contexts*. 635When taking suggestions from translators, there is no need to worry if 636the proposed context will be sufficient for "all" languages. 637It is fine to simply add the information that a translator into 638particular language requested, and wait for translators into other 639languages to maybe request some other context information as well. 640 641Having said this, some apriori guidelines on contexts can be followed. 642 643Since in English the form of an adjective does not change based on 644the gender of the noun it modifies, properly translating messages which 645are single standalone adjectives will be impossible in many languages 646without a context. So, in general, every message which is a standalone 647adjective should have context: 648 649~~~ 650i18nc("new file", "New"); 651i18nc("default action", "Default"); 652~~~ 653 654 655Lists of related items typically benefit from having the same context, 656since they should all be translated in the same style: 657 658~~~ 659i18nc("IPv4 configuration method", "Automatic (VPN)"); 660i18nc("IPv4 configuration method", "Automatic (VPN) addresses only"); 661i18nc("IPv4 configuration method", "Automatic (PPP)"); 662i18nc("IPv4 configuration method", "Automatic (PPP) addresses only"); 663... 664~~~ 665 666 667When there are placeholders in the text for which it is not clear, 668from the text alone, what kind of argument they represent, 669this should be explained in the context: 670 671~~~ 672i18nc("%1 old file path, %2 new file path", 673 "Cannot move '%1' to '%2'.", oldPath, newPath); 674i18nc("%1 track URL, %2 artist name", 675 "%1 (by %2)", trackUrl, artistName); 676~~~ 677 678 679It is frequently suggested to state in the context the grammar category 680of the message text, such as "this is a verb" or "this is a noun". 681Since the grammar category of the translation does not have to be 682the same as that of the original, this kind of context provides 683circumstantial information at best (see the section \ref uimark_ctxt 684for what translators may use it to draw some real information about), 685and is worthless at worst. 686Also, due to relative absence of declension in English grammar, 687different programmers may have different opinion on the grammar category: 688the menu title "View", is it a verb or a noun? 689 690<a name="uimark_ctxt"> 691 692#### User Interface Markers 693 694In the same way there exists a HIG (Human Interface Guidelines) document 695for the programmers to follow, translators should establish HIG-like 696convention for their language concerning the forms of UI text. 697Therefore, for a proper translation, the translator will need too know 698not only what does the message mean, but also where it figures in the UI. 699E.g. is the message a button label, a menu title, a tooltip, etc. 700 701To this end a convention has been developed among KDE translators, 702which programmers can use to succinctly describe UI usage of messages. 703In this convention, the context string starts with an *UI marker* 704of the form `@<major>:<minor>`, and may be followed by any other 705usual context information, separated with a single space: 706 707~~~ 708i18nc("@action:inmenu create new file", "New"); 709~~~ 710 711 712The major and minor component of the UI marker are not arbitrary, 713but are drawn from the following table. 714For each component, the superscript states the Ki18n release 715when the component was introduced. 716<table> 717<tr><th>Major</th><th>Minor</th><th>Description</th></tr> 718<tr><td><b>\@action</b><sup>5.0</sup></td><td></td> 719 <td>Labels of clickable widgets which cause an action 720 to be performed.</td></tr> 721<tr><td></td><td>:button<sup>5.0</sup></td> 722 <td>Push buttons in windows and dialogs.</td></tr> 723<tr><td></td><td>:inmenu<sup>5.0</sup></td> 724 <td>Menu entries that perform an action 725 (as opposed e.g. to being checked).</td></tr> 726<tr><td></td><td>:intoolbar<sup>5.0</sup></td> 727 <td>Toolbar buttons.</td></tr> 728<tr><td><b>\@title</b><sup>5.0</sup></td><td></td> 729 <td>Text that is the title of a major UI element or 730 a widget container.</td></tr> 731<tr><td></td><td>:window<sup>5.0</sup></td> 732 <td>Title of a window or a (dockable) view/pane.</td></tr> 733<tr><td></td><td>:menu<sup>5.0</sup></td> 734 <td>Menu title.</td></tr> 735<tr><td></td><td>:tab<sup>5.0</sup></td> 736 <td>Tab name.</td></tr> 737<tr><td></td><td>:group<sup>5.0</sup></td> 738 <td>Title to a group of widgets, like a group of checkboxes or 739 radio buttons.</td> 740<tr><td></td><td>:column<sup>5.0</sup></td> 741 <td>Column name in a table header, 742 e.g. in a table view widget.</td></tr> 743<tr><td></td><td>:row<sup>5.0</sup></td> 744 <td>Row name in a table.</td></tr> 745<tr><td><b>\@option</b><sup>5.0</sup></td><td></td> 746 <td>Labels of option selection widgets, which can be enable/disabled 747 or selected between.</td></tr> 748<tr><td></td><td>:check<sup>5.0</sup></td> 749 <td>Checkbox label, also a checkable menu entry.</td></tr> 750<tr><td></td><td>:radio<sup>5.0</sup></td> 751 <td>Radio button label.</td></tr> 752<tr><td><b>\@label</b><sup>5.0</sup></td><td></td> 753 <td>Various widget labels which are not covered by any of 754 \@action, \@title, or \@option.</td></tr> 755<tr><td></td><td>:slider<sup>5.0</sup></td> 756 <td>Slider label.</td></tr> 757<tr><td></td><td>:spinbox<sup>5.0</sup></td> 758 <td>Spinbox label.</td></tr> 759<tr><td></td><td>:listbox<sup>5.0</sup></td> 760 <td>Label to a list box or combo box.</td></tr> 761<tr><td></td><td>:textbox<sup>5.0</sup></td> 762 <td>Label to a text box or text edit field.</td></tr> 763<tr><td></td><td>:chooser<sup>5.0</sup></td> 764 <td>Label to any special-purpose chooser widget, 765 like color chooser, font chooser, etc.</td></tr> 766<tr><td><b>\@item</b><sup>5.0</sup></td><td></td> 767 <td>Strings that are items from a range of possibilities or 768 properties of a given type.</td></tr> 769<tr><td></td><td>:inmenu<sup>5.0</sup></td> 770 <td>Item presented in menu (e.g. sort ordering, 771 encoding name, etc).</td></tr> 772<tr><td></td><td>:inlistbox<sup>5.0</sup></td> 773 <td>Item presented in a list or combo box.</td></tr> 774<tr><td></td><td>:intable<sup>5.0</sup></td> 775 <td>Item presented in a table cell.</td></tr> 776<tr><td></td><td>:inrange<sup>5.0</sup></td> 777 <td>End range labels, e.g. on sliders.</td></tr> 778<tr><td></td><td>:intext<sup>5.0</sup></td> 779 <td>Words and short phrases which are inserted into 780 a larger piece of text.</td></tr> 781<tr><td></td><td>:valuesuffix<sup>5.46</sup></td> 782 <td>Suffix appended to a value, including any spacing 783 (e.g. in a spinbox).</td></tr> 784<tr><td><b>\@info</b><sup>5.0</sup></td><td></td> 785 <td>Any transient information for the user.</td></tr> 786<tr><td></td><td>:tooltip<sup>5.0</sup></td> 787 <td>Expanded formulation of the widget's label, 788 usually appearing automatically when the pointer 789 hovers over the widget.</td></tr> 790<tr><td></td><td>:whatsthis<sup>5.0</sup></td> 791 <td>Longer description of a widget's purpose and behavior, 792 usually manually called up by the user.</td></tr> 793<tr><td></td><td>:placeholder<sup>5.46</sup></td> 794 <td>A hint what input is expected in an input field, 795 shown in the place of the input where there is none yet.</td></tr> 796<tr><td></td><td>:status<sup>5.0</sup></td> 797 <td>A piece of text displayed in application's status view 798 (e.g in the status bar).</td></tr> 799<tr><td></td><td>:progress<sup>5.0</sup></td> 800 <td>Text describing the current step or state of an operation, 801 possibly periodically updating.</td></tr> 802<tr><td></td><td>:usagetip<sup>5.0</sup></td> 803 <td>A tip that comes up to inform the user about 804 a certain possibility in a given context, 805 e.g. a "tip of the day" on application startup.<br/> 806 Deprecated synonym: :tipoftheday.</td></tr> 807<tr><td></td><td>:credit<sup>5.0</sup></td> 808 <td>Contributor names and their contributions, 809 e.g. in the about dialog.</td></tr> 810<tr><td></td><td>:shell<sup>5.0</sup></td> 811 <td>A note, warning or error sent to application's text output stream 812 (stdout, stderr) rather than shown in the UI.</td></tr> 813</table> 814If none of the minor components apply to a given message, 815a major component can be used standalone. 816For example, this would happen with a library-provided list of items 817without any immediate UI context (e.g. language or country names), 818where the appropriate UI marker would be just `@item`. 819 820One way to extend the context after the UI marker, 821which is simple for the programmer yet can be very helpful for translators, 822is simply to add the text of the (technically or logically) parent widget. 823For example, if the action "New" is in the menu "File", then: 824 825~~~ 826i18nc("@action:inmenu File", "New") 827~~~ 828 829Or, if the item "Left" is found in the list box with 830the label "Vertical alignment": 831 832~~~ 833i18nc("@item:inlistbox Vertical alignment", "Left") 834~~~ 835 836 837<a name="nocpp_ctxt"> 838 839#### Adding Contexts in Non-C++ files 840 841When Qt Designer is used to build the user interface, 842the \em -tr option of `uic` should be used to pass UI strings 843through Ki18n's `tr2i18n` function (see also \ref link_ui). 844This function is the equivalent of `i18n` or `i18nc`, 845based on whether the second argument is null or not. 846If a string in the `.ui` file has the attribute `comment=`, 847its value will be automatically used as the context argument. 848(In Qt Designer, this is the "disambiguation" property of a string.) 849Alternatively, strings can be passed to Ki18n's `tr2xi18n` function 850(see \ref kuit_markup). 851 852In KXmlGui (`.rc`) and KConfigXT (`.kcfg`) files, 853contexts can be added through `context=` attributes to 854`text`, `label`, and `whatsthis` tags. 855 856<a name="ctxt_extc"> 857 858#### Disambiguation Context vs. Extracted Comment 859 860The GNU Gettext system actually defines *two* types of context 861for translators. The type discussed so far, the first argument 862of `*i18nc*` calls, is called *disambiguation context*. 863The other type of context is *extracted comment*. 864In Ki18n, this other type of context is written as a code comment, 865in the line just preceding the message text, 866and starting with *i18n:* keyword: 867 868~~~ 869// i18n: This is a short text containing all letter of the alphabet, 870// e.g. for testing fonts. Translate with a sentence which can 871// serve the same purpose in your language. 872i18n("The quick brown fox jumps over the lazy dog"); 873~~~ 874 875 876There are two main differences between disambiguation contexts and 877extracted comments. 878 879The first difference is that extracted comments 880*do not separate messages* in the translation catalog. 881For example, such two messages equipped with extracted comments: 882 883~~~ 884// i18n: new file 885QString msg1 = i18n("New"); 886// i18n: new folder 887QString msg2 = i18n("New"); 888~~~ 889 890will show up in the translation catalog as a single message 891with aggregate comments: 892 893~~~ 894#. i18n: new file 895#. i18n: new folder 896msgid "New" 897msgstr "" 898~~~ 899 900The same two messages equipped with disambiguation contexts: 901 902~~~ 903QString msg1 = i18nc("new file", "New"); 904QString msg2 = i18nc("new folder", "New"); 905~~~ 906 907will show up in the translation catalog as two messages: 908 909~~~ 910msgctxt "new file" 911msgid "New" 912msgstr "" 913 914msgctxt "new folder" 915msgid "New" 916msgstr "" 917~~~ 918 919 920The second difference is that a change in extracted comment 921*does not invalidate the existing translation*, i.e. 922it will not force translators to revisit the message and revise 923the translation (see the section \ref handle_update for details 924on how this invalidation happens with disambiguation contexts). 925Thus, for example, if there is a "message freeze" 926before the next release of a piece of software, during which 927programmers must not modify messages so that translators can 928thoroughly complete their work, it is allowed to modify 929the extracted comment, but it is not allowed to modify 930the disambiguation context. 931 932The Gettext manual suggests to use extracted comments as 933the default way of providing context for translators, 934and to use disambiguation contexts only when message separation 935is necessary. However, we (the people in the KDE community) 936suggest the opposite -- to use disambiguation context by default, 937and extracted comments only in special cases. 938This because there are two dangers associated with extracted comments: 939one is that programmer may fail to properly judge when two messages 940should be made separate for translation (and having to judge that 941all the time is a burden in the first place), and the other is that 942when the context change is such that translators really should revisit 943the message, they would not get any automatic signal about that. 944The message freeze advantage of extracted comments has not been 945observed to be very important. 946 947One special case when to an use extracted comment is when the context 948is a multi-sentence text explaining the purpose of the message, 949and the context is unlikely to change (in its meaning). 950Another case is when the context lists a fixed set 951of possible translations ("meta-messages", by which translators 952influence some aspect of text formatting), which may expand in 953the future, as new possibilities are introduced at request of 954translators into new languages. 955 956<a name="i18n_noop"> 957 958### Extraction-Only Functions 959 960Sometimes it is convenient only to mark a message for extraction 961(into the catalog template, as described in \ref handle_extract), 962and to place the actual `i18n` call somewhere else. 963A typical case of this are global static initializers, 964where only POD types can be safely used. 965For this purpose `kli18n*` functions are provided. 966 967The `kli18n` function is the counterpart to `*i18n` calls, 968and it is used like this: 969 970~~~ 971typedef struct 972{ 973 const KLazyLocalizedString description; 974 const char *regExp; 975} term; 976 977static const term items[] = { 978 {kli18n("any character"), "."}, 979 {kli18n("start of line"), "^"}, 980 {kli18n("end of line"), "$"}, 981 {kli18n("repeats, zero or more times"), "*"}, 982 ... 983}; 984 985... 986 987void populatePatternMenu (QMenu *menu) 988{ 989 for (uint i = 0; i < sizeof(items) / sizeof(items[0]); i++) { 990 menu->addAction(new RegExpAction(menu, 991 // ...actual i18n call here. 992 items[i].description.toString(), 993 items[i].regExp)); 994 } 995} 996~~~ 997 998 999The `kli18nc` macro is the counterpart to `*i18nc` calls: 1000 1001~~~ 1002typedef struct 1003{ 1004 const KLazyLocalizedString abbrev; 1005} unitDef; 1006static 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 1015Variants for singular/plural and with or without markup exist as well. 1016Unlike the `I18N_NOOP` macros they replace, mixing different variants 1017in the same message table is possible, e.g. to add a context to a few 1018messages when necessary. 1019 1020 1021<a name="link_cat"> 1022 1023## Connecting Calls to Catalogs 1024 1025Every `i18n` call must look for translations in exactly 1026one translation catalog for a given language of translation. 1027For this purpose, a group of catalogs which have the same source text 1028but translations into different languages, is identified by 1029a unique canonical name, called the *domain*. 1030Therefore, every `i18n` call must be connected to a domain. 1031This connection is established differently for applications 1032and libraries, though the difference is only for convenience: if desired, 1033the 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 1039All `*i18n*` calls in an application can be connected 1040to a single domain by calling the static 1041`KLocalizedString::setApplicationDomain` method with 1042the domain as the argument: 1043 1044~~~ 1045#include <klocalizedstring.h> 1046 1047... 1048 1049int main (int argc, char *argv[]) 1050{ 1051 ... 1052 KLocalizedString::setApplicationDomain("fooapp"); 1053 ... 1054} 1055~~~ 1056 1057This call must be made in the code before any `i18n` call takes place, 1058and right after creating the instance of `QCoreApplication` or one 1059of its subclasses. `ki18n` calls can still be made before, but the 1060respective `KLocalizedString::toString()` has to be delayed to after that. 1061 1062This is all there is to connecting calls and catalogs application's 1063C++ source files. However, there may also be some non-code files 1064that need connecting, and how to do this is some typical non-code 1065files 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 1072own translation domain no matter how the library is used, 1073and this should be fully transparent to the library's client. 1074In particular, if the client does not use Ki18n for internationalization 1075of its own messages, library translation must still work as expected. 1076Therefore, in library code, the call-domain connection is established 1077in this way: 1078 1079~~~ 1080#define TRANSLATION_DOMAIN "foolib" 1081#include <klocalizedstring.h> 1082 1083... 1084 1085void some_library_function () 1086{ 1087 ... 1088 QString msg = i18n("Greetings from Foolib!"); 1089 ... 1090} 1091~~~ 1092 1093The definition of `TRANSLATION_DOMAIN` triggers 1094the domain-specialization macro in `klocalizedstring.h`. 1095It routes all `*i18n*` calls to their `*i18nd*` counterparts, 1096which take the domain as their first argument. 1097The `i18n` call from this example will thus expand into: 1098 1099~~~ 1100QString msg = i18nd("foolib", "Greetings from Foolib!"); 1101~~~ 1102 1103 1104It is possible to use `*i18nd*` calls explicitly, 1105but there should be no need for that. 1106If there are any messages that should draw translations 1107from a special domain, it is better style-wise to use the 1108`ki18n("...").toString(domain)` construct. 1109 1110Definition of `TRANSLATION_DOMAIN` can be put into 1111a private header file of the library, so that it does not have 1112to be repeated at multiple locations. 1113If there are some `i18n` calls in a *public* header file, 1114definition of `TRANSLATION_DOMAIN` would propagate 1115into and affect the application client code that uses Ki18n too. 1116This is prevented by adding the following lines somewhere 1117after the last `i18n` call in the public header: 1118 1119~~~ 1120#undef TRANSLATION_DOMAIN 1121#include <klocalizedstring.h> 1122~~~ 1123 1124This will undefine all expansions of `*i18n*` into `*i18nd*`, 1125leaving the client's environment clean. 1126If instead the public header contains only `kli18n*` function calls, 1127defining `TRANSLATION_DOMAIN` is unnecessary in the first place, 1128since actual `i18n` calls happen somewhere else. 1129 1130<a name="link_noncode"> 1131 1132### Connecting to Catalogs in Non-Code Files 1133 1134Both KDE applications and libraries can include some non-code files 1135which contain messages that need to be connected to a translation domain. 1136This can be the same domain where messages from C++ code are found, 1137or another domain, whatever seems more appropriate. 1138In principle, each type of non-code file requires its own connection 1139mechanism, and here it is explained how this works for 1140typical types of non-code files found in KDE sources. 1141 1142It is assumed in the following that all messages in the non-code file 1143are connected to the single domain. In other words, the connection 1144is specified on the file level rather than on the message level. 1145 1146<a name="link_ui"> 1147 1148#### Qt Designer (.ui) files 1149 1150First, to have UI strings from `.ui` file passed through Ki18n, 1151`uic` is run with `-tr tr2i18n`. This will replace all 1152native Qt `tr` calls with Ki18n's `tr2i18n` calls 1153in the resulting header file. 1154Then, the generated header file needs to be post-processed 1155to fix empty messages and include `klocalizedstring.h`. 1156At this point, the `TRANSLATION_DOMAIN` can be defined just like 1157in static C++ files. 1158 1159If CMake is used as the build system, a macro that performs 1160all of the above is provided (`ki18n_wrap_ui`). 1161Otherwise, one could use a shell snippet such as this: 1162 1163~~~ 1164domain=fooapp 1165uifile=fooconfpage.ui 1166uihfile=$uifile.h 1167uic -tr tr2i18n $uifile -o $uihfile 1168sed -i 's/tr2i18n("")/QString()/g' $uihfile 1169sed -i 's/tr2i18n("", "")/QString()/g' $uihfile 1170sed -i "1i\#define TRANSLATION_DOMAIN \"$domain\"\n#include <klocalizedstring.h>" $uihfile 1171~~~ 1172 1173 1174If 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 1181Since `.rc` files are interpreted at runtime, 1182the translation domain connection is established simply 1183by 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 1191If the `.rc` file belongs to application rather than library source, 1192it is not necessary to set `translationDomain`. If not set, 1193translations will be looked up in the domain set with 1194`KLocalizedString::setApplicationDomain` call in the code. 1195 1196If strings contain KUIT markup (section \ref kuit_markup), 1197additionally the attribute `translationMarkup="true"` should be set. 1198 1199<a name="link_kcfg"> 1200 1201#### KConfigXT (.kcfg) files 1202 1203Instructions for building the configuration code from a `.kcfg` file 1204are contained in the `.kcfgc` file of the same base name; 1205`kconfig_compiler` is invoked with both files as arguments. 1206Then, the domain connection is established simply by adding 1207the `TranslationSystem` and `TranslationDomain` fields in 1208the `.kcfgc` file, to select Ki18n as the translation system 1209and the appropriate translation domain: 1210 1211~~~ 1212File=foolib.kcfg 1213... 1214TranslationSystem=kde 1215TranslationDomain=foolib 1216~~~ 1217 1218If the `.kcfg` file is part of an application rather than a library, 1219the `TranslationDomain` field can be omitted in order 1220to have messages looked up in the domain set by 1221`KLocalizedString::setApplicationDomain` call in the code. 1222 1223If strings contain KUIT markup (section \ref kuit_markup), 1224additionally the field `TranslationMarkup=true` should be set. 1225 1226<a name="handle_cat"> 1227 1228## Handling Catalog Files 1229 1230For translators to start working, one or more translation catalog files 1231should be prepared, based on the `i18n` calls in the source code. 1232The procedure to do this is called *extraction* of messages. 1233Extraction produces empty catalog files, called *templates*. 1234These files are in the PO format, and have `.pot` extension. 1235Section \ref handle_extract explains how to perform extraction. 1236 1237Once templates are ready, a translators make copies of them, 1238with `.po` extension, and start filling them out with translations 1239into respective languages. 1240When translation is done, the translated catalog is committed 1241into the source code repository. 1242The build system is set up to install translated catalogs. 1243Section \ref handle_install provides necessary steps for this. 1244 1245After some development has passed, the source repository will 1246contain many translated catalogs which are out of date with 1247respect to latest catalog templates. 1248Of course, translators do not have to start translating from scratch, 1249but there are specialized tools to carry over as much of existing 1250translation as possible, so that only new and modified texts 1251need to be considered. 1252Section \ref handle_update shows how this is done. 1253 1254A usual application or a library has one translation catalog, 1255but there can be more if there is higher modularity of the source. 1256The following subsections refer to a single catalog wherever 1257the extension to case with multiple catalogs is obvious, 1258and mention multiple catalogs only where necessary. 1259 1260<a name="handle_extract"> 1261 1262### Extracting Templates 1263 1264The primary tool for collecting texts from `i18n` calls and 1265writing out the catalog template is `xgettext`, 1266from the official Gettext tools package. 1267`xgettext` supports many programming languages and sublanguage 1268environments, among which naturally C++ and Ki18n specifically. 1269 1270The extraction process from source code files is thus simple: 1271`xgettext` runs with appropriate options over all files, 1272and it writes out the catalog template. 1273For the moment masking the complete list of options as `$EXTOPTS`, 1274`xgettext` can be run for example like this at the top of Fooapp 1275source to create the catalog template `fooapp.pot`: 1276 1277~~~ 1278find -name \*.cpp -o -name \*.h -o -name \*.qml | sort \ 1279| xargs xgettext $EXTOPTS -o fooapp.pot 1280~~~ 1281 1282Or, a list of source files that should be extracted from can be 1283assembled separately and fed to `xgettext:` 1284 1285~~~ 1286# ...create sources.list... 1287xgettext $EXTOPTS -f sources.list -o fooapp.pot 1288~~~ 1289 1290One may want to assemble the list of source files by hand 1291or semi-automatically in order to prioritize the order of translation 1292(messages from most important files appearing first in the catalog), 1293to exclude some portions of the source tree from extraction, and so on. 1294 1295`$EXTOPTS` that cover everything from Ki18n, and some generalities, 1296should 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 1311are C++ with Ki18n. `--from-code=UTF-8` specifies the encoding 1312of source files to be UTF-8, which must be so for Ki18n. 1313`-c i18n` states that comments for extraction start with given 1314keyword (`// i18n: ...`). 1315The series of `-k` options informs `xgettext` of all possible 1316translation call names and which of their arguments to extract. 1317Finally, options `--copyright-holder` and 1318`--msgid-bugs-address` automatically write 1319the corresponding information into the catalog at proper place. 1320If there are semantic markup calls in the code (section \ref kuit_markup), 1321the 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 1331from the usual XML files appearing in Qt and KDE sources -- 1332Designer (`.ui`), KXmlGui (`.rc`) and KConfigXT (`.kcfg`) files. 1333Therefore the `kdesdk` package provides the `extractrc` script, 1334which extracts XML messages as dummy `i18n` calls into a dummy C++ file, 1335This file can then be included into the list of files for `xgettext` run. 1336The usual invocation of `extractrc` is: 1337 1338~~~ 1339find -name \*.ui -o -name \*.rc -o -name \*.kcfg | sort \ 1340| extractrc > rc.cpp 1341# ...run xgettext with rc.cpp included in source files... 1342rm rc.cpp 1343~~~ 1344 1345 1346If the catalog being extracted is an application catalog, 1347i.e. given as `KLocalizedString::setApplicationDomain` in the code, 1348it should contain two meta-messages for translation credits 1349which will be shown by `KAboutApplicationDialog`. 1350These messages are also written as dummy `i18n` calls, 1351usually into the same dummy C++ file with XML messages, 1352with the following context and text: 1353 1354~~~ 1355echo 'i18nc("NAME OF TRANSLATORS", "Your names");' >> rc.cpp 1356echo 'i18nc("EMAIL OF TRANSLATORS", "Your emails");' >> rc.cpp 1357~~~ 1358 1359 1360The extraction command sequence can be written down as a small script, 1361to be run periodically by the maintainer, 1362or it can be integrated into the build system. 1363 1364For the code residing in the official KDE repositories 1365a special form of the extraction script is mandated. 1366This enables automatic overnight template extraction and feeding 1367into dedicated translation section of KDE repositories. 1368Details 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 1375For an application or a library which uses a single catalog, 1376the usual organization of catalogs in the source tree is this: 1377 1378~~~ 1379fooapp/ 1380 src/ 1381 doc/ 1382 po/ 1383 fooapp.pot 1384 aa.po 1385 bb.po 1386 cc.po 1387 ... 1388~~~ 1389 1390Here translated catalog files are named by their language codes 1391(`aa`, `bb`, `cc`...). 1392In case of multiple catalogs, one directory per catalog can be created 1393under the `po/` directory: 1394 1395~~~ 1396fooapp/ 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 1413An alternative organization is to have one directory per language, 1414and name catalog files by the translation domain. 1415In multiple catalog situation this would look like: 1416 1417~~~ 1418fooapp/ 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 1436Catalog templates are fully derived files, and therefore 1437some maintainers do not like to keep them inside the repository. 1438In that case, at least the tarball should contain the templates 1439(i.e. they should be generated at packaging time), 1440so that translators have somewhere to get them from. 1441Another possibility is to upload the template to 1442a *translation hub* (such as 1443<a href="https://www.transifex.com/">Transifex</a>), 1444which translators can use to upload translated catalogs back, 1445and usually for some other features as well (assignment, review, etc). 1446 1447If the code resides in an official KDE repository, neither templates 1448nor translated catalogs are kept inside the source tree. 1449Instead, translated catalogs are fetched from an appropriate place 1450when tarball is made, using a script provided for that purpose. 1451Details can be found at 1452<a href="http://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems">KDE Techbase</a>. 1453 1454No matter how the catalog files are named and organized inside 1455the distribution tarball, they must be installed in exactly one way. 1456The base name of the installed catalog must be their translation domain, 1457and if the package is installed into `$PREFIX`, the installed directory 1458tree 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 1475Given that these directories are shared with other packages 1476in the same prefix, by Gettext convention translation domains 1477must be unique (like package names are). 1478 1479MO files are the compiled version of PO files, and they are produced 1480using Gettext's `msgfmt` command: 1481 1482~~~ 1483msgfmt $SRCDIR/po/fooapp/aa.po -o $BUILDDIR/mo/aa/fooapp.mo 1484~~~ 1485 1486Compilation and installation of catalogs should naturally be integrated 1487into the build system. In case <a href="http://www.cmake.org/">CMake</a> 1488is used, KDE provides CMake macros for this purpose. 1489 1490<a name="handle_transcript"> 1491 1492#### Placing and Installing Scripting Modules 1493 1494Since Ki18n provides a run-time scripting capability for translators, 1495some translators may also write the scripting module corresponding 1496to the catalog. 1497A scripting module is a directory named like the translation domain, 1498and at least one JavaScript file inside, also with the same base name 1499as the translation domain. 1500 1501Scripting modules can be placed like this in the source tree: 1502 1503~~~ 1504fooapp/ 1505 po/ 1506 fooapp.pot 1507 aa.po 1508 aa/ 1509 fooapp.js 1510 ... 1511 bb.po 1512 ... 1513~~~ 1514 1515or in the per-language directory variant: 1516 1517~~~ 1518fooapp/ 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 1533The installation location for scripting modules is like that for catalogs, 1534only 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 1548When a translator inquires about adding a scripting module, 1549or sends one in, the maintainer should check with the translator 1550if perhaps the functions provided by the module are more widely 1551applicable. If that is the case, they should rather become part of 1552Ki18n's own scripting module, because then they will be accessible 1553to all Ki18n-based translations in the given language. 1554 1555<a name="handle_update"> 1556 1557### Updating Catalogs 1558 1559When new catalog template is extracted after some development 1560has been done, existing translation should be updated against it. 1561This is called *merging* with template, and it is performed 1562by Gettext's `msgmerge` command. 1563There are some merging options that can be examined here, 1564but generally the best invocation of `msgmerge` is this: 1565 1566~~~ 1567msgmerge --update --backup=none --previous aa.po fooapp.pot 1568~~~ 1569 1570Options `--update --backup=none` mean to update the catalog 1571in place, and not to make a backup file. Option `--previous` 1572puts some additional information into every modified message, 1573that translation editing tools can use to show to the translator 1574all changes in the text. 1575This command should be run once for every existing translation catalog. 1576 1577One thing to keep in mind is that a change in the context string 1578of a message in the code (i.e. the first argument to `*i18nc*` calls), 1579including adding or removing one, will also register as 1580a modified message in the merged catalog. 1581This will require that translators revisit it, which is exactly as 1582intended: if the context has changed, especially if it was added, 1583some changes in translation may be needed. 1584However, this means that when a "message freeze" is declared so that 1585translators can complete updating translations without disruption, 1586contexts fall under same rules as text. 1587 1588There are a few possibilities for who and when should perform merging. 1589For example, the maintainer can write a script that at the same time 1590extracts the template and merges all catalogs, and run it periodically, 1591committing updated catalogs to the repository for translators to pick up. 1592This could even be integrated into the build system. 1593Some maintainers do not like committing automatic changes, 1594and instead expect translators to run the extraction-merging script 1595for the language they maintain, update the translation, 1596and commit only that updated catalog. This solution is cleaner with 1597respect to repository history, but it may burden translators. 1598 1599When operating in an official KDE repository, maintainers do not 1600have to deal with merging at all. The server-side automation which 1601automatically extracts templates and provides them to translators, 1602also performs merging. So the maintainer is left only to pick up 1603whatever are the latest catalogs when making a tarball. 1604 1605 1606<a name="kuit_markup"> 1607 1608## Semantic Markup 1609 1610When composing user-interface text, some programmers ponder about 1611the typographical conventions to use in certain contexts. 1612For example, when a file name is inserted into the text, 1613some typographical solutions that can be used are: 1614 1615~~~ 1616i18n("Cannot open %1 for reading.", filePath); 1617i18n("Cannot open '%1' for reading.", filePath); 1618i18n("Cannot open \"%1\" for reading.", filePath); 1619~~~ 1620 1621For the Qt widgets that have rich text capability, 1622exposed as subset of HTML tags, additional solutions include: 1623 1624~~~ 1625i18n("Cannot open <b>%1</b> for reading.", filePath); 1626i18n("Cannot open <i>%1</i> for reading.", filePath); 1627i18n("Cannot open <tt>%1</tt> for reading.", filePath); 1628~~~ 1629 1630The problem here is not so much to decide on one solution, as it is 1631to follow it consistently through time and between contributors. 1632One may also want to use two solutions, one in places where only 1633plain text is allowed, and another where rich text is available. 1634Wouldn't it then be easier to write everywhere: 1635 1636~~~ 1637xi18n("Cannot open <filename>%1</filename> for reading.", filePath); 1638~~~ 1639 1640and have it automatically resolve into plain or rich text according to 1641the UI context, using formatting patterns defined at one place? 1642This approach is called *semantic* markup, because the author 1643marks parts of the text according to what they *represent*. 1644 1645Ki18n implements such a semantic markup, 1646called KUIT (KDE User Interface Text). 1647It is accessed through the series of `xi18n*` and `kxi18n*` calls, 1648which are the KUIT-aware counterparts of `i18n*` and `ki18n*` calls. 1649Ordinary and KUIT-aware calls can be freely mixed within 1650a given body of code. 1651 1652KUIT defines a number of semantic tags that are frequently of use, 1653as listed in the section \ref kuit_tags. 1654But, KUIT also allows the programmer to define custom tags, 1655as well as to change visual formatting patterns for predefined tags. 1656This capability should lessen one important issue of semantic markups: 1657when the author is forced to choose between several tags 1658none of which exactly fits the desired meaning; 1659with KUIT, the author can simply define a custom tag in that case. 1660 1661<a name="kuit_def_tags"> 1662 1663### Defining Tags 1664 1665Tags are defined and redefined per translation domain, so that changes 1666will not affect markup resolution in any other domain. 1667Changes are performed through the `KuitSetup` object associated 1668with the domain, as returned by the `Kuit::setupForDomain` method. 1669A tag is defined (or redefined) by defining (or redefining) 1670its formatting patterns, with one call to `KuitSetup::setTagPattern` 1671for each desired combination of tag name, attribute names, 1672and visual format. 1673Here is an example of defining the tag `<player>`, 1674which has an optional attribute `color=`, 1675on the domain `foogame`: 1676 1677~~~ 1678KuitSetup *ks = Kuit::setupForDomain("foogame"); 1679QString tagName; 1680QStringList attribNames; 1681 1682tagName = "player"; 1683attribNames.clear() 1684ks->setTagPattern(tagName, attribNames, Kuit::PlainText, 1685 ki18nc("tag-format-pattern <player> plain", 1686 "'%1'")); 1687ks->setTagPattern(tagName, attribNames, Kuit::RichText, 1688 ki18nc("tag-format-pattern <player> rich", 1689 "<b>%1</b>")); 1690attribNames.append("color"); 1691ks->setTagPattern(tagName, attribNames, Kuit::RichText, 1692 ki18nc("tag-format-pattern <player color= > rich", 1693 "<font color='%2'><b>%1</b></font>")); 1694~~~ 1695 1696The first two `setTagPattern` calls set up resolution of 1697`<player>` without attributes, into plain and rich text. 1698The third call sets up resolution for `<player color="...">`, 1699but only into rich text; since a plain text pattern is not defined 1700for this tag-attribute combination, it will fall back to basic 1701`<player>` plain text pattern. 1702A fallback is always defined, the elementary fallback being a no-op, 1703where tag is simply removed. 1704Formatting patterns must be wrapped for translation too, 1705since translators may need to tweak them; 1706*ordinary* (not markup-aware) `ki18nc` calls must be used here, 1707since patterns themselves are not KUIT markup. 1708The `%1` placeholder in the pattern will be replaced by 1709the text wrapped with the tag, and `%2` and upwards with 1710attribute values, in the order of appearance in attribute names list. 1711 1712If a simple substitution pattern is insufficient for formatting, 1713additionally a formatting function of type `Kuit::TagFormatter` 1714can be given. The result of this function is substituted into the pattern; 1715alternatively an empty pattern can be given (as `KLocalizedString()`), 1716in which case the result is used directly, no substitution is performed. 1717The formatting function also receives the current element path, 1718so that the resolution can depend on the markup tree context if needed. 1719Anything in the function that may need translator input 1720should be appropriately exposed through `i18nc*` or `ki18nc*` calls. 1721 1722In the section \ref kuit_tags it is stated that every KUIT tag 1723is classified either as a phrase tag or as a structuring tag, 1724and explained what that means for processing. 1725A newly defined tag is by default a phrase tag; 1726method `KuitSetup::setTagClass` can be used to change its class: 1727 1728~~~ 1729tagName = "list2"; 1730ks->setTagPattern(tagName, ...); 1731ks->setTagClass(tagName, Kuit::StructTag); 1732~~~ 1733 1734 1735In a library, changes to the KUIT setup may need to be private, 1736applicable only in library's own domain, but they may also need 1737to be public, applicable in clients' domains. 1738For changes that should be public, the library should define 1739a public function which takes the domain as the argument 1740and performs all the changes on that domain: 1741 1742~~~ 1743void updateKuitSetup (const char *domain) 1744{ 1745 KuitSetup *ks = Kuit::setupForDomain(domain); 1746 .... 1747} 1748~~~ 1749 1750The client code should then call this function in its initialization. 1751 1752<a name="kuit_sel_fmt"> 1753 1754### Selecting Visual Format 1755 1756The target visual format for any given `xi18n` call can be selected 1757in two ways. 1758 1759The primary way is by UI markers in the message context, 1760which were described in the section \ref uimark_ctxt. 1761Every `@<major>:<minor>` marker combination has 1762a 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> 1786Target visual formats associated with UI markers can be changed using 1787the `KUITSetup::setFormatForMarker` method: 1788 1789~~~ 1790KuitSetup *ks = Kuit::setupForDomain("fooapp"); 1791// Set standalone @info (no minor component) to plain text: 1792ks->setFormatForMarker("@info", Kuit::PlainText); 1793// Set @info:tooltip to rich text: 1794ks->setFormatForMarker("@info:tooltip", Kuit::RichText); 1795// Set all @info:<minor> to plain text: 1796ks->setFormatForMarker("@info:", Kuit::PlainText); 1797~~~ 1798 1799 1800The second way to select the visual format is by using a `kxi18n*` call, 1801and passing the format type to the `toString` method: 1802 1803~~~ 1804kxi18nc("@info", "Logging paused.").toString(Kuit::PlainText); 1805~~~ 1806 1807This will override any format implied by the UI marker if present. 1808 1809If a library is making modifications in visual format association 1810with UI markers, and these changes should be available to clients, 1811the same approach as in the section \ref kuit_def_tags should be used. 1812 1813<a name="kuit_escape"> 1814 1815### Escaping 1816 1817While for `*i18n*` calls it was advised to keep each message text 1818well-formed by itself with respect to Qt rich text markup, 1819for `*xi18n*` calls well-formedness is mandatory. 1820This means that markup-significant characters in plain-looking text 1821need to be escaped, using standard XML entities: 1822 1823~~~ 1824xi18n("Installed Fooapp too old, need release >= 2.1.8."); 1825xi18n("Set <themeId> as theme on startup"); 1826~~~ 1827 1828The exception is the ampersand (&) character, which in XML denotes 1829the start of an entity, but in Qt denotes the accelerator marker. 1830Therefore it is necessary to escape ampersand as `&` 1831only when it is in position which would result in valid entity syntax: 1832 1833~~~ 1834// Escaping not needed because not in entity-like position: 1835xi18n("Remove &all entries"); 1836// Escaping not needed for the same reason wrt. markup, 1837// but ampersand doubled to escape it wrt. Qt accelerator marker: 1838xi18n("Look && Feel"); 1839// Escaping wrt. markup necessary: 1840xi18n("Delete &everything; see if I care!"); 1841~~~ 1842 1843The example for necessary escaping above is rather artificial, 1844because in practice it is unlikely for ampersand to appear 1845in entity-like position while not actually starting an entity. 1846 1847To assure the validity of markup when arguments are inserted into 1848`xi18n`-wrapped text, all markup-significant characters 1849in string arguments are automatically escaped. 1850For example, this works as expected: 1851 1852~~~ 1853QString filePath("assignment03-<yourname>.txt"); 1854QString msg1 = kxi18n("Delete <filename>%1</filename>?", filePath) 1855 .toString(Kuit::PlainText); 1856// msg1 == "Delete 'assignment03-<yourname>.txt'?" 1857QString msg2 = kxi18n("Delete <filename>%1</filename>?", filePath) 1858 .toString(Kuit::RichText); 1859// msg2 == "Delete `assignment03-<yourname>.txt`?" 1860~~~ 1861 1862But, how then to compose a text where the arguments too should 1863contain some KUIT markup? This is done by using non-finalization 1864`kxi18n*` call to translate the argument text, and passing 1865the returned `KLocalizedString` object directly as argument: 1866 1867~~~ 1868KLocalizedString stateDesc = kxi18n( 1869 "On <emphasis>indefinite</emphasis> hold."); 1870QString 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 1877If the argument and the text have different visual formats implied by 1878their UI markers, the outermost format overrides inner formats. 1879 1880<a name="kuit_tags"> 1881 1882### Predefined Tags 1883 1884All 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 1889A text without any structuring tags is considered equivalent of 1890one paragraph or sub-paragraph sentence or phrase. 1891If at least one structuring tag appears in the text, 1892then the text is considered multi-paragraph, 1893and no content may appear outside of structuring tags. 1894For example: 1895 1896~~~ 1897// Good: 1898i18nc("@info", 1899 "You can configure the history sidebar here."); 1900// BAD: 1901i18nc("@info", 1902 "<title>History Sidebar</title>" 1903 "You can configure the history sidebar here."); 1904// Good: 1905i18nc("@info", 1906 "<title>History Sidebar</title>" 1907 "<para>You can configure the history sidebar here.</para>"); 1908~~~ 1909 1910 1911The current set of predefined tags is presented below. 1912For each tag the following information is stated: 1913the tag name (in superscript: Ki18n release of first appearance), 1914available attributes (in superscript: \em * if mandatory, 1915Ki18n release of first appearance), 1916admissible subtags, and description. 1917 1918<table> 1919<tr><th> 1920Phrase Tags 1921</th></tr> 1922<tr><td> 1923<b>\<application\></b><sup>5.0</sup><br/> 1924Name of an application. 1925 1926~~~ 1927i18nc("@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/> 1934Line-breaking body of code, for short code or output listings. 1935 1936~~~ 1937i18nc("@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/> 1949Name of a shell command, system call, signal, etc. 1950Its man section can be given with the `section=` attribute. 1951 1952~~~ 1953i18nc("@info", 1954 "This will call <command>%1</command> internally.", cmdName); 1955i18nc("@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/> 1964Email address. 1965Without attributes, the tag text is the address. 1966If the address is explicitly given with the `address=` attribute, 1967the tag text is the name or description attached to the address. 1968In rich text, the phrase will be hyperlinked. 1969 1970~~~ 1971i18nc("@info", 1972 "Send bug reports to <email>%1</email>.", emailNull); 1973i18nc("@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/> 1981Emphasized word or phrase in the text. 1982For strong emphasis, attribute `strong=` 1983can be set to `[1|true|yes]`. 1984</td></tr> 1985<tr><td> 1986<b>\<envar\></b><sup>5.0</sup><br/> 1987Environment variable. 1988A `$`-sign will be prepended automatically in formatted text. 1989 1990~~~ 1991i18nc("@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/> 1999File or folder name or path. 2000Slash (/) should be used as path separator, and it will be converted 2001into native separator for the underlying platform. 2002 2003~~~ 2004i18nc("@info", "Cannot read <filename>%1</filename>.", filePath); 2005i18nc("@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/> 2013Inline code, like a shell command line. 2014 2015~~~ 2016i18nc("@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/> 2023Path to a graphical user interface element. 2024If a path of UI elements is needed, 2025elements should be separated with `|` or `->`, 2026which will be converted into the canonical separator. 2027 2028~~~ 2029i18nc("@info:whatsthis", 2030 "If you make a mistake, click " 2031 "<interface>Reset</interface> to start again."); 2032i18nc("@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/> 2041Link to a URL-addressable resource. 2042Without attributes, the tag text is the URL; 2043alternatively, the URL can be given by `url=` attribute, 2044and then the text serves as description. 2045Separate URL and description are preferred if applicable. 2046The phrase will be hyperlinked in rich text. 2047 2048~~~ 2049i18nc("@info:tooltip", 2050 "Go to <link>%1</link> website.", urlKDE); 2051i18nc("@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/> 2059An external message inserted into the text. 2060 2061~~~ 2062i18nc("@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/> 2069Line break. 2070 2071~~~ 2072i18nc("@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/> 2082The sentence is a side note related to the topic. 2083Prefix "Note:" will be added automatically; 2084another prefix can be set with attribute `label=`. 2085 2086~~~ 2087i18nc("@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/> 2096A placeholder text. 2097It could be something which the user should replace with actual text, 2098or a generic item in a list. 2099 2100~~~ 2101i18nc("@info", 2102 "Replace <placeholder>name</placeholder> with your name."); 2103i18nc("@item:inlistbox", 2104 "<placeholder>All images</placeholder>"); 2105~~~ 2106 2107</td></tr> 2108<tr><td> 2109<b>\<shortcut\></b><sup>5.0</sup><br/> 2110Combination of keyboard keys to press. 2111Key names should be separated by "+" or "-", 2112and the shortcut will be converted into canonical form. 2113 2114~~~ 2115i18nc("@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/> 2124The sentence is a warning. 2125Prefix "Warning:" will be added automatically; 2126another prefix can be set with attribute `label=`. 2127 2128~~~ 2129i18nc("@info", 2130 "Really delete this key? " 2131 "<warning>This cannot be undone.</warning>"); 2132~~~ 2133 2134</tr></td> 2135<tr><th> 2136Structuring Tags 2137</th></tr> 2138<tr><td> 2139<b>\<item\></b><sup>5.0</sup><br/> 2140<i>Subtags:</i> all phrase tags<br/> 2141A list item. 2142</tr></td> 2143<tr><td> 2144<b>\<list\></b><sup>5.0</sup><br/> 2145<i>Subtags:</i> \<item\><br/> 2146List of items. 2147List is considered an element of the paragraph, 2148so `<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/> 2153One 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/> 2158The 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/> 2163The title of the text. 2164Must be the first tag in the text if present. 2165</tr></td> 2166</table> 2167 2168The criteria for adding new tags to the predefined set, 2169particularly new phrase tags, are not very strict. 2170If the tag is clearly useful to a class of applications, 2171of which more than one are known to use Ki18n, 2172it is reasonable to add it here. 2173Adding synonymous tag names is also fine, where one finds that 2174the original name is not sufficiently discoverable, 2175or that it is too verbose for the given frequency of use. 2176 2177<a name="kuit_ents"> 2178 2179### Predefined Entities 2180 2181KUIT defines a fixed set of XML entities, which means that unlike tags, 2182entities cannot be added to, nor their character expansions changed. 2183The 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> 2192The `&apos;` and `&quot;` are really needed only 2193within attribute values (and even there they can be avoided 2194by choosing the opposite quote sign for quoting the attribute value). 2195 2196Additional entities are (Ki18n release where they were introduced 2197given 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 2206The reason for not allowing custom entities 2207can be demonstrated by the following example. 2208An application programmer may think of defining the entity 2209`&appname;`, which would be used everywhere in text in place of 2210the actual application name. In that way, seemingly, it would be easy 2211to play with various names or spellings without disrupting translations. 2212The problem, however, is that in many languages the structure of 2213the sentence depends on the grammar properties of the particular name 2214(e.g. its grammar gender or number), and conversely, the name may 2215need modification according to sentence structure (e.g. by grammar case). 2216Thus, custom entities are not allowed because 2217they are misused too easily. 2218If something *really* needs to be inserted verbatim into text, 2219argument substitution is always at hand. 2220 2221 2222<a name="non_text"> 2223 2224## Localizing Non-Text Resources 2225 2226It sometimes happens that a non-textual application resource 2227needs localization. The most frequent example are images 2228that contain some text, like splash screens. 2229Ki18n also provides a rudimentary facility for this situation, 2230the `KLocalizedString::localizedFilePath` static method. 2231When called with a resource file path as the argument, 2232this method will check what are the active languages, 2233and look if there exists a localized version of the resource at path 2234`<original-parent-dir>/l10n/<language>/<original-basename>`. 2235For example, if the active language is `aa`, and a candidate image 2236for localization is installed as: 2237 2238~~~ 2239$PREFIX/share/fooapp/splash.png 2240~~~ 2241 2242then a call to 2243 2244~~~ 2245QString splashPath = QStandardPaths::locate( 2246 QStandardPaths::GenericDataLocation, "splash.png"); 2247splashPath = KLocalizedString::localizedFilePath(splashPath); 2248~~~ 2249 2250will check if there exist the file 2251 2252~~~ 2253$PREFIX/share/fooapp/l10n/aa/splash.png 2254~~~ 2255 2256and return that path if it does, or else the original path. 2257 2258Some KDE libraries will call `KLocalizedString::localizedFilePath` 2259on their own behind the scene, for resources that may need localization 2260but whose paths are not directly manipulated in application sources. 2261An example here are icons handled through `KIcon` class, 2262which are referred to in the code only by the icon name. 2263 2264 2265<a name="refs"> 2266 2267## Further References 2268 2269For details about the format of translation catalogs (PO) 2270and various Gettext tools, the first stop is the 2271<a href="http://www.gnu.org/software/gettext/manual/gettext.html"> 2272Gettext 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"> 2276series of tutorials</a> on preparing the KDE code for localization, 2277and on the internationalization process in general. 2278 2279