SYNOPSIS

    package MyApp::L10N;
    use base 'Locale::Maketext::Fuzzy'; # instead of Locale::Maketext

    package MyApp::L10N::de;
    use base 'MyApp::L10N';
    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('de');

    # All ->maketext calls below will become ->maketext_fuzzy instead
    $lh->override_maketext(1);

    # This prints "Exact match"
    print $lh->maketext('0 camels were released.');

    # "1 Kamel wurde freigegeben." -- quant() gets 1
    print $lh->maketext('1 camel was released.');

    # "2 Kamele wurden freigegeben." -- quant() gets 2
    print $lh->maketext('2 camels were released.');

    # "3 Kamele wurden freigegeben." -- parameters are ignored
    print $lh->maketext('3 released.');

    # "4 Kamele wurden freigegeben." -- normal usage
    print $lh->maketext('[*,_1,camel was,camels were] released.', 4);

    # "!Perl ist frei!" -- matches the broader one
    # Note that the sequence ([_2] before [_1]) is preserved
    print $lh->maketext('Perl released!');

DESCRIPTION

This module is a subclass of \*(C`Locale::Maketext\*(C', with additional support for localizing messages that already contains interpolated variables.

This is most useful when the messages are returned by external sources \*(-- for example, to match \*(C`dir: command not found\*(C' against \*(C`[_1]: command not found\*(C'.

Of course, this module is also useful if you're simply too lazy to use the

$lh->maketext("[quant,_1,file,files] deleted.", $count);

syntax, but wish to write

$lh->maketext_fuzzy("$count files deleted");

instead, and have the correct plural form figured out automatically.

If \*(C`maketext_fuzzy\*(C' seems too long to type for you, this module also provides a \*(C`override_maketext\*(C' method to turn all \*(C`maketext\*(C' calls into \*(C`maketext_fuzzy\*(C' calls.

METHODS

That method takes exactly the same arguments as the \*(C`maketext\*(C' method of \*(C`Locale::Maketext\*(C'.

If key is found in lexicons, it is applied in the same way as \*(C`maketext\*(C'. Otherwise, it looks at all lexicon entries that could possibly yield key, by turning \*(C`[...]\*(C' sequences into \*(C`(.*?)\*(C' and match the resulting regular expression against key.

Once it finds all candidate entries, the longest one replaces the key for the real \*(C`maketext\*(C' call. Variables matched by its bracket sequences ($1, $2...) are placed before parameters; the order of variables in the matched entry are correctly preserved.

For example, if the matched entry in %Lexicon is \*(C`Test [_1]\*(C', this call:

$fh->maketext_fuzzy("Test string", "param");

is equivalent to this:

$fh->maketext("Test [_1]", "string", "param");

However, most of the time you won't need to supply parameters to a \*(C`maketext_fuzzy\*(C' call, since all parameters are already interpolated into the string. If flag is true, this accessor method turns \*(C`$lh->maketext\*(C' into an alias for \*(C`$lh->maketext_fuzzy\*(C', so all consecutive \*(C`maketext\*(C' calls in the $lh's packages are automatically fuzzy. A false flag restores the original behaviour. If the flag is not specified, returns the current status of override; the default is 0 (no overriding).

Note that this call only modifies the symbol table of the language class that $lh belongs to, so other languages are not affected. If you want to override all language handles in a certain application, try this:

MyApp::L10N->override_maketext(1);

CAVEATS

  • The \*(L"longer is better\*(R" heuristic to determine the best match is reasonably good, but could certainly be improved.

  • Currently, "[quant,_1,file] deleted" won't match "3 files deleted"; you'll have to write "[quant,_1,file,files] deleted" instead, or simply use "[_1] file deleted" as the lexicon key and put the correct plural form handling into the corresponding value.

  • When used in combination with \*(C`Locale::Maketext::Lexicon\*(C''s \*(C`Tie\*(C' backend, all keys would be iterated over each time a fuzzy match is performed, and may cause serious speed penalty. Patches welcome.

RELATED TO Locale::Maketext::Fuzzy…

Locale::Maketext, Locale::Maketext::Lexicon

HISTORY

This particular module was written to facilitate an auto-extraction layer for Slashcode's Template Toolkit provider, based on \*(C`HTML::Parser\*(C' and \*(C`Template::Parser\*(C'. It would work like this:

Input | <B>from the [% story.dept %] dept.</B> Output| <B>[%|loc( story.dept )%]from the [_1] dept.[%END%]</B>

Now, this layer suffers from the same linguistic problems as an ordinary \*(C`Msgcat\*(C' or \*(C`Gettext\*(C' framework does \*(-- what if we want to make ordinals from \*(C`[% story.dept %]\*(C' (i.e. \*(C`from the 3rd dept.\*(C'), or expand the \*(C`dept.\*(C' to \*(C`department\*(C' / \*(C`departments\*(C'?

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. "Successfully deleted 7 ticket(s) in 'c:\temp'.".

Since I didn't have the time to refactor \*(C`DBI\*(C' and \*(C`DBI::SearchBuilder\*(C', I devised a \*(C`loc_match\*(C' method to pre-process their messages into one of the candidate strings, then applied the matched string to \*(C`maketext\*(C'.

Afterwards, I realized that instead of preparing a set of candidate strings, I could actually match against the original lexicon file (i.e. \s-1PO\s0 files via \*(C`Locale::Maketext::Lexicon\*(C'). This is how \*(C`Locale::Maketext::Fuzzy\*(C' was born.

AUTHORS

Audrey Tang <[email protected]>

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.

This work is published from Taiwan.

<http://creativecommons.org/publicdomain/zero/1.0>