UI and Help files Content Guide

This guide details the content of the UI and Help files regarding the elements that have or have not to be translated, such as variables or xml elements used in the .po files.

Unique terms
Some words have to be unique in your translation files otherwise it will break the product or risk data loss for the user. These terms are:
 * Style names such as those that you can find in the sw/source/ui/utlui.po file
 * Function names in Calc (such as STRLIST_FUNCTION_NAME) that you can find in the formula/source/core/resource.po file
 * Math symbols that you can find in the starmath/source.po file. Note also that Math symbols must not contain spaces. For example the perthousand math symbol must not be translated per thousand or noelement must not be translated no element.
 * Index entries in the online help such as  Editing;Help Files\<\/bookmark_value\> , even if they are not in the same files, as it will break the display of the index entry.
 * the | symbol in Windows installer strings

Variables and symbols in the UI files
While it is hard to state any hard rules about variables and symbols in the UI files, as LibreOffice uses a mix of technologies in different parts of the source code, this is an attempt at writing down some rules.

Up one level| Create New Folder|
 * Some files contain a | at the end of the strings. This sign is mandatory, as a runtime error in the installer will occur if it is left out. Here is an example from instsetoo_native/inc_openoffice/windows/msi_languages.po:

%PRODUCTNAME                This will display the name of the product Change object title of %1   %1 will be replaced by the name of the object Internal error $(ARG1). $(ARG1) will be replaced by the internal error number
 * $ and % most of the time introduce a variable that will be replaced in the user interface, and the word or number following the $ or % must not be translated. Examples:


 * If $ is used as a currency as in the following string, though, it is not a variable, and the currency can freely be translated if appropriate in the situation:

Returns the price per $100 face value of a security with an odd last period


 *  \n  indicates a new line in the UI. You should try to organize the string in your translation to fit the line break but do not remove it or the string will be truncated in the dialog box. Example:
 * 1) 1 Verify Impress is running \n
 * 2) 2 For Bluetooth user, enable "Preferences"-"LibreOffice Impress"-"General"-"Enable remote control"\n
 * 3) 3 For WiFi user, tick "Preferences"-"LibreOffice"-"Advanced"-"Enable Experimental Features" \n
 *  {x} , where 'x' is a number, is a variable used in the Impress Remote app. It must not be changed.


 *   , where X is a word in UPPERCASE letters, is in most cases a variable which should not be translated. Some examples are , ,  and . Ask on the l10n@global.libreoffice.org mailing list about the specific case if you are in doubt.


 *  [n] , where n is a number, indicates a parameter which value will be expanded in the final string. The number must not be changed or translated.


 *  [x] , where x is a word (perhaps with a digit in the end), often indicate a parameter whose value will be expanded in the final string and whose name must not be touched or translated (e.g. [ProductName]), but sometimes it is a string that should in fact be translated (e.g. the [M] and [T] in the user interface of the auto-correct settings). Ask on the l10n@global.libreoffice.org mailing list about the specific case if you are in doubt.


 *  {xxx} , where xxx is a string, marks a part of a string which will be omitted if the [parameter] values inside them have no values at the time of display.
 * Example:

The file [2][3] is being held in use {by the following process: Name: [4], ID: [5], Window Title: [6]}. Close that application and retry.


 * In this case, if either the variables [5] or [6] has no value at the time of display, the substring "by the following process: Name: [4], ID: [5], Window Title: [6]" will be left out and not displayed. In that case the final string would not make sense, but that is a different issue. :-)

XML elements in Help files
The help files contain many XML elements in them that makes it difficult to translate for newcomers. We detail them here, so you have no questions when you do your translation. Be aware, that sometimes elements are nested in other elements. The element contains also attributes that we mention in the description of each element.

The best way to treat these elements is to copy and paste them into your translation, so you make sure that you do not forget a part of them or make a typo. Then you translate the content between the two flags, taking into account the nested elements too.

This is an element that is present in the help directory. However, the information it contains is displayed in the UI as an extended tooltip when it is activated in LibreOffice options tab. This element is  the extended tooltip . Example:

This element has two attributes that you do not have to translate:
 * hid (as in the example above)
 * visibility

This element gives an alternative text to a graphic. It is often nested into the  element, example:


 * Here you have to translate the word Icon, nothing else.
 * It also contains xml-lang=\"en-US\" for localized graphics, where you have to replace the en-US by your language's ISO code.


This element is used for the index entries of the online help. The first word is the main entry, separated by a semicolon. The second word represent the second level entry, for example:


 * Sometimes it happens that the word in the sources has a different meaning in English but not in your language, like header and title. If you find such entry like Header;Title, you can just remove it from your translation, as it will have no effect.
 * Most of the times several entries are grouped in the same paragraph.
 * There should not be two similar entries in the help directory because it will break the index display in the help UI.

This element allows to switch the content depending on the platform (Windows, Linux or Mac). The text displayed will then be different. It is often nested in or elements. Example:

and click the tab of the sheet where you want to insert the contents.
 * in this example you only have to translate the string Command between the two caseinline tags. If you use a different key than Ctrl on your keyboard in your language, you should additionally change it as well (like in German, where the keyboard key is labelled "Strg") however it belongs to the tags.
 * this element has one attribute: select as in the example above. This attribute do not have to be translated.

This element contains the default text that will be displayed, when there is a possible switch of content depending on the platform. As seen in the previous element, it is often nested with and elements. Example:


 * this element has no attribute.

This element has no content that needs localization between its tags. But it may be nested too. Example:


 * this element has one attribute: href as in the example above

This element allows to emphasize the string between its tags, so you always have to translate the content in between. Example:


 * this element has no attribute

This element is for the pictures embedded in the files. By itself, it does not contain localizable content, but other elements such as  that contains localizable strings are always nested in it. Example:

In this example, you see the element nested where Icon has to be translated.

This element has four attributes that are not to be translated:
 * id indicates the reference of the picture
 * src indicates the picture location
 * width indicates the width of the picture, the metric used can be different (cm for example) but it has no effect on the picture display
 * height indicates the height of the picture, the metric used here can also be different

This element describes a special formatting applied to the content between its tags.

Examples:

In this example, you see that the special formatting is applied to emphasize a keyboard entry.

In this more complex example, you can see that the special formatting is used to emphasize a menu entry.


 * type is the only attribute of this element. It determines the type of entry to emphasize.

This element indicates a link to another help file or to the web. Examples:

In this example, the content that will be displayed is located in the scalc/01/func_datedif.xhp. You only need to translate DATEDIF.

In this example, the content after the name attribute has also to be translated.

This element has four attributes:
 * href is the reference to the file. It has no localizable content.
 * name is a completely unused attribute. Localizing it will have no effect whatsoever.
 * target is the target when it is about a web content. It has no localizable content.
 * type is the type of content to be displayed. It has no localizable content.

As seen above with the elements   and  , this element allows to switch the content depending on the platform (Windows, Linux or Mac). It has no translatable content by itself, but always contains the latter nested elements. Example:

and click the tab of the sheet where you want to insert the contents.
 * select is its only attribute. It has no localizable content.

This element determines a content that is reused in the files. The content between its tags has to be localized. Example:

This element has two attributes:
 * id is the name of the variable and must not be translated. Its name could give indication on the type of content, unfortunately most of the time, it is in German.
 * visibility where the content has not to be translated.

Search and manage .po files
There are several operations that you can execute directly on your .po files. They are text files and some scripts such as the translate toolkit can be used to manipulate them.

As the Search field on Weblate is not very effective, using the grep command line instructions under Linux will give you much more significant results when you search for a string in multiple files. This part contains a brief description of some scripts, and examples with grep and sed commands to help you to manipulate your files.

You have first to download the files from Weblate and use the cd command to be in the directory you want to work on (ui or help).

Translate Toolkit
Most of the time the Translate Toolkit packages are available for your distro. In case it is not or it is an old version, you can get it from here. If you have any problems installing or using those scripts, do not hesitate to ask for help on the l10n mailing list.

Several scripts from the Translate Toolkit are implemented in Weblate, like the Failing Checks, which allow you to check your translation. Some, however, may be relevant for you:
 * poterminology lets you extract a terminology file from the .po/pot files. Before beginning a translation project, it is a great help to have the most important or ambiguous words filled and translated in a glossary. You will be able to upload this file under a Weblate project too. The syntax and options are explained on the site.
 * posegment will help to increase the quality of your TM by segmenting the po files based on sentence level. The syntax and options can be found on the site.
 * pocompendium let you create one big po file from a directory of po files. This is useful if you have for example have split a large file to distribute it to a team of translators. The syntax and options are explained on the site.
 * posplit let you extract three .po files respectively containing translated strings, untranslated strings and fuzzy strings. The syntax and options are explained on the site.

Using grep to find strings
The grep command is used under Linux, macOS or Unix-like systems to search through text files, or to search the given file for lines containing a match to the given strings or words. The command will display the line matching the search. grep 'word' filename.po
 * The simplest syntax is:
 * Example:

sophie@sophie:~/libo_ui-fr$ grep 'Browse' accessibility/source/helper.po
 * returns

msgid "Browse"
 * Here we are telling the grep command to find the word Browse in the helper.po file, which is in the subdirectory source of the accessibility directory.


 * This is not very useful, because you have to know the directory where the string is located, while LibreOffice has so many. So we will add an option that will look recursively into all the directories, contained in the main one. This is the -r option.
 * The syntax is:

grep -r 'word' directory


 * Example:

sophie@sophie:~/libo_ui-fr$ grep -r 'Browse' accessibility/
 * returns

accessibility/source/helper.po:msgid "Browse"
 * this looks easier! The output gives you the path to the string

grep -r -i 'word' directory
 * To force to ignore the case of the word (for example to search case-insensitive for Browse, browse or BROWSE), you will add the -i option. The syntax is:


 * Now, we want to retrieve the line number of the string in the output too. This is the -n option
 * The syntax is:

grep -r -i -n 'word' directory
 * Let me show you an example on our own directory with all the options we know:

sophie@sophie:~/libo_ui-fr$ grep -r -i -n 'Browse' accessibility/
 * the output is:

accessibility/source/helper.po:23:"RID_STR_ACC_NAME_BROWSEBUTTON\n" accessibility/source/helper.po:25:msgid "Browse"
 * You can see, that the second entry contains the word to translate.

egrep -w -r -n 'word1|word2' directory/
 * If you want your search to match only the string you have entered, you can add the -w option. For example to search for is and not retrieve this or his, etc.
 * If you want to search for several words matching only what you have entered, the syntax is:
 * Example:

sophie@sophie:~/libo_ui-fr$ egrep -w -r -n '~File|_File' sw/
 * the output is:

sw/uiconfig/swriter/ui.po:313:msgid "_File System" sw/uiconfig/swriter/ui.po:1649:msgid "_File name" sw/source/ui/frmdlg.po:563:msgid "~File name" sw/source/ui/misc.po:591:#~ msgid "~File system" sw/source/ui/dialog.po:169:msgid "~File name" sw/source/ui/index.po:522:msgid "~File"
 * Note: we use egrep to match a particular regular expression. The e is for extended grep but you can use the -E option for that as well: ''grep -E -r -n 'word1|word2' directory/

sophie@sophie:~/libo_ui-fr$ grep -r -n "l'objet" sw/ sw/source/ui/utlui.po:4106:msgstr "Cliquer sur l'objet" sw/source/ui/utlui.po:4133:msgstr "Souris sur l'objet" sw/source/ui/utlui.po:4151:msgstr "Souris quitte l'objet" sw/source/ui/utlui.po:4626:#~ msgstr "Renommer l'objet : " sw/source/core/undo.po:641:msgstr "Supprimer l'objet"
 * If you have an escaping character in your search, like an apostrophe (e.g. child's book in English or l'objet in French), the simplest way to overcome that is to enclose the word to search with double quotes instead of single ones, like in this example:


 * the usual regular expressions applied to grep (*: match zero or more of the preceding character or expression ; ^: match expression at the start of a line, as in ^A, etc.)

Using sed to modify your files
Like grep, sed is a powerful command that let you modify the content of your .po files very easily. Sed stands for Stream EDitor. For example, if you want to substitute Header by Title on a file, the syntax will be: sed 's/Header/Title/g' <file.po Sed uses regular expressions to manage the instructions, but the syntax will still remain the same as above. We will not detail all the syntax of the lines given bellow, but they are quite simple expressions you can use safely on your files.
 * first you have the name of the command s for substitute
 * then you have the original word separated by / delimiters
 * after that the word to substitute to the original
 * g is used for global and will substitute all the occurrences in the file, and not only the first occurrence of the searched word
 * then the file where the substitution takes place
 * note the presence of the single quotes too.


 * Remove comments from a file
 * Example of the file where you want to remove the # my comment comment in the utlui.po

#: 04180400.xhp
 * 1) my comment
 * 2) . dnChg
 * Enter the following in the sw/source/ui directory:

sophie@sophie:~/libo_ui-fr/sw/source/ui$ sed '/^#\ /d' utlui.po > tt
 * that will create the file "tt" in that directory, containing the strings where all the "#" at the beginning of the line (^) followed by nothing are deleted (the d in the syntax).


 * To get the tt file turn into utlui.po again:

sophie@sophi:~/libo_ui-fr/sw/source/ui$ mv tt utlui.po
 * and now it's a cleaned file!

Taking again our first example, you want to work only on a given line, 306 here: sed '306 s/Header/Title/g' <file.po so now you know how to grep first on the file to find the string and then use the sed command to correct it
 * Indicate the line of substitution

Localization
 * you will find more information on the gnu site about the delimiters, the regular expressions and syntax.