.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Log::Report::Translator::Context 3pm" .TH Log::Report::Translator::Context 3pm "2014-06-22" "perl v5.18.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Log::Report::Translator::Context \- handle translation contexts .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& # usually, the context information is in a separate file \& textdomain \*(Aqmy\-domain\*(Aq \& , config => $filename; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" [Added in Log::Report v1.00] The \*(L"contexts\*(R" concept in (\s-1GNU\s0's version of) \f(CW\*(C`gettext\*(C'\fR, has a very restricted purpose: to separate two (accidental) uses of the same message-id, under different circumstances. The same msgid may translated diffently in one file or the other. The name \*(L"context\*(R" is pretending much more power than the gettext libraries are capable of: it only behaves like a namespace. .PP For Log::Report, the power of \*(L"context\*(R" is extended with selecting between alternatives for the use of a msgid \fBon the same spot\fR. For instance, the gender of the user of the website determines whether `he' or `she' needs to be used in the translation. In this example, the gender is set as context keyword in the message: .PP .Vb 3 \& my ($name, $gender) = (\*(AqJack\*(Aq, \*(Aqmale\*(Aq); \& print _\|_x"{name $name \& , _context => $gender; .Ve .SH "METHODS" .IX Header "METHODS" .SS "Constructors" .IX Subsection "Constructors" .IP "Log::Report::Translator::Context\->\fBnew\fR(%options)" 4 .IX Item "Log::Report::Translator::Context->new(%options)" .Vb 2 \& \-Option\-\-Default \& rules {} .Ve .RS 4 .IP "rules => \s-1HASH\s0" 2 .IX Item "rules => HASH" .RE .RS 4 .RE .SS "Attributes" .IX Subsection "Attributes" .PD 0 .ie n .IP "$obj\->\fBrules\fR()" 4 .el .IP "\f(CW$obj\fR\->\fBrules\fR()" 4 .IX Item "$obj->rules()" .PD Returns a \s-1HASH\s0 to the simplified context maps. .SS "Action" .IX Subsection "Action" .ie n .IP "$obj\->\fBctxtFor\fR( $message, $lang, [$context] )" 4 .el .IP "\f(CW$obj\fR\->\fBctxtFor\fR( \f(CW$message\fR, \f(CW$lang\fR, [$context] )" 4 .IX Item "$obj->ctxtFor( $message, $lang, [$context] )" Returns a pair of the \s-1MSGID\s0 stripped from context markup, and the context evaluated into the msgctxt string. The \f(CW$message\fR is a Log::Report::Message object. The \f(CW$context\fR is the default context for a certain textdomain. .Sp .Vb 1 \& my ($msgid, $msgctxt) = $context\->ctxtFor($msg, $lang, $context); .Ve .ie n .IP "$obj\->\fBexpand\fR($msgid, $language, %options)" 4 .el .IP "\f(CW$obj\fR\->\fBexpand\fR($msgid, \f(CW$language\fR, \f(CW%options\fR)" 4 .IX Item "$obj->expand($msgid, $language, %options)" Expand the context settings into all possible combinations which need translations in the \s-1PO\s0 file. This may depend on the \f(CW$language\fR. The \f(CW$msgid\fR is used in error messages. .ie n .IP "$obj\->\fBneedDecode\fR($source, STRING|ARRAY|HASH|LIST)" 4 .el .IP "\f(CW$obj\fR\->\fBneedDecode\fR($source, STRING|ARRAY|HASH|LIST)" 4 .IX Item "$obj->needDecode($source, STRING|ARRAY|HASH|LIST)" .PD 0 .IP "Log::Report::Translator::Context\->\fBneedDecode\fR($source, STRING|ARRAY|HASH|LIST)" 4 .IX Item "Log::Report::Translator::Context->needDecode($source, STRING|ARRAY|HASH|LIST)" .PD Converts the context settings passed with the \s-1MSGID,\s0 into a \s-1HASH\s0 which will be matched to the context providers. .SH "DETAILS" .IX Header "DETAILS" .SS "Using context_rules" .IX Subsection "Using context_rules" In Log::Report's extended concept of \*(L"contexts\*(R", you can select between multiple translations for the same msgid, when they .IP "\(bu" 4 appear with different purpose (like gnu's concept of contexts) .IP "\(bu" 4 need alternative translation sets \fBon the same spot\fR .PP In the standard gettext set-up, some msgid may accidentally collide between two different uses. For instance, whether you translate the word \&\*(L"Open\*(R" in the menu for \*(L"Files\*(R" to mean \*(L"open a file\*(R", and the word \*(L"Open\*(R" in the status display meaning \*(L"the file is open\*(R". In some languages, these translations may differ. Using a msgctxt keyword will cause the same msgid to appear twice in the PO-file. .PP But, there is a much broader need for context sensitive translations, which is not in the provided by standard gettext: environmental information or parameters may influence the translation more than simply solvable by inserted parameters. .PP For instance, the gender of the user of the website determines whether `he' or `she' needs to be used. In this example, the gender is set as context keyword in the message: .PP .Vb 2 \& $name = \*(AqJack\*(Aq; \& print _\|_x"{name} found her key", name => $name; .Ve .PP You may try to solve this via: .PP .Vb 3 \& my ($name, $gender) = (\*(AqJack\*(Aq, \*(Aqmale\*(Aq); \& print _\|_x"{name} found {personal} key", name => $name \& , personal => ($gender eq \*(Aqmale\*(Aq ? \*(Aqhis\*(Aq : \*(Aqher\*(Aq); # No! .Ve .PP This does not translate! For one, you would need to translate \f(CW\*(C`his\*(C'\fR and \&\f(CW\*(C`her\*(C'\fR to the language as well. But in some languages, the differences between addressed genders have more impact on the whole sentence. .PP So, Log::Report translations add extra syntax: .PP .Vb 3 \& my ($name, $gender) = (\*(AqJack\*(Aq, \*(Aqmale\*(Aq); \& print _\|_x"{name $name \& , _context => "gender=$gender"; .Ve .PP The \f(CW\*(C`gender\*(C'\fR marking tells the translation table builder (xgettext-perl) and the translation handler that there is a context active. .PP Now, the English PO-file has .PP .Vb 1 \& # gender alternatives \*(Aqmale\*(Aq and \*(Aqfemale\*(Aq \& \& msgctxt "gender=male" \& msgid "{name} found his key" \& msgstr "{name} found his key" \& \& msgctxt "gender=female" \& msgid "{name} found his key" \& msgstr "{name} found her key" .Ve .PP To make this work, both the application and the \f(CW\*(C`xgettext\-perl\*(C'\fR script must share information to understand which genders are available. See the section on \*(L"Configuration\*(R" below. .PP Another example: .PP .Vb 2 \& print _\|_x"greetings{ \*(Aqgender=male\*(Aq \& _context => \*(Aqgender=male,agegroup=adult,married=yes\*(Aq \& _context => [ \*(Aqgender=male\*(Aq, \*(Aqagegroup=adult\*(Aq, \*(Aqmarried=yes\*(Aq] \& _context => [ qw/gender=male agegroup=adult married=yes/ ] \& \& my @context = (qw/gender=male agegroup=adult married=yes/); \& _context => \e@context; .Ve .PP Probably the my \f(CW%context\fR = (gender => 'male', agegroup => 'adult', married => 'yes'); my \f(CW%context\fR = qw/gender male agegroup adult married yes/; _context => \e%context; .PP Standard gettext only allows a single keyword (=string) \&\f(CW\*(C`Log::Report\*(C'\fR permits you to set-up a context for a whole text-domain, which means that multiple context rules may be active at any moment. .PP \fISpecifying the context per Domain\fR .IX Subsection "Specifying the context per Domain" .PP Above examples are to be specified per message. You may also set a default. The top of your modules set the text-domain (name of the translation table) for all strings found in those files. In this case, for instance \*(L"webpages\*(R" .PP .Vb 2 \& # Log::Report::textdomain() \& (textdomain \*(Aqwebpages\*(Aq)\->setContext(%context); .Ve .PP This context is used as defaults, the \f(CW\*(C`_context\*(C'\fR attribute used by strings are overruling these. .PP \fIThe msgctxt\fR .IX Subsection "The msgctxt" .PP The gnutext implementation of the context is very simple. This is to be expected from a library written in C. The msgctxt alternatives are matched against the context keywords of the message. In all or none of the alternatives match, then just a random translation is chosen. .PP In the simplest form, the msgctxt field contains a single keyword (not containing a comma). .PP .Vb 1 \& msgctxt "gender=male" .Ve .PP But you can do more. \fBBe warned\fR that most (all?) existing tools which smartly edit PO-files do not understand these constructs: they see the msgctxt as dump string without meaning. .PP .Vb 2 \& msgctxt "agegroup=baby,agegroup=grandparent" # baby OR grandparent \& msgctxt "gender=male agegroup=adult" # both male AND adult .Ve .PP So, a comma separated list of alternatives. If any matches, then the rule is selected. .PP \fIConfiguration\fR .IX Subsection "Configuration" .PP The tools which handle translations expect the msgctxt to be static. For instance, contain a filename where the string is used to disambigue accidental collissions of the use of the same msgid for different purposes. .PP Now, we have designed far more flexible contexts. We need to generate all possible msgctxt values while extracting msgids to update the PO-files. Therefore, we need a map-file. .PP The context maps are included in a configuration file which is passed to xgettext-perl and to the program which uses contexts. See \fILog::Report::Domain::readConfig()\fR. .PP Example of such configuration file: (\s-1JSON\s0 syntax and Perl syntax) .PP .Vb 9 \& === JSON === ==== Perl === \& { { \& "context_rules" : { context_rules => { \& "gender" : [ gender => [ \& "male", \*(Aqmale\*(Aq, \& "female" \*(Aqfemale\*(Aq \& ] ] \& } } \& } } .Ve .PP or .PP .Vb 12 \& { { \& "context_rules" : { context_rules => { \& "gender" : { gender => { \& "alternatives" : [ alternatives => [ \& "male", \*(Aqmale\*(Aq, \& "female", \*(Aqfemale\*(Aq, \& "unknown" \*(Aqunknown\*(Aq \& ] ] \& ... more config for \*(Aqgender\*(Aq ... \& } } \& } } \& } } .Ve .PP As \*(L"alternatives\*(R", we list the alternatives as known by the application internals. Each msgid which contains a \f(CW\*(C`{ \& "context_rules" : { { gender => \& "gender" : { { default => { qw/ \& "default" : { female female \& "female" : "female", male male \& "male" : "male" unknown male / } \& "unknown" : "male", , \*(Aqnl,de\*(Aq => { qw/ \& }, unknown x / } \& "nl,de" : { \& "unknown" : "x" \& } } \& ... more configuration ... \& } \& ... more context rules ... \& } } \& } } .Ve .PP By default, there will only be two msgid copies in a language file, because at run-time the \*(L"unknown\*(R" is mapped on \*(L"male\*(R". An exception for the Dutch (nl*) and German (de*) tables, which apparently support the third gender. .PP If you are not interested for a certain tag, then put it on '\s-1IGNORE\s0' as default or for your language. .PP .Vb 2 \& "default" : "IGNORE", default => \*(AqIGNORE\*(Aq \& "nl": "IGNORE" nl => \*(AqIGNORE\*(Aq .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" This module is part of Log-Report-Lexicon distribution version 1.03, built on June 04, 2014. Website: \fIhttp://perl.overmeer.net/log\-report/\fR .SH "LICENSE" .IX Header "LICENSE" Copyrights 2007\-2014 by [Mark Overmeer]. For other contributors see ChangeLog. .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See \fIhttp://www.perl.com/perl/misc/Artistic.html\fR