403Webshell
Server IP : 103.119.228.120  /  Your IP : 18.218.95.236
Web Server : Apache
System : Linux v8.techscape8.com 3.10.0-1160.119.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Jul 15 12:09:18 UTC 2024 x86_64
User : nobody ( 99)
PHP Version : 5.6.40
Disable Function : shell_exec,symlink,system,exec,proc_get_status,proc_nice,proc_terminate,define_syslog_variables,syslog,openlog,closelog,escapeshellcmd,passthru,ocinum cols,ini_alter,leak,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dl,dll,myshellexec,proc_open,socket_bind,proc_close,escapeshellarg,parse_ini_filepopen,fpassthru,exec,passthru,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter,popen,show_source,proc_nice,proc_terminate,proc_get_status,proc_close,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,dl,symlink,shell_exec,system,dl,passthru,escapeshellarg,escapeshellcmd,myshellexec,c99_buff_prepare,c99_sess_put,fpassthru,getdisfunc,fx29exec,fx29exec2,is_windows,disp_freespace,fx29sh_getupdate,fx29_buff_prepare,fx29_sess_put,fx29shexit,fx29fsearch,fx29ftpbrutecheck,fx29sh_tools,fx29sh_about,milw0rm,imagez,sh_name,myshellexec,checkproxyhost,dosyayicek,c99_buff_prepare,c99_sess_put,c99getsource,c99sh_getupdate,c99fsearch,c99shexit,view_perms,posix_getpwuid,posix_getgrgid,posix_kill,parse_perms,parsesort,view_perms_color,set_encoder_input,ls_setcheckboxall,ls_reverse_all,rsg_read,rsg_glob,selfURL,dispsecinfo,unix2DosTime,addFile,system,get_users,view_size,DirFiles,DirFilesWide,DirPrintHTMLHeaders,GetFilesTotal,GetTitles,GetTimeTotal,GetMatchesCount,GetFileMatchesCount,GetResultFiles,fs_copy_dir,fs_copy_obj,fs_move_dir,fs_move_obj,fs_rmdir,SearchText,getmicrotime
MySQL : ON |  cURL : ON |  WGET : ON |  Perl : ON |  Python : ON |  Sudo : ON |  Pkexec : ON
Directory :  /usr/local/share/man/man3/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /usr/local/share/man/man3/Locale::Maketext::Utils.3pm
.\" 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
.\" ========================================================================
.\"
.IX Title "Locale::Maketext::Utils 3"
.TH Locale::Maketext::Utils 3 "2014-11-18" "perl v5.16.3" "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::Utils \- Adds some utility functionality and failure handling to Local::Maketext handles
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
In MyApp/Localize.pm:
.PP
.Vb 3
\&    package MyApp::Localize;
\&    use Locale::Maketext::Utils; 
\&    use base \*(AqLocale::Maketext::Utils\*(Aq; 
\&  
\&    our $Encoding = \*(Aqutf\-8\*(Aq; # see below
\&    
\&    # no _AUTO
\&    our %Lexicon = (...
.Ve
.PP
Make all the language Lexicons you want. (no _AUTO)
.PP
Then in your script:
.PP
.Vb 1
\&   my $lang = MyApp::Localize\->get_handle(\*(Aqfr\*(Aq);
.Ve
.PP
Now \f(CW$lang\fR behaves like a normal Locale::Maketext handle object but there are some new features, methods, and failure handling which are described below.
.ie n .SH "our $Encoding"
.el .SH "our \f(CW$Encoding\fP"
.IX Header "our $Encoding"
If you set your class's \f(CW$Encoding\fR variable the object's encoding will be set to that.
.PP
.Vb 1
\&   my $enc = $lh\->encoding();
.Ve
.PP
\&\f(CW$enc\fR is \f(CW$MyApp::Localize::fr::Encoding\fR || \f(CW$MyApp::Localize::Encoding\fR || \fIencoding()\fR's default
.SH "Argument based singleton"
.IX Header "Argument based singleton"
The \fIget_handle()\fR method returns an argument based singleton. That means the overhead of initializing an object and compiling parts of the lexicon being used only happen once even if \fIget_handle()\fR is called several times with the same arguments.
.ie n .SH "Lexicon hashes that are ""read only"""
.el .SH "Lexicon hashes that are ``read only''"
.IX Header "Lexicon hashes that are read only"
Sometimes you want your lexicon to be a tied hash that is read only which would be fatal when storing a compiled key's value (e.g. GDBM_File).
.PP
To faciltate that (without needing other special \fItie()\fRs as per \*(L"Tie::Hash::ReadonlyStack compat Lexicon\*(R") you can simply \fIinit()\fR your handle with:
.PP
.Vb 1
\&  $lh\->{\*(Aquse_external_lex_cache\*(Aq} = 1;
.Ve
.PP
That will cause all compiled strings to be stored in the object instead of back in the lexicon.
.SH "Aliasing"
.IX Header "Aliasing"
In your package you can create an alias with this:
.PP
.Vb 3
\&   _\|_PACKAGE_\|_\->make_alias($langs, 1);
\&   or
\&   MyApp::Localize\->make_alias([qw(en en_us i_default)], 1);
\&   
\&   _\|_PACKAGE_\|_\->make_alias($langs);
\&   or
\&   MyApp::Localize::fr\->make_alias(\*(Aqfr_ca\*(Aq);
.Ve
.PP
Where \f(CW$langs\fR is a string or a reference to an array of strings that are the aliased language tags.
.PP
You must set the second argument to true if _\|_PACKAGE_\|_ is the base class.
.PP
The reason is there is no way to tell if the pakage name is the base class or not.
.PP
This needs done before you call \fIget_handle()\fR or it will have no effect on your object really.
.PP
Ideally you'd put all calls to this in the main lexicon to ensure it will apply to any \fIget_handle()\fR calls.
.PP
Alternatively, and at times more ideally, you can keep each module's aliases in them and then when setting your obj require the module first.
.SH "METHODS"
.IX Header "METHODS"
.SS "Deprecated for clarity:"
.IX Subsection "Deprecated for clarity:"
These are deprecated because they are ambiguous names (i.e. used in other places by other things) and thus problematic when harvesting phrases.
.PP
\fI\f(CI$lh\fI\->print($key, \f(CI@args\fI);\fR
.IX Subsection "$lh->print($key, @args);"
.PP
Shortcut for
.PP
.Vb 1
\&    print $lh\->maketext($key, @args);
.Ve
.PP
\fI\f(CI$lh\fI\->fetch($key, \f(CI@args\fI);\fR
.IX Subsection "$lh->fetch($key, @args);"
.PP
Alias for
.PP
.Vb 1
\&    $lh\->maketext($key, @args);
.Ve
.PP
\fI\f(CI$lh\fI\->say($key, \f(CI@args\fI);\fR
.IX Subsection "$lh->say($key, @args);"
.PP
Like \f(CW$lh\fR\->print($key, \f(CW@args\fR); except appends $/ || \en
.PP
\fI\f(CI$lh\fI\->get($key, \f(CI@args\fI);\fR
.IX Subsection "$lh->get($key, @args);"
.PP
Like \f(CW$lh\fR\->fetch($key, \f(CW@args\fR); except appends $/ || \en
.ie n .SS "$lh\->\fIget_base_class()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_base_class()\fP"
.IX Subsection "$lh->get_base_class()"
Returns the base class of the object. So if \f(CW$lh\fR is a MyApp::Localize::fr object then it returns MyApp::Localize
.ie n .SS "$lh\->\fIget_language_class()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_language_class()\fP"
.IX Subsection "$lh->get_language_class()"
Returns the language class of the object. So if \f(CW$lh\fR is a MyApp::Localize::fr object then it returns MyApp::Localize::fr
.ie n .SS "$lh\->\fIget_language_tag()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_language_tag()\fP"
.IX Subsection "$lh->get_language_tag()"
Returns the real language name space being used, not \fIlanguage_tag()\fR's \*(L"cleaned up\*(R" one
.ie n .SS "$lh\->langtag_is_loadable($lang_tag)"
.el .SS "\f(CW$lh\fP\->langtag_is_loadable($lang_tag)"
.IX Subsection "$lh->langtag_is_loadable($lang_tag)"
Returns 0 if the argument is not a language that can be used to get a handle.
.PP
Returns the language handle if it is a language that can be used to get a handle.
.ie n .SS "$lh\->\fIlang_names_hashref()\fP"
.el .SS "\f(CW$lh\fP\->\fIlang_names_hashref()\fP"
.IX Subsection "$lh->lang_names_hashref()"
This returns a hashref whose keys are the language tags and the values are the 
name of language tag in \f(CW$lh\fR's native langauge.
.PP
It can be called several ways:
.IP "\(bu" 4
Give it a list of tags to lookup
.Sp
.Vb 1
\&    $lh\->lang_names_hashref(@lang_tags)
.Ve
.IP "\(bu" 4
Have it search \f(CW@INC\fR for Base/Class/*.pm's
.Sp
.Vb 1
\&    $lh\->lang_names_hashref() # IE no args
.Ve
.IP "\(bu" 4
Have it search specific places for Base/Class/*.pm's
.Sp
.Vb 2
\&    local $lh\->{\*(Aq_lang_pm_search_paths\*(Aq} = \e@lang_paths; # array ref of directories
\&    $lh\->lang_names_hashref() # IE no args
.Ve
.PP
The module it uses for lookup (Locales::Language) is only required when this method is called. Make sure you have the latest verison of Locales as 0.04 (i.e. Locales::Base 0.03) is buggy!
.PP
The module it uses for lookup (Locales::Language) is currently limited to two character codes but we try to handle it gracefully here.
.PP
In array context it will build and return an additional hashref with the same keys whose values are the language name in the langueage itself.
.PP
Does not ensure that the tags are loadable, to do that see below.
.ie n .SS "$lh\->\fIloadable_lang_names_hashref()\fP"
.el .SS "\f(CW$lh\fP\->\fIloadable_lang_names_hashref()\fP"
.IX Subsection "$lh->loadable_lang_names_hashref()"
Exactly the same as \f(CW$lh\fR\->\fIlang_names_hashref()\fR (because it calls that method...) except it only contains tags that are loadable.
.PP
Has additional overhead of calling \f(CW$lh\fR\->\fIlangtag_is_loadable()\fR on each key. So most likely you'd use this on a single specific place (a page to choose their language setting for instance) instead of calling it on every instance your script is run.
.ie n .SS "$lh\->append_to_lexicons( $lexicons_hashref );"
.el .SS "\f(CW$lh\fP\->append_to_lexicons( \f(CW$lexicons_hashref\fP );"
.IX Subsection "$lh->append_to_lexicons( $lexicons_hashref );"
This method allows modules or script to append to the object's Lexicons. Consider using \*(L"Tie::Hash::ReadonlyStack compat Lexicon\*(R" instead.
.PP
Each key is the language tag whose Lexicon you will prepend its value, a hashref, to.
.PP
So assuming the key is 'fr', then this is the lexicon that gets appended to:
.PP
_\|_PACKAGE_\|_::fr::Lexicon
.PP
The only exception is if the key is '_'. In that case the main package's Lexicon is appended to:
.PP
_\|_PACKAGE_\|_::Lexicon
.PP
.Vb 8
\&    $lh\->append_to_lexicons({
\&        \*(Aq_\*(Aq => {
\&            \*(AqHello World\*(Aq => \*(AqHello World\*(Aq,
\&        },
\&        \*(Aqfr\*(Aq => {
\&            \*(AqHello World\*(Aq => \*(AqBonjour Monde\*(Aq,
\&        }, 
\&    });
.Ve
.ie n .SS "$lh\->remove_key_from_lexicons($key)"
.el .SS "\f(CW$lh\fP\->remove_key_from_lexicons($key)"
.IX Subsection "$lh->remove_key_from_lexicons($key)"
Removes \f(CW$key\fR from every lexicon. Consider using \*(L"Tie::Hash::ReadonlyStack compat Lexicon\*(R" instead.
.PP
What is removed is stored in \f(CW$lh\fR\->{'_removed_from_lexicons'}
.PP
If defined, \f(CW$lh\fR\->{'_removed_from_lexicons'} is a hashref whose keys are the index number of the \f(CW$lh\fR\->\fI_lex_refs()\fR arrayref.
.PP
The value is the key and the value that that lexicon had.
.PP
This is used internally to remove _AUTO keys so that the failure handler below will get used
.ie n .SS "$lh\->\fIget_locales_obj()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_locales_obj()\fP"
.IX Subsection "$lh->get_locales_obj()"
Return a Locales object suitable for the object (or the optional locale tag argument).
.PP
If the locale tag can not be loaded it tries the super (if any) then \f(CW$lh\fR\->{'fallback_locale} (if set) and its super (if any) before defaulting to 'en'.
.PP
Locales is where all the \s-1CLDR\s0 data and logic comes from.
.ie n .SS "$lh\->\fIget_language_tag_name()\fP;"
.el .SS "\f(CW$lh\fP\->\fIget_language_tag_name()\fP;"
.IX Subsection "$lh->get_language_tag_name();"
Takes 2 optional arguments:
.IP "1. A locale tag whose name you want (defaults to the object's locale)." 4
.IX Item "1. A locale tag whose name you want (defaults to the object's locale)."
.PD 0
.IP "2. A locale tag whose language you want the name to be in (defaults to the object's locale)." 4
.IX Item "2. A locale tag whose language you want the name to be in (defaults to the object's locale)."
.PD
.PP
These names are defined by the \s-1CLDR.\s0
.ie n .SS "$lh\->\fIget_html_dir_attr()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_html_dir_attr()\fP"
.IX Subsection "$lh->get_html_dir_attr()"
With no argument, returns the object locale’s character orientation as a string suitable for HTML’s dir attribute.
.PP
Given a \s-1CLDR\s0 character orientation string it will return a string suitable for HTML’s dir attribute.
.PP
Given a locale tag and second argument of true (specifying that the first argument is a tag not a \s-1CLDR\s0 character orientation string ) it returns that locale’s character orientation as a string suitable for HTML’s dir attribute.
.PP
The character orientation comes from \s-1CLDR.\s0
.ie n .SS "$lh\->\fIget_locale_display_pattern()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_locale_display_pattern()\fP"
.IX Subsection "$lh->get_locale_display_pattern()"
Returns the locale display pattern for the object or the tag given as the ofrst optional argument.
.PP
The pattern comes from the \s-1CLDR.\s0
.ie n .SS "$lh\->\fIget_language_tag_character_orientation()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_language_tag_character_orientation()\fP"
.IX Subsection "$lh->get_language_tag_character_orientation()"
Returns the character orientation string for the object or the tag given as the first optional argument.
.PP
The string comes from the \s-1CLDR.\s0
.ie n .SS "$lh\->lextext('Your key here.')"
.el .SS "\f(CW$lh\fP\->lextext('Your key here.')"
.IX Subsection "$lh->lextext('Your key here.')"
Get the lexicon’s text of 'Your key here.' without compiling it (in other words all bracket notation is still in tact).
.PP
The results are suitable for the first arg to \fImakethis()\fR.
.PP
\fI\f(CI$lh\fI\->text('Your key here.')–deprecated for clarity\fR
.IX Subsection "$lh->text('Your key here.')–deprecated for clarity"
.PP
Deprecated name of \f(CW$lh\fR\->\fIlextext()\fR.
.PP
It is deprecated because it is an ambiguous name (i.e. used in other places by other things) and thus problematic when harvesting phrases.
.ie n .SS "$lh\->\fImakethis()\fP"
.el .SS "\f(CW$lh\fP\->\fImakethis()\fP"
.IX Subsection "$lh->makethis()"
Like \fImaketext()\fR but does not lookup the phrase in the lexicon and compiles the phrase exactly as given.
.ie n .SS "$lh\->\fImakethis_base()\fP"
.el .SS "\f(CW$lh\fP\->\fImakethis_base()\fP"
.IX Subsection "$lh->makethis_base()"
Like \fImakethis()\fR but uses the base class as the phrase compiler instead of the object.
.PP
This is usful in testing when you want consistent semantics on arbitrary objects.
.ie n .SS "$lh\->\fImakevar()\fP"
.el .SS "\f(CW$lh\fP\->\fImakevar()\fP"
.IX Subsection "$lh->makevar()"
This is an alias to \fImaketext()\fR. Its sole purpose is to be used to semantically indicate that the source code does not contain a translatable string in the call to \fImaketext()\fR.
.PP
For example:
.PP
.Vb 1
\&    $lh\->maketext(\*(AqHello World\*(Aq)
.Ve
.PP
It is easy to tell that we need to provide translations for 'Hello World'. But given:
.PP
.Vb 1
\&    $lh\->maketext($api_rv\->{\*(Aqstring\*(Aq})
.Ve
.PP
It is not easy to determine what \f(CW$api_rv\fR\->{'string'} is in order to pass it on to the translation team.
.PP
However if we do that like this:
.PP
.Vb 3
\&     my $string = translatable(\*(AqHello World\*(Aq); # See Locale::Maketext::Utils::MarkPhrase
\&     …
\&     $lh\->makevar($api_rv\->{\*(Aqstring\*(Aq})
.Ve
.PP
Then the parser can simply ignore the call to \fImakevar()\fR and find the value it is interested in via \fItranslatable()\fR
.PP
Additionally, since \fImakevar()\fR is meant to work with variables it also has the distinction of taking an array ref, as its only arg, that contains the arguments you’d normally pass to make*().
.PP
This makes it easier/possible to do something like this:
.PP
.Vb 1
\&    $locale\->makevar(@mystuff)
.Ve
.PP
in, say, Template Toolkit syntax.
.PP
For example, if 'api_mt_result' is [ 'You have [quant,_1,user,users].', 42 ] you could do:
.PP
.Vb 1
\&    [% locale.makevar(api_mt_result) %]
.Ve
.PP
instead of something hacky and convoluted like:
.PP
.Vb 3
\&    [%\- SET item_list = [] \-%]
\&    [%\- FOREACH i IN api_mt_result; item_list.push(i.json); END \-%]
\&    [% \*(Aq\e[% locale.makevar(\*(Aq _ item_list.join(", ") _ \*(Aq) %\e]\*(Aq | evaltt %]
.Ve
.ie n .SS "$lh\->\fIget_asset()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_asset()\fP"
.IX Subsection "$lh->get_asset()"
Helps you find an asset for a locale based on the locale's fallback.
.PP
Takes a code ref and an optional locale tag (default to the object's locale).
.PP
The code ref is passed a locale tag (from the list of the locale's fallbacks).
.PP
The first tag that returns a defined value halts the loop and that value is returned.
.PP
.Vb 5
\&    my $foo = $lh\->get_asset(sub {
\&        my ($tag) = @_;
\&        return "foo+$tag" if Foo\->has_locale($tag);
\&        return;
\&    });
.Ve
.ie n .SS "$lh\->\fIget_asset_file()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_asset_file()\fP"
.IX Subsection "$lh->get_asset_file()"
Takes a path to look for with \f(CW%s\fR where the locale tag should be. The first locale (in the object's locale's fallback list) whose path passes \-f gets the path returned. Does a return; if none are found.
.PP
.Vb 1
\&    my $template = $lh\->get_asset_file(\*(Aq…/.locale/%s.tt\*(Aq); # …/.locale/fr.tt
.Ve
.PP
The optional second argument is a string to return when the path passes \-f.
.PP
.Vb 1
\&    my $js = $lh\->get_asset_file(\*(Aq…/.locale/%s.css\*(Aq,\*(Aqhttp://example.com/locale_css/%s.css\*(Aq); # http://example.com/locale_css/fr.css
.Ve
.ie n .SS "$lh\->\fIget_asset_dir()\fP"
.el .SS "\f(CW$lh\fP\->\fIget_asset_dir()\fP"
.IX Subsection "$lh->get_asset_dir()"
Same as \fIget_asset_file()\fR but the path must pass \-d.
.ie n .SS "$lh\->\fIdelete_cache()\fP"
.el .SS "\f(CW$lh\fP\->\fIdelete_cache()\fP"
.IX Subsection "$lh->delete_cache()"
Delete the internal cache. Returns the hashref that was removed.
.PP
You can pass it a key and only that is removed (i.e. instead of the entire cache).
.PP
.Vb 1
\&    my $get_asset_file_cache = $lh\->delete_cache(\*(Aqget_asset_file\*(Aq);  # only delete the cached data for get_asset_file()
\&    
\&    my $entire_cache = $lh\->delete_cache();# delete the entire cache
.Ve
.PP
Currently this applies to 'get_asset_file', 'get_asset_dir', 'makethis', and 'makethis_base'.
.SH "Automatically _AUTO'd Failure Handling with hooks"
.IX Header "Automatically _AUTO'd Failure Handling with hooks"
This module sets \fIfail_with()\fR so that failure is handled for every Lexicon you define as if _AUTO was set and in addition you can use the hooks below.
.PP
This functionality is turned off if:
.IP "\(bu" 4
_AUTO is set on the Lexicon (and it was not removed internally for some strange reason)
.IP "\(bu" 4
you've changed the failure function with \f(CW$lh\fR\->\fIfail_with()\fR (If you do change it be sure to restore your _AUTO's inside \f(CW$lh\fR\->{'_removed_from_lexicons'})
.PP
The result is that a key is looked for in the handle's Lexicon, then the default Lexicon, then the handlers below, and finally the key itself (Again, as if _AUTO had been set on the Lexicon).
I find this extremely useful and hope you do as well :)
.ie n .SS "$lh\->{'_get_key_from_lookup'}"
.el .SS "\f(CW$lh\fP\->{'_get_key_from_lookup'}"
.IX Subsection "$lh->{'_get_key_from_lookup'}"
If lookup fails this code reference will be called with the arguments ($lh, \f(CW$key\fR, \f(CW@args\fR)
.PP
It can do whatever you want to try and find the \f(CW$key\fR and return the desired string.
.PP
.Vb 1
\&   return $string_from_db;
.Ve
.PP
If it fails it should simply:
.PP
.Vb 1
\&   return;
.Ve
.PP
That way it will continue on to the part below:
.ie n .SS "$lh\->{'_log_phantom_key'}"
.el .SS "\f(CW$lh\fP\->{'_log_phantom_key'}"
.IX Subsection "$lh->{'_log_phantom_key'}"
If \f(CW$lh\fR\->{'_get_key_from_lookup'} is not a code ref, or \f(CW$lh\fR\->{'_get_key_from_lookup'} returned undef then this method is called with the arguments ($lh, \f(CW$key\fR, \f(CW@args\fR) right before the failure handler does its _AUTO wonderfulness.
.SH "Improved Bracket Notation"
.IX Header "Improved Bracket Notation"
.SS "\fInumf()\fP"
.IX Subsection "numf()"
This uses the decimal format defined in \s-1CLDR\s0 to format the number. That means there is no need to subclass or define special data per class.
.PP
It takes an additional argument to specify the maximum number of decimal places you want.
.SS "\fInumerate()\fP"
.IX Subsection "numerate()"
\&\s-1CLDR\s0 plural rule aware version of the Locale::Maketext \fInumerate()\fR. That means there is no need to subclass.
.PP
See Locales::DB::Docs::PluralForms for locale specific arguments.
.SS "\fIquant()\fP"
.IX Subsection "quant()"
\&\s-1CLDR\s0 plural rule aware version of the Locale::Maketext \fIquant()\fR.
.PP
That means there is no need to subclass, you need to specify all arguments (except the always optional “Special Zero” argument that some locales have)
.PP
See Locales::DB::Docs::PluralForms for locale specific arguments.
.PP
e.g. Key is 'en', value is 'ru':
.PP
.Vb 1
\&    \*(Aq… [quant,_1,one category text,other category text,special_zero text] …\*(Aq => \*(Aq… [quant,_1,one category text,few category text,many category text,other category text] …\*(Aq
.Ve
.PP
You can use '%s' to specify the position of the number. Other wise it is prepended with a space (except “Special Zero” which won't contain the number.)
.PP
The number is formatted via \fInumf()\fR with a max decimal place of 3.
.PP
You can pass in an array ref instead of the number in order to pass in a max decimal places value. The first item is the number, the second item is the max decimal places.
.PP
.Vb 2
\&    maketext(\*(AqThe average monthly rainfall is [quant,_1,inch,inches].\*(Aq, $n); # … is 42.869 inches.
\&    maketext(\*(AqThe average monthly rainfall is [quant,_1,inch,inches].\*(Aq, [$n,2]); # … is 42.87 inches.
.Ve
.SH "Additional bracket notation methods"
.IX Header "Additional bracket notation methods"
.SS "\fIjoin()\fP"
.IX Subsection "join()"
Joins the given arguments with the first argument:
.PP
.Vb 4
\&   [join,\-,_*], @numbers becomes 1\-2\-3\-4\-5
\&   [join,,_*], @numbers becomes 12345
\&   [join,~,,_*], @numbers becomes 1,2,3,4,5
\&   [join,~, ,_*], @numbers becomes 1, 2, 3, 4, 5
.Ve
.PP
Array ref arguments are expanded:
.PP
.Vb 1
\&   $lh\->maketext(\*(Aq… [join,\-,_1,2] …\*(Aq, [1,2,3],4); # … 1\-2\-3\-4 …
.Ve
.SS "\fIlist_and()\fP"
.IX Subsection "list_and()"
Take a list of arguments (like join–array ref arguments are expanded) and format it per the locale's \s-1CLDR\s0 list pattern for and.
.PP
.Vb 1
\&   You chose [list_and,_1]., \e@pals
\&   
\&   You chose Rhiannon.
\&   You chose Rhiannon and Parker.
\&   You chose Rhiannon, Parker, and Char.
\&   You chose Rhiannon, Parker, Char, and Bean.
.Ve
.PP
See \*(L"\fIget_list_and()\fR\*(R" in Locales for more information.
.SS "\fIlist_or()\fP"
.IX Subsection "list_or()"
Same as list_and but with or-lists. See \*(L"\fIget_list_or()\fR\*(R" in Locales for more information and an important caveat.
.SS "\fIlist_and_quoted()\fP"
.IX Subsection "list_and_quoted()"
Like \fIlist_and()\fR but all values are quoted via the \s-1CLDR\s0 to disambiguate them.
.SS "\fIlist_or_quoted()\fP"
.IX Subsection "list_or_quoted()"
Like \fIlist_or()\fR but all values are quoted via the \s-1CLDR\s0 to disambiguate them.
.PP
\fI\fIlist()\fI–deprecated\fR
.IX Subsection "list()–deprecated"
.PP
Creates a phrased list \*(L"and/or\*(R" style:
.PP
.Vb 1
\&  You chose [list,and,_*]., @pals
\&  
\&  You chose Rhiannon.
\&  You chose Rhiannon and Parker.
\&  You chose Rhiannon, Parker, and Char.
\&  You chose Rhiannon, Parker, Char, and Bean.
.Ve
.PP
The 'and' above is by default an '&':
.PP
.Vb 1
\&  You chose [list,,_*]
\&
\&  You chose Rhiannon, Parker, & Char
.Ve
.PP
A locale can set that but I recommend being explicit in your lexicons so the translators will know what you're trying to say:
.PP
.Vb 2
\&   [list,and,_*]
\&   [list,or,_*]
.Ve
.PP
A locale can also control the seperator and \*(L"oxford\*(R" comma character (\s-1IE\s0 empty string for no oxford comma)
.PP
The locale can do this by setting some variables in the same manner you'd set 'numf_comma' to 
change how \fInumf()\fR behaves for a class without having to write an almost identical method.
.PP
The variables are (w/ defaults shown):
.PP
.Vb 3
\&  $lh\->{\*(Aqlist_seperator\*(Aq}   = \*(Aq, \*(Aq;
\&  $lh\->{\*(Aqoxford_seperator\*(Aq} = \*(Aq,\*(Aq;
\&  $lh\->{\*(Aqlist_default_and\*(Aq} = \*(Aq&\*(Aq;
.Ve
.PP
Array ref arguments are expanded.
.SS "\fIdatetime()\fP"
.IX Subsection "datetime()"
Allows you to get datetime output formatted for the current locale.
.PP
.Vb 1
\&    \*(AqRight now it is [datetime]\*(Aq
.Ve
.PP
It can take 2 arguments which default to DateTime\->now and 'date_format_long' respectively.
.PP
The first argument  tells the function what point in time you want. The values can be:
.IP "\(bu" 4
A DateTime object
.IP "\(bu" 4
A hashref of arguments suitable for DateTime\->\fInew()\fR
.IP "\(bu" 4
An epoch suitable for DateTime\->\fIfrom_epoch()\fR's 'epoch' field.
.Sp
Uses \s-1UTC\s0 as the time zone
.IP "\(bu" 4
A time zone suitable for DateTime constructors' 'time_zone' field
.Sp
The current time is used.
.Sp
Passing it an empty string will result in \s-1UTC\s0 being used.
.IP "\(bu" 4
An epoch and time zone as above joined together by a colon
.Sp
A colon followed by nothing will result in \s-1UTC\s0
.PP
The second tells it what format you'd like that point in time stringified. The values can be:
.IP "\(bu" 4
A coderef that returns a string suitable for DateTime\->\fIformat_cldr()\fR
.IP "\(bu" 4
A string that is the name of a DateTime::Locale *_format_* method
.IP "\(bu" 4
A string suitable for DateTime\->\fIformat_cldr()\fR
.SS "\fIcurrent_year()\fP"
.IX Subsection "current_year()"
\&\s-1CLDR\s0 version of current year. i.e. Shortcut to [datetime,,YYYY].
.SS "\fIformat_bytes()\fP"
.IX Subsection "format_bytes()"
Convert byte count to human readable format. Does not require external modules.
.PP
.Vb 1
\&   \*(AqYou have used [format_bytes,_1] of your alloted space.\*(Aq, $bytes
.Ve
.PP
Accepts an optional argument for max number of decimal places, default is 2.
.SS "\fIconvert()\fP"
.IX Subsection "convert()"
Shortcut to Math::Units \fIconvert()\fR
.PP
.Vb 1
\&  \*(AqThe fish was [convert,_1,_2,_3]" long\*(Aq, $feet,\*(Aqft\*(Aq,\*(Aqin\*(Aq
.Ve
.SS "\fIboolean()\fP"
.IX Subsection "boolean()"
This method allows you to choose a word or phrase to use based on a boolean.
.PP
The first argument is the boolean value which should be true, false, or undefined. The next arguments are the string to use for a true value, the string to use for a false value and an optional value for an undefined value (if none is given undefined uses the false value).
.PP
.Vb 1
\&  \*(AqYou [boolean,_1,have won,didn\*(Aqt win] a new car.\*(Aq
\&
\&  \*(AqYou [boolean,_1,have won,didn\*(Aqt win,have not entered our contest to win] a new car.\*(Aq
\&
\&   $lh\->maketext(q{Congratulations! It\*(Aqs a [boolean,_1,girl,boy]!}, $is_a_girl);
.Ve
.PP
It can have “embedded args”:
.PP
.Vb 1
\&    \*(AqYou must specify a value[boolean,_1, for the “_1” field].
.Ve
.SS "\fIis_defined()\fP"
.IX Subsection "is_defined()"
This method allows you to choose a word or phrase to use based on definedness.
.PP
The first argument is the value which should be defined or undefined.
.PP
The next arguments are: the string to use for a defined value, the string to use for a undefined value and an optional string for a defined value  that is false (if none is given undefined uses the undefined value).
.PP
It can have “embedded args”.
.PP
.Vb 3
\&    \*(AqSorry, [is_defined,_2,“_2” is an invalid,you must specify a valid] value for “[_1]”.\*(Aq \*(Aqdomain\*(Aq, $domain
\&    # Sorry, “localhost” is an invalid value for “domain”.
\&    # Sorry, you must specify a valid value for “domain”.
.Ve
.SS "\fIis_future()\fP"
.IX Subsection "is_future()"
The first argument is the same as the first argument to \fIdatetime()\fR. Then comes the string for future and the string for false.
.PP
.Vb 1
\&    Your session [is_future,_1,will expire,expired] on [datetime,_1,date_format_medium].
.Ve
.SS "\fIcomment()\fP"
.IX Subsection "comment()"
Embed comments in your phrases.
.PP
.Vb 2
\&    \*(AqThe transmogrifier has been constipulated to level “[_1]”[comment,The argument is the variable name containing the superposition of the golden ratio’s decimal place in relation to π as mildegredaded by the authoritative falloosifier.].\*(Aq
\&    # The transmogrifier has been constipulated to level “☺”.
.Ve
.SS "\fIasis()\fP"
.IX Subsection "asis()"
Include non-translatable text in your phrase, e.g. a proper name.
.PP
.Vb 1
\&   \*(AqThanks you for contacting [asis,Feel Good Inc.].\*(Aq
.Ve
.PP
This is a short-name alias to 'output,asis' so it can have embedded methods like any \fIoutput()\fR method.
.PP
.Vb 1
\&   \*(AqThanks you for contacting [asis,Foo chr(38) Barsup(®)].\*(Aq
.Ve
.PP
Does not support embedded args.
.SS "\fIoutput()\fP"
.IX Subsection "output()"
When you output a phrase you might mark it up by wrapping the string in, say, <p> tags. You wouldn't inlcude \s-1HTML\s0 *in* the key itself for a number of obvious reasons (\s-1HTML\s0 is not human, \s-1HTML\s0 is not the only possible output you may ever want, etc):
.PP
.Vb 1
\&    print $lh\->maketext(\*(Aq<p class="ok">Good news everyone!</p>\*(Aq); # WRONG DO NOT DO THIS  !!
\&    
\&    print q{<p class="ok">} . $lh\->maketext(\*(AqGood news everyone!\*(Aq) . "</p>"; # good
.Ve
.PP
What about when you want to format something inside the string? For example, you want to be sure certain words stand out. Or the argument is a \s-1URL\s0 that you want to be a link?
.PP
Again, you don't want to add formatting inside the string so what do you do? You use the \fIoutput()\fR method.
.PP
This method allows you to specify various output types. Those types allows a key to specify how a word or phrase should be output without having to understand or anticipate every possible context it might be used in.
.PP
.Vb 1
\&   \*(AqWhat ever you do, do [output,strong,NOT] cut the blue wire!\*(Aq
\&   
\&   \*(AqYour addon domain [output,underline,_1] has been setup.\*(Aq
.Ve
.PP
\fIDefault output methods.\fR
.IX Subsection "Default output methods."
.PP
Each output method name is the second argument to output. e.g. if the output method is 'xyz' you'd use it like this [output,xyz,…] and define a new one like this 'sub output_xyz { … }'.
.PP
All \fIoutput()\fR methods support embedded methods: \fIsub()\fR, \fIsup()\fR, \fIchr()\fR, \fIamp()\fR, and \fInumf()\fR. Note: \fIsub()\fR, \fIsup()\fR, and \fInumf()\fR are simplified in that they only work with one argument.
.PP
These default bare bones methods support 3 contexts: \s-1HTML, ANSI,\s0 and plain text. See \*(L"\fIoutput()\fR context\*(R" below.
.PP
Feel free to over ride them if they do not suit your needs.
.PP
The terminal control codes were ripped from Term::ANSIColor but the module itself is not used.
.IP "\(bu" 4
\&\fIunderline()\fR
.Sp
Underline the string:
.Sp
.Vb 1
\&    \*(AqYou [output,underline,must] be on time from now on.\*(Aq
.Ve
.Sp
For \s-1HTML\s0 it uses a span tag w/ \s-1CSS,\s0 for text it uses the standard terminal control code 4.
.Sp
Allows embedded arguments in the string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.IP "\(bu" 4
\&\fIstrong()\fR
.Sp
Make the string strong:
.Sp
.Vb 1
\&    \*(AqYou [output,strong,do not] want to feed the velociraptors.\*(Aq
.Ve
.Sp
For \s-1HTML\s0 it uses a <strong>, for text it uses the standard terminal control code 1.
.Sp
Allows embedded arguments in the string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.IP "\(bu" 4
\&\fIem()\fR
.Sp
Add emphasis to the string:
.Sp
.Vb 1
\&    \*(AqWe [output,em,want] you to succeed.\*(Aq
.Ve
.Sp
For \s-1HTML\s0 it uses a <em>, for text it uses the standard terminal control code 3. (This may change in the future. See the blurb about \*(L"not all displays are \s-1ISO\s0 6429\-compliant\*(R" at \*(L"\s-1NOTES\*(R"\s0 in Term::ANSIColor.)
.Sp
Allows embedded arguments in the string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.IP "\(bu" 4
\&\fIurl()\fR
.Sp
Handle URLs appropriately:
.Sp
In its simplest form you pass it a \s-1URL\s0 and the text:
.Sp
.Vb 1
\&   \*(AqVisit [output,url,_1,CPAN] today.\*(Aq, \*(Aqhttp://search.cpan.org\*(Aq
.Ve
.Sp
in \s-1HTML\s0 context you get: Visit <a href=\*(L"http://search.cpan.org\*(R">CPAN</a> today.
.Sp
in non-HTML context you get: Visit \s-1CPAN \s0(http://search.cpan.org) today.
.Sp
It is more flexible by using a special hash.
.Sp
.Vb 1
\&   \*(AqYou must [output,url,_1,html,click here,plain,go to] to complete your registration.\*(Aq
.Ve
.Sp
The arguments after the method name ('output') and the output type ('url') are: the \s-1URL,\s0 a hash of values to use in determining the string that the \s-1URL\s0 is turned into.
.Sp
The main keys are 'html' and 'plain' (the latter is used for both 'plain' and 'ansi' contexts). Their values are the string to use in conjuction with the context's rendering of the value. Embedded arguments are supported in those values:
.Sp
.Vb 1
\&    \*(AqYou must [output,url,_1,html,click on the _2 icon,plain,go to] to complete your registration.\*(Aq, $URL, \*(Aq<img …/>\*(Aq
.Ve
.Sp
For \s-1HTML\s0 it uses a plain anchor tag. You can specify _type => 'offsite' to the arguments and it will have 'target=\*(L"_blank\*(R" class=\*(L"offsite\*(R"' as attributes. Again, feel free to create your own if this does not suit your needs.
.Sp
.Vb 1
\&   [output,url,_1,html,click here,_type,offsite,…]
.Ve
.Sp
For text the \s-1URL\s0 is appended unless it had embedded args and the string contains the \s-1URL\s0 after those arguments are applied.
.Sp
.Vb 1
\&   \*(AqYou should [output,url,plain:visit _1 soon,…].\*(Aq
.Ve
.Sp
becomes 'You should visit http://search.cpan.org soon.' and
.Sp
.Vb 1
\&   \*(AqYou should [output,url,_1,plain,visit,…].\*(Aq
.Ve
.Sp
becomes 'You should visit http://search.cpan.org.'
.Sp
Both 'html' and 'plain' fallback to the \s-1URL\s0 itself if no value is given:
.Sp
.Vb 1
\&   My favorite site is [output,url,_1,_type,offsite].
\&   
\&   text: My favorite site is http://search.cpan.org.
\&   
\&   html: My favorite site is <a target="_blank" class="offsite" href="http://search.cpan.org">http://search.cpan.org</a>.
.Ve
.Sp
This method can be used also when the context has different types of values. For example, a web based \s-1UI\s0 might have a \s-1URL\s0 but via command line there is an equivalent command to run.
.Sp
.Vb 1
\&   \*(AqTo unlock this account [output,url,_1,plain,execute \`%s\` via SSH,html,click here].\*(Aq
.Ve
.Sp
Tips:
.RS 4
.IP "\(bu" 4
Pass the \s-1URL\s0 in as an argument so that if the \s-1URL\s0 changes your phrase won't. That also lends itself to reusability.
.IP "\(bu" 4
Try to use context agnostic verbiage.
.Sp
e.g. Click [output,url,_1,here] for the documentation.
.Sp
It won't look right in a terminal (e.g. Click here (http://….) for the documentation.) thus it takes away reusability.
.RE
.RS 4
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.Sp
The display text (whether from arg (i.e. simple form) or from “html” or “plain” keys) can have embedded methods.
.RE
.IP "\(bu" 4
\&\fIchr()\fR
.Sp
Output the character represented by the given number. It is a wrapper around perl's built-in chr function that also encodes the value into the handle's encoding if it's over 127, and outputs as appropriate for the \s-1UI.\s0
.Sp
.Vb 1
\&    $lh\->maketext(\*(AqI [output,chr,60]3 ascii art!\*(Aq);
.Ve
.Sp
For text you get 'I <3 ascii art!'
.Sp
For \s-1HTML\s0 you get 'I &lt;3 ascii art!'
.IP "\(bu" 4
\&\fIclass()\fR
.Sp
Output the given string as a certain class of text. Since terminals have no concept of a styling classes we currently just make it bold. You could create your own 'sub output_class' that has a map of your project's standard visual \s-1CSS\s0 classes to ANSIColor escape sequences to use.
.Sp
.Vb 1
\&    $lh\->maketext(\*(AqThe user [output,class,_1,highlight,contrast] was updated.\*(Aq, $user);
.Ve
.Sp
For text you get 'The user bob was updated.' with 'bob' wrapped in the standard terminal control code 1.
.Sp
For \s-1HTML\s0 you get 'The user <span class=\*(L"highlight contrast\*(R">bob</span> was updated.'
.IP "\(bu" 4
\&\fIencode_puny()\fR
.Sp
.Vb 1
\&    $lh\->maketext(\*(AqThe ascii safe version of your domain is “[output,encode_puny,_1]”.\*(Aq, $domain);
.Ve
.Sp
If the string is already punycode it will return the string as-is.
.Sp
If there are any problems encoding the string it will return 'Error: invalid string for punycode'.
.IP "\(bu" 4
\&\fIdecode_puny()\fR
.Sp
.Vb 1
\&    $lh\->maketext(\*(AqThe unicode version of your domain is “[output,decode_puny,_1]” is really cool.\*(Aq, $domain);
.Ve
.Sp
If the string is not punycode it will return the string as-is.
.Sp
If there are any problems decoding the string it will return 'Error: invalid punycode'.
.IP "\(bu" 4
\&\fIasis_for_tests()\fR
.Sp
Returns the given string as-is. Named so as to explicitly indicate a testing state.
.Sp
Allows embedded arguments in the string.
.IP "\(bu" 4
\&\fIattr()\fR
.Sp
Alias for \fIinline()\fR
.IP "\(bu" 4
\&\fIinline()\fR
.Sp
Allows assigning attributes to part of a string.
.Sp
The first argument is the string. The rest are outlined in \*(L"Arbitrary name/value attribute list\*(R".
.Sp
Allows embedded arguments in the string.
.Sp
In \s-1HTML\s0 context it is a span tag.
.IP "\(bu" 4
\&\fIblock()\fR
.Sp
Same as \fIinline()\fR except, in \s-1HTML\s0 context, it uses a div instead of span.
.Sp
The div should conceptually be an inline-div for positioning part of a string and not for document stucture. (Bracket notation is not a template system!)
.Sp
When we get real world examples of this I'll update the \s-1POD.\s0 For now you probably really want output,inline or output,sub or output,sup.
.IP "\(bu" 4
\&\fIimg()\fR
.Sp
Output an image. In non-HTML context the \s-1ALT\s0 text is what is output.
.Sp
The arguments are the images src and alt (alt default to src but don't do that).
.Sp
.Vb 1
\&    \*(Aq[output,img,big_brother.png,Big Brother] is watching you!\*(Aq
.Ve
.Sp
Allows embedded arguments in the alt string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R" except 'src' and 'alt' which will be ignored if given.
.IP "\(bu" 4
\&\fIabbr()\fR
.Sp
Takes 2 arguments: the abbreviated form and the non-abbreviated form.
.Sp
.Vb 1
\&    [output,abbr,Abbr.,Abbreviation]
.Ve
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R" except 'title' which will be ignored if given.
.Sp
Best for truncation type abbreviations. (Mnemonic: abbr is a truncated word itself)
.Sp
If you want to further pin down the type of abbreviation is is you can specify a more specific class (e.g. end-clip, blend, numeronym, begin-clip, phonogram, contraction,  portmanteau, apheresis, aphesis, etc).
.IP "\(bu" 4
\&\fIacronym()\fR
.Sp
Takes 2 arguments: the acronym and what it stands for.
.Sp
.Vb 1
\&   [output,acronym,SCUBA,Self Contained Underwater Breathing Apparatus]
.Ve
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R" except 'title' which will be ignored if given.
.Sp
Best for initial type abbreviations. (Typically all caps)
.Sp
To be \s-1HTML5\s0 compat it outputs <abbr> with a class of “initialism” (like bootstrap).
.Sp
If you want to further pin down the type of abbreviation is is you can specify a more specific class (e.g. acronym, hybrid, acrostic, alphabetism, backronym, macronym, recursive, context, composite, etc).
.Sp
If you do pass in a class value “initialism” is still retained.
.IP "\(bu" 4
\&\fIsup()\fR
.Sp
Super script the argument.
.Sp
.Vb 1
\&   [output,sup,X]
.Ve
.Sp
Allows embedded arguments in the string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.IP "\(bu" 4
\&\fIsub()\fR
.Sp
Sub script the argument.
.Sp
.Vb 1
\&   [output,sub,X]
.Ve
.Sp
Allows embedded arguments in the string.
.Sp
Supports \*(L"Arbitrary name/value attribute list\*(R".
.IP "\(bu" 4
\&\fInbsp()\fR
.Sp
Convenience method to get a non breaking space character (not the \s-1HTML\s0 entity, the character–works the same as the entity ina browser).
.Sp
Helps to visually indicate you intend a non breaking space when it is required.
.Sp
.Vb 1
\&   \*(Aqfoo[output,nbsp]bar\*(Aq vs \*(Aqfoo bar\*(Aq
.Ve
.IP "\(bu" 4
\&\fIamp()\fR
.Sp
[output,amp] is a shortcut to [output,chr,38]
.IP "\(bu" 4
\&\fIlt()\fR
.Sp
[output,lt] is a shortcut to [output,chr,60]
.IP "\(bu" 4
\&\fIgt()\fR
.Sp
[output,gt] is a shortcut to [output,chr,62]
.IP "\(bu" 4
\&\fIapos()\fR
.Sp
[output,apos] is a shortcut to [output,chr,39]
.IP "\(bu" 4
\&\fIquot()\fR
.Sp
[output,quot] is a shortcut to [output,chr,34]
.IP "\(bu" 4
\&\fIshy()\fR
.Sp
[output,shy] is a shortcut to [output,chr,173]
.IP "\(bu" 4
\&\fIasis()\fR
.Sp
.Vb 1
\&   [output,asis,…]
.Ve
.Sp
Alias for \*(L"\fIasis()\fR\*(R".
.PP
\fIAdding your own output methods\fR
.IX Subsection "Adding your own output methods"
.PP
Output methods can be created (and overridden) simply by defining a method prefixed by output_ followed by the output type. For example in your lexicon class you would:
.PP
.Vb 2
\&   sub output_de_profanitize {
\&       my ($lh, $word_or_phrase, $level, $substitute) = @_;
\&       
\&       return get_clean_text({
\&          \*(Aqlang\*(Aq => $lh\->get_language_tag(),
\&          \*(Aqtext\*(Aq => $word_or_phrase,
\&          \*(Aqlevel\*(Aq => $level,
\&          \*(Aqcharacter\*(Aq => $substitute,
\&       });
\&   }
.Ve
.PP
Then you can use this in your lexicon key:
.PP
.Vb 1
\&   \*(AqQuote of the day "[output,de_profanitize,_1,9,*]"\*(Aq
.Ve
.PP
Your class can do whatever you like to determine the context and is by no means limited to 'plain' and 'html'  types. Keys that are not context names (i.e. _type) should be preceded by an underscore.
.SS "Arbitrary name/value attribute list"
.IX Subsection "Arbitrary name/value attribute list"
Methods that support this feature are able to accept additional arguments treated as name/value pair attributes.
.PP
The idea is to embed ones that will likely not change and hopefully add to the meaning of the string.
.PP
.Vb 1
\&    Your hair [output,inline,is on fire,class,urgent]!
.Ve
.PP
After that list (or instead of it) a single hashref can be passed in. The intent here is to be able to do any arbitrary name/value that the caller might want to use but is likely to change and/or adds little meaning if any to the string.
.SS "\fIoutput()\fP context"
.IX Subsection "output() context"
Context as used here means what type of output we want based on where it will be happening at.
.PP
\&'html' will do output suitable for use in \s-1HTML\s0 code.
.PP
\&'ansi' will do output suitable for a terminal.
.PP
\&'plain' will do output without any sort of formatting.
.IP "\(bu" 4
\&\fIset_context()\fR
.Sp
Set the context. If no arguments are given it will set it to 'html' or 'ansi' based on IO::Interactive::Tiny.
.Sp
This happens automatically if needed so you shouldn't have to call it unless you want to change it.
.Sp
Otherwise it accepts 'html', 'ansi', or 'plain'.
.Sp
Returns the context that it sets it to (or an empty string if you pass in a second true argument).
.IP "\(bu" 4
\&\fIget_context()\fR
.Sp
Takes no arguments.
.Sp
Returns 'html', 'ansi', or 'plain'. Calls \f(CW$lh\fR\->\fIset_context()\fR if it has not been set yet.
.IP "\(bu" 4
\&\fIset_context_html()\fR
.Sp
Takes no arguments. Sets the contect to 'html'.
.Sp
Returns the context it was set to previously (or an empty string if you pass in a second true argument) on success, false otherwise.
.IP "\(bu" 4
\&\fIset_context_ansi()\fR
.Sp
Takes no arguments. Sets the contect to 'ansi'.
.Sp
Returns the context it was set to previously (or an empty string if you pass in a second true argument) on success, false otherwise.
.IP "\(bu" 4
\&\fIset_context_plain()\fR
.Sp
Takes no arguments. Sets the contect to 'plain'.
.Sp
Returns the context it was set to previously (or an empty string if you pass in a second true argument) on success, false otherwise.
.IP "\(bu" 4
\&\fIcontext_is()\fR
.Sp
Takes one argument and returns true if that is what the context currently is.
.IP "\(bu" 4
\&\fIcontext_is_html()\fR
.Sp
Takes no arguments. Returns true if that is what the context is currently 'html'.
.IP "\(bu" 4
\&\fIcontext_is_ansi()\fR
.Sp
Takes no arguments. Returns true if that is what the context is currently 'ansi'.
.IP "\(bu" 4
\&\fIcontext_is_plain()\fR
.Sp
Takes no arguments. Returns true if that is what the context is currently 'plain'.
.IP "\(bu" 4
\&\fImaketext_html_context()\fR
.Sp
Does \fImaketext()\fR under the 'html' context regardless of what the current context is.
.IP "\(bu" 4
\&\fImaketext_ansi_context()\fR
.Sp
Does \fImaketext()\fR under the 'ansi' context regardless of what the current context is.
.IP "\(bu" 4
\&\fImaketext_plain_context()\fR
.Sp
Does \fImaketext()\fR under the 'plain' context regardless of what the current context is.
.SH "Project example"
.IX Header "Project example"
Main Class:
.PP
.Vb 3
\&    package MyApp::Localize;
\&    use Locale::Maketext::Utils; 
\&    use base \*(AqLocale::Maketext::Utils\*(Aq; 
\&
\&    our $Encoding = \*(Aqutf\-8\*(Aq; 
\&    
\&    _\|_PACKAGE_\|_\->make_alias([qw(en en_us i_default)], 1);
\&
\&    our %Lexicon = (
\&        \*(AqHello World\*(Aq => \*(AqHello World\*(Aq, # $Onesided used to allow for \*(AqHello World\*(Aq => \*(Aq\*(Aq,
\&    );
\&    
\&    1;
.Ve
.PP
French class:
.PP
.Vb 5
\&    package MyApp::Localize::fr;
\&    use base \*(AqMyApp::Localize\*(Aq;
\&    our %Lexicon = (
\&        \*(AqHello World\*(Aq => \*(AqBonjour Monde\*(Aq,
\&    );
\&    
\&    # not only is this too late to be of any use
\&    # but it\*(Aqs pointless as it already in essence happens since a failed NS 
\&    # lookup tries the superordinate (in this case \*(Aqfr\*(Aq) before moving on 
\&    # _\|_PACKAGE_\|_\->make_alias(\*(Aqfr_ca\*(Aq);
\&    
\&    sub init {
\&        my ($lh) = @_;
\&        $lh\->SUPER::init();
\&        $lh\->{\*(Aqnumf_comma\*(Aq} = 1; # Locale::Maketext numf()
\&        return $lh;
\&    }
\&    
\&    1;
.Ve
.SS "Standard"" .pm layout"
.IX Subsection "Standard"" .pm layout"
In the name of consistency I recommend the following \*(L"Standard\*(R" namespace/file layout.
.PP
You put all of your locales in MainNS::language_code
.PP
You put any utility functions/methods in MainNS::Utils and/or MainNS::Utils::*
.PP
So assuming a main class of MyApp::Localize the files && name spaces would be:
.PP
.Vb 8
\&   MyApp/Localize.pm                MyApp::Localize
\&   MyApp/Localize/Utils.pm          MyApp::Localize::Utils
\&   MyApp/Localize/Utils/Etc.pm      MyApp::Localize::Utils::Etc
\&   MyApp/Localize/Utils/AndSoOn.pm  MyApp::Localize::Utils::AndSoOn
\&   MyApp/Localize/fr.pm             MyApp::Localize::fr
\&   MyApp/Localize/it.pm             MyApp::Localize::it
\&   MyApp/Localize/es.pm             MyApp::Localize::es
\&   ...
.Ve
.PP
If you choose to use this paradigm you'll have two additional methods available:
.PP
\fI\f(CI$lh\fI\->\fIget_base_class_dir()\fI\fR
.IX Subsection "$lh->get_base_class_dir()"
.PP
Returns the directory that correspnds to the base class's name space.
.PP
Again, assuming a main class of MyApp::Localize it'd be '/usr/lib/whatever/MyApp/Localize'
.PP
\fI\f(CI$lh\fI\->\fIlist_available_locales()\fI\fR
.IX Subsection "$lh->list_available_locales()"
.PP
Returns a list of locales available. These are based on the .pm files in \f(CW$lh\fR\->\fIget_base_class_dir()\fR that are not 'Utils.pm'.
.PP
They are returned in the order \fIglob()\fR returns them. (i.e. no particular order)
.PP
Assuming the file layout above you'd get something like (fr, it, es, ...)
.PP
This would be useful for creating a menu of available languages to choose from:
.PP
.Vb 1
\&   my ($current_lookup, $native_lookup) = $lh\->lang_names_hashref(\*(Aqen\*(Aq, $lh\->list_available_locales());
\&   
\&   # since our main lexicon only has aliases (i.e. no .pm file): 
\&   #    we want the main language on top and we only want one of the aliases: the superordinate
\&   for my $langtag (\*(Aqen\*(Aq, sort $lh\->list_available_locales()) {
\&       if ($current_lookup\->{$langtag} eq $native_lookup\->{$langtag}) {
\&           # do menu entry like "Current $current_lookup\->{$langtag} ($langtag)" # Currently English (en)
\&       }
\&       else {
\&          # do menu entry like "$current_lookup\->{$langtag} :: $native_lookup\->{$langtag} :: ($langtag)" # Italian :: Italiano (it)
\&      }
\&   }
.Ve
.SS "Tie::Hash::ReadonlyStack compat Lexicon"
.IX Subsection "Tie::Hash::ReadonlyStack compat Lexicon"
Often you'll want to add things to the lexicon. Perhaps a server's local version of a few strings or a context specific lexicon and using \fIappend_to_lexicons()\fR and \fIremove_key_from_lexicons()\fR is too cumbersome.
.PP
Buy making your lexicon a Tie::Hash::ReadonlyStack hash we can do just that.
.PP
First we make our main lexicon:
.PP
.Vb 1
\&    use Tie::Hash::ReadonlyStack;
\&    
\&    tie %MyApp::Localize::Lexicon, \*(AqTie::Hash::ReadonlyStack\*(Aq, \e%actual_lexicon;
.Ve
.PP
\&'%actual_lexicon' can be a normal hash or a specially tied hash (e.g. a \s-1GDBM_READER \s0GDBM_File hash)
.PP
Next we add the server admin's overrides:
.PP
.Vb 1
\&  $lh\->add_lexicon_override_hash($tag, \*(Aqserver\*(Aq, \e%server);
.Ve
.PP
When we init a user we add their override:
.PP
.Vb 1
\&  $lh\->add_lexicon_override_hash($tag, \*(Aquser\*(Aq, \e%user);
.Ve
.PP
Then we start a request and add request specific keys (perhaps a small lexicon package included with the module that implements the functionality for the current request) to fallback on if they do not exist:
.PP
.Vb 1
\&  $lh\->add_lexicon_fallback_hash($tag, \*(Aqrequest\*(Aq, \e%request);
.Ve
.PP
After the request we don't need that last one any more so we remove it:
.PP
.Vb 1
\&  $lh\->del_lexicon_hash($tag, \*(Aqrequest\*(Aq);
.Ve
.PP
When the user context goes out of scope out we clean up theirs as well:
.PP
.Vb 1
\&  $lh\->del_lexicon_hash($tag, \*(Aquser\*(Aq);
.Ve
.PP
If you choose to use this paradigm (via Tie::Hash::ReadonlyStack or a class implementing the methods in use below) you'll have three additional methods availble:
.PP
These methods all returns false if the lexicon is not tied to an object that implements the method necessary to do this. Otherwise they return whatever the tied class's method returns
.PP
\fI\fIadd_lexicon_override_hash()\fI\fR
.IX Subsection "add_lexicon_override_hash()"
.PP
This adds a hash to be checked before any others currently in the stack.
.PP
Takes 2 or 3 arguments. The language tag whose lexicon we are adding to, a short identifier string, and a reference to a hash. If the language tag is not specified or not in use in the current object the main lexicon is the one it gets asssigned to.
.PP
.Vb 1
\&   # $lh is \*(Aqfr\*(Aq and the main language is english, both are tied to Tie::Hash::ReadonlyStack
\&   
\&   $lh\->add_lexicon_override_hash(\*(Aqfr\*(Aq, \*(Aquser\*(Aq, \e%user_fr); # updated the \*(Aqfr\*(Aq lexicon
\&   $lh\->add_lexicon_override_hash(\*(Aquser\*(Aq, \e%user_en); # updates main lexicon since no language was specified
\&   $lh\->add_lexicon_override_hash(\*(Aqit\*(Aq, \*(Aquser\*(Aq, \e%user_it); # updates main lexicon since \*(Aqit\*(Aq is not in use in the handle
.Ve
.PP
Uses \*(L"\fIadd_lookup_override_hash()\fR\*(R" in Tie::Hash::ReadonlyStack under the hood.
.PP
\fI\fIadd_lexcion_fallback_hash()\fI\fR
.IX Subsection "add_lexcion_fallback_hash()"
.PP
Like \*(L"\fIadd_lexicon_override_hash()\fR\*(R" except that it adds the hash after any others currently in the stack.
.PP
Uses \*(L"\fIadd_lookup_fallback_hash()\fR\*(R" in Tie::Hash::ReadonlyStack under the hood.
.PP
\f(CW$lh\fR\->{'add_lex_hash_silent_if_already_added'}
.IX Subsection "$lh->{'add_lex_hash_silent_if_already_added'}"
.PP
That attribute when true (e.g. set in \fIinit()\fR) will cause the add_lexicon* methods to return true if the given name has been added before it tries to add them (which will return false since they exist already)
.PP
Care must be taken that you're not using the same identifier with different hashes or you some lexicons will simply not be added.
.PP
A better approach is to design your stack modifying logic so it doesn't try to add uplicate entries. This option is really only inteneded for debugging and testing.
.PP
\fI\fIdel_lexicon_hash()\fI\fR
.IX Subsection "del_lexicon_hash()"
.PP
This deletes a hash added via \fIadd_lexicon_override_hash()\fR or \fIadd_lexicon_fallback_hash()\fR from the stack.
.PP
Its arguments are the langtag and the short identifier string.
.PP
If langtag is not specified or is an '*' then it is removed from all lexicons in use.
.PP
If the specified langtag is not in use in the current object it gets removed from the main lexicon.
.PP
.Vb 4
\&   $lh\->del_lexicon_hash(\*(Aqfr\*(Aq, \*(Aquser\*(Aq); # remove \*(Aquser\*(Aq from the \*(Aqfr\*(Aq lexicon
\&   $lh\->del_lexicon_hash(\*(Aq*\*(Aq, \*(Aquser\*(Aq); # remove \*(Aquser\*(Aq from all the handle\*(Aqs lexicons
\&   $lh\->del_lexicon_hash(\*(Aquser\*(Aq); # remove \*(Aquser\*(Aq from all the handle\*(Aqs lexicons
\&   $lh\->del_lexicon_hash(\*(Aqit\*(Aq, \*(Aquser\*(Aq); # remove \*(Aquser\*(Aq from the main lexicon since \*(Aqit\*(Aq is not in use
.Ve
.PP
Uses \*(L"\fIdel_lookup_hash()\fR\*(R" in Tie::Hash::ReadonlyStack under the hood.
.SH "Phrase Utils"
.IX Header "Phrase Utils"
See Locale::Maketext::Utils::Phrase::Norm for pragmatic examination and normalization of maketext phrase.
.PP
See Locale::Maketext::Utils::Phrase::cPanel for the same but via a cPanel recipe.
.PP
See Locale::Maketext::Utils::Mock for a mock object you can use for testing phrases.
.PP
See Locale::Maketext::Utils::MarkPhrase for a lightweight way to mark phrases in source code as translatable.
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
\&\f(CW$ENV\fR{'maketext_obj'} gets set to the language object on initialization ( for functions to use, see \*(L"\s-1FUNCTIONS\*(R"\s0 below ) unless \f(CW$ENV\fR{'maketext_obj_skip_env'} is true
.SS "\s-1FUNCTIONS\s0"
.IX Subsection "FUNCTIONS"
Locale::Maketext::Pseudo has some exportable functions that make use of \f(CW$ENV\fR{'maketext_obj'} to do things like:
.PP
.Vb 1
\&    use Locale::Maketext::Pseudo qw(env_maketext);
\&    
\&    ...
\&    
\&    env_maketext("Hello, my name is [_1]", $name); # use real object if we have one otherwise use pseudo object
.Ve
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Locale::Maketext, Locales::Language, Locale::Maketext::Pseudo, Text::Extract::MaketextCallPhrases
.PP
If you use \*(L"$lh\-\*(R"\fIlang_names_hashref()\fR> or \*(L"$lh\-\*(R"\fIloadable_lang_names_hashref()\fR> make sure you have the latest verison of Locales as 0.04 (i.e. Locales::Base 0.03) is buggy!
.SH "TODO"
.IX Header "TODO"
Audit that “Arbitrary name/value attribute list” is being used everywhere it makes sense to and that each use of it is documented.
.PP
Add in currently beta \fIdatetime_duration()\fR (\*(L"\s-1LOCALIZATION\s0 of DateTime::Format modules\*(R" in DateTime::Format::Span and company)
.PP
Add in currently beta \fIcurrency()\fR, \fIcurrency_convert()\fR
.PP
Add more tests for v0.20: The changes have been in production outside of \s-1CPAN\s0 for a while, this was just a release to bring the \s-1CPAN\s0 verison up to date.
.SH "SUGGESTIONS"
.IX Header "SUGGESTIONS"
If you have an idea for a method that would fit into this module just let me know and we'll see what can be done
.SH "AUTHOR"
.IX Header "AUTHOR"
Daniel Muey, <http://drmuey.com/cpan_contact.pl>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright (c) 2011 cPanel, Inc. \f(CW\*(C`<copyright@cpanel.net>\*(C'\fR. All rights reserved.
.PP
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.

Youez - 2016 - github.com/yon3zu
LinuXploit