.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" 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" '' '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. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" 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 "Locale::Maketext::Fuzzy 3pm" .TH Locale::Maketext::Fuzzy 3pm "2011-12-11" "perl v5.14.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" Locale::Maketext::Fuzzy \- Maketext from already interpolated strings .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& package MyApp::L10N; \& use base \*(AqLocale::Maketext::Fuzzy\*(Aq; # instead of Locale::Maketext \& \& package MyApp::L10N::de; \& use base \*(AqMyApp::L10N\*(Aq; \& our %Lexicon = ( \& # Exact match should always be preferred if possible \& "0 camels were released." \& => "Exact match", \& \& # Fuzzy match candidate \& "[quant,_1,camel was,camels were] released." \& => "[quant,_1,Kamel wurde,Kamele wurden] freigegeben.", \& \& # This could also match fuzzily, but is less preferred \& "[_2] released[_1]" \& => "[_1][_2] ist frei[_1]", \& ); \& \& package main; \& my $lh = MyApp::L10N\->get_handle(\*(Aqde\*(Aq); \& \& # All \->maketext calls below will become \->maketext_fuzzy instead \& $lh\->override_maketext(1); \& \& # This prints "Exact match" \& print $lh\->maketext(\*(Aq0 camels were released.\*(Aq); \& \& # "1 Kamel wurde freigegeben." \-\- quant() gets 1 \& print $lh\->maketext(\*(Aq1 camel was released.\*(Aq); \& \& # "2 Kamele wurden freigegeben." \-\- quant() gets 2 \& print $lh\->maketext(\*(Aq2 camels were released.\*(Aq); \& \& # "3 Kamele wurden freigegeben." \-\- parameters are ignored \& print $lh\->maketext(\*(Aq3 released.\*(Aq); \& \& # "4 Kamele wurden freigegeben." \-\- normal usage \& print $lh\->maketext(\*(Aq[*,_1,camel was,camels were] released.\*(Aq, 4); \& \& # "!Perl ist frei!" \-\- matches the broader one \& # Note that the sequence ([_2] before [_1]) is preserved \& print $lh\->maketext(\*(AqPerl released!\*(Aq); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module is a subclass of \f(CW\*(C`Locale::Maketext\*(C'\fR, with additional support for localizing messages that already contains interpolated variables. .PP This is most useful when the messages are returned by external sources \&\*(-- for example, to match \f(CW\*(C`dir: command not found\*(C'\fR against \&\f(CW\*(C`[_1]: command not found\*(C'\fR. .PP Of course, this module is also useful if you're simply too lazy to use the .PP .Vb 1 \& $lh\->maketext("[quant,_1,file,files] deleted.", $count); .Ve .PP syntax, but wish to write .PP .Vb 1 \& $lh\->maketext_fuzzy("$count files deleted"); .Ve .PP instead, and have the correct plural form figured out automatically. .PP If \f(CW\*(C`maketext_fuzzy\*(C'\fR seems too long to type for you, this module also provides a \f(CW\*(C`override_maketext\*(C'\fR method to turn \fIall\fR \f(CW\*(C`maketext\*(C'\fR calls into \f(CW\*(C`maketext_fuzzy\*(C'\fR calls. .SH "METHODS" .IX Header "METHODS" .ie n .SS "$lh\->maketext_fuzzy(\fIkey\fP[, \fIparameters...\fP]);" .el .SS "\f(CW$lh\fP\->maketext_fuzzy(\fIkey\fP[, \fIparameters...\fP]);" .IX Subsection "$lh->maketext_fuzzy(key[, parameters...]);" That method takes exactly the same arguments as the \f(CW\*(C`maketext\*(C'\fR method of \f(CW\*(C`Locale::Maketext\*(C'\fR. .PP If \fIkey\fR is found in lexicons, it is applied in the same way as \&\f(CW\*(C`maketext\*(C'\fR. Otherwise, it looks at all lexicon entries that could possibly yield \fIkey\fR, by turning \f(CW\*(C`[...]\*(C'\fR sequences into \f(CW\*(C`(.*?)\*(C'\fR and match the resulting regular expression against \fIkey\fR. .PP Once it finds all candidate entries, the longest one replaces the \&\fIkey\fR for the real \f(CW\*(C`maketext\*(C'\fR call. Variables matched by its bracket sequences (\f(CW$1\fR, \f(CW$2\fR...) are placed before \fIparameters\fR; the order of variables in the matched entry are correctly preserved. .PP For example, if the matched entry in \f(CW%Lexicon\fR is \f(CW\*(C`Test [_1]\*(C'\fR, this call: .PP .Vb 1 \& $fh\->maketext_fuzzy("Test string", "param"); .Ve .PP is equivalent to this: .PP .Vb 1 \& $fh\->maketext("Test [_1]", "string", "param"); .Ve .PP However, most of the time you won't need to supply \fIparameters\fR to a \f(CW\*(C`maketext_fuzzy\*(C'\fR call, since all parameters are already interpolated into the string. .ie n .SS "$lh\->override_maketext([\fIflag\fP]);" .el .SS "\f(CW$lh\fP\->override_maketext([\fIflag\fP]);" .IX Subsection "$lh->override_maketext([flag]);" If \fIflag\fR is true, this accessor method turns \f(CW\*(C`$lh\->maketext\*(C'\fR into an alias for \f(CW\*(C`$lh\->maketext_fuzzy\*(C'\fR, so all consecutive \&\f(CW\*(C`maketext\*(C'\fR calls in the \f(CW$lh\fR's packages are automatically fuzzy. A false \fIflag\fR restores the original behaviour. If the flag is not specified, returns the current status of override; the default is 0 (no overriding). .PP Note that this call only modifies the symbol table of the \fIlanguage class\fR that \f(CW$lh\fR belongs to, so other languages are not affected. If you want to override all language handles in a certain application, try this: .PP .Vb 1 \& MyApp::L10N\->override_maketext(1); .Ve .SH "CAVEATS" .IX Header "CAVEATS" .IP "\(bu" 4 The \*(L"longer is better\*(R" heuristic to determine the best match is reasonably good, but could certainly be improved. .IP "\(bu" 4 Currently, \f(CW"[quant,_1,file] deleted"\fR won't match \f(CW"3 files deleted"\fR; you'll have to write \f(CW"[quant,_1,file,files] deleted"\fR instead, or simply use \f(CW"[_1] file deleted"\fR as the lexicon key and put the correct plural form handling into the corresponding value. .IP "\(bu" 4 When used in combination with \f(CW\*(C`Locale::Maketext::Lexicon\*(C'\fR's \f(CW\*(C`Tie\*(C'\fR backend, all keys would be iterated over each time a fuzzy match is performed, and may cause serious speed penalty. Patches welcome. .SH "SEE ALSO" .IX Header "SEE ALSO" Locale::Maketext, Locale::Maketext::Lexicon .SH "HISTORY" .IX Header "HISTORY" This particular module was written to facilitate an \fIauto-extraction\fR layer for Slashcode's \fITemplate Toolkit\fR provider, based on \&\f(CW\*(C`HTML::Parser\*(C'\fR and \f(CW\*(C`Template::Parser\*(C'\fR. It would work like this: .PP .Vb 2 \& Input | from the [% story.dept %] dept. \& Output| [%|loc( story.dept )%]from the [_1] dept.[%END%] .Ve .PP Now, this layer suffers from the same linguistic problems as an ordinary \f(CW\*(C`Msgcat\*(C'\fR or \f(CW\*(C`Gettext\*(C'\fR framework does \*(-- what if we want to make ordinals from \f(CW\*(C`[% story.dept %]\*(C'\fR (i.e. \f(CW\*(C`from the 3rd dept.\*(C'\fR), or expand the \f(CW\*(C`dept.\*(C'\fR to \f(CW\*(C`department\*(C'\fR / \f(CW\*(C`departments\*(C'\fR? .PP The same problem occurred in \s-1RT\s0's web interface, where it had to localize messages returned by external modules, which may already contain interpolated variables, e.g. \f(CW"Successfully deleted 7 ticket(s) in \*(Aqc:\etemp\*(Aq."\fR. .PP Since I didn't have the time to refactor \f(CW\*(C`DBI\*(C'\fR and \f(CW\*(C`DBI::SearchBuilder\*(C'\fR, I devised a \f(CW\*(C`loc_match\*(C'\fR method to pre-process their messages into one of the \fIcandidate strings\fR, then applied the matched string to \f(CW\*(C`maketext\*(C'\fR. .PP Afterwards, I realized that instead of preparing a set of candidate strings, I could actually match against the original \fIlexicon file\fR (i.e. \s-1PO\s0 files via \f(CW\*(C`Locale::Maketext::Lexicon\*(C'\fR). This is how \&\f(CW\*(C`Locale::Maketext::Fuzzy\*(C'\fR was born. .SH "AUTHORS" .IX Header "AUTHORS" Audrey Tang .SH "CC0 1.0 Universal" .IX Header "CC0 1.0 Universal" To the extent possible under law, a\*oXXe\*'\s-1XX\s0 has waived all copyright and related or neighboring rights to Locale-Maketext-Fuzzy. .PP This work is published from Taiwan. .PP