If the shell escape is enabled or \directlua is available,
this package may also be used to query the LC_ALL
or LANG environment variable (see
§6). Windows users, who don’t have the locale
stored in environment variables, can use texosquery
in combination with tracklang. (Similarly if LC_ALL
or LANG don’t contain sufficient information.) In order to
use texosquery through the restricted shell escape, you must
have at least Java 8 and set up texosquery.cfg
appropriately. (See the texosquery manual for further details.)
The fundamental aim of this generic package is to be able to effectively say:
The user (that is, the document author) wants to use dialectsNaturally, this is only of use if the locale-sensitive packages use tracklang to pick up this information, which is entirely up to the package authors, but at the moment there’s no standard method for packages to detect the required language and region. The aim of tracklang is to provide that method. In particular, the emphasis is on using ISO language and region codes rather than hard-coding the various language labels used by different language packages.xx-XX,yy-YY-Scrp, etc in their document. Any packages used by their document that provide multilingual or region-dependent support should do whatever is required to activate the settings for those languages and regions (or warn the user that there’s no support).
Related articles: “Localisation of TeX documents: tracklang.” TUGboat, Volume 37 (2016), No. 3, Localisation with tracklang.tex, and tracklang FAQ.
 
 
 
When I’m developing a package that provides multilingual support
(for example, glossaries) it’s cumbersome trying to work out
if the user has requested translations for fixed text. This usually
involves checking if babel or translator or
polyglossia has been loaded and, if so, what language settings
have been used. The result can be a tangled mass of conditional
code. The alternative is to tell users to add the language as
a document class option, which they may or may not want to do, or to
tell them to supply the language settings to every package they load
that provides multilingual support, which users are even less likely
to want to do.
 
The tracklang package tries to neaten this up by working out
as much of this information as possible for you and providing a
command that iterates through the loaded languages. This way, you
can just iterate through the list of tracked languages and, for each
language, either define the translations or warn the user that
there’s no translation for that language.
 
As from version 1.6.4, tracklang now checks for
babel’s  
If polyglossia is loaded, tracklang will check if
 
The tracklang package works fairly well with
translator but will additionally assume the root language was
also requested when a dialect is specified. So, for example,
 
If any document class or package options are passed to
tracklang, then tracklang won’t bother checking
for known language packages. So, if the above example is changed to:
 
Predefined dialects are listed in Tables 1.1, 1.2 & 1.3. These may be 
passed in the document class options or
used in  
§2 provides brief examples of use for those
who want a general overview before reading the more detailed
sections.
§3 describes generic commands for
identifying the document languages.
§5 is for package writers who want to
add multilingual support to their package and need to know which
settings the user has requested through language packages like
babel. §6 is for
developers of language definition packages who want to help other
package writers to detect what languages have been requested.
 
 
 
 
 
There are three levels of use:
 
 
 
 
Document level use can be divided into generic TeX use 
(§2.1.1) and LaTeX-specific use (§2.1.2).
 
 
This section is for generic TeX use. The tracklang files are
loaded with  
A Unix-like user wants the locale information picked up from the 
locale environment variable (the tex extension may be omitted):
 
A Windows user wants the locale information picked up from the 
operating system (again the tex extension may be omitted):
 
A user is writing in Italy in Armenian with a Latin
script (Latn) and the arevela variant:
 
A user is writing in English in the UK:
 
Find out information about the current language (supplied
in  
 
This section is for LaTeX use. See §2.1.1 for generic TeX use.
 
With newer versions of polyglossia, where  
For babel users where the supplied babel dialect
label is sufficient, and is passed either through the document class
or package options, there’s no need to do anything special:
 
If the region is important but there’s no babel dialect that
represents it, there are several options.
The first method is to use the class options recognised by tracklang
and the root language labels when loading babel:
 
Another method with babel is to use  
 
Let’s suppose you are developing a package called 
mypackage.sty or mypackage.tex and you want
to find out what languages the document author has requested. (See also:
Using
tracklang.tex in Packages with Localisation Features.)
 
Generic TeX use (the tex extension may be omitted):
 
LaTeX use:
 
(LaTeX) If you want to allow the user to set the locale in the 
package options:
 
 
If you want to fetch the locale information from the operating
system when the user hasn’t requested a language:
 
Set up the defaults if necessary:
 
Now load the resource files:
 
Each resource file has the naming scheme -.ldf.
In this example, the  is mypackage. The
 part may be the language or dialect label (for
example, english or british) or a combination of the
ISO language and region codes (for example, en-GB or
en or GB). As from version 1.4, 
may also include the script or variant. (See the definition of
 
The simplest scheme is to use the root language label (not the
dialect label) for the base language settings and use the ISO
codes for regional support.
 
For example, the file mypackage-english.ldf:
 
With pre-v1.4 versions of tracklang, the script isn’t included
in the file search. If it’s needed then either require at least v1.4
or have a base ldf file that tries to load a version for the
particular script (which can be accessed with
 
 
Let’s suppose now you’re the developer of a package that 
sets up the language, hyphenation patterns and so on.
It would be really helpful to the locale-sensitive packages 
in §2.2 to know what languages
the document author has requested. You can use the
tracklang package to identify this information
by tracking the requested localisation, so that other packages
can have a consistent way of querying it. (See also:
Integrating
tracklang.tex into Language Packages.)
 
Generic use:
 
When a user requests a particular language through your package,
the simplest way of letting tracklang know about it
is to use  
This now means that  
When the user switches language through commands like
 
 
For plain TeX you can input tracklang.tex:
 
The LaTeX package tracklang.sty 
inputs the generic TeX code in tracklang.tex, but before 
it does so it defines
 
This means that all the predefined languages and dialects
(Tables 1.1, 1.2 & 1.3) automatically become package options, so
the tracklang.sty package can pick up document class
options and add them to tracklang’s internal list of tracked
document languages.
 
As from version 1.6.3, the LaTeX package also has options
verbose and noverbose to switch on and
off verbose mode. As from version 1.6.5, there are also
warn and nowarn settings to switch on
(default) and off warnings. This means that these options can be
picked up if they are used as document class options or passed to
tracklang before it’s first loaded.
 
If you’re not using LaTeX, package options aren’t available
although you can redefine 
 
 
For example:
 
Note that it’s impractical to define every possible language
and region combination as it would significantly slow the
time taken to load tracklang so, after version 1.3,
I don’t intend adding any new predefined dialects. As from version
1.3, if you want to track a dialect that’s not predefined by
tracklang, then you can use:
 
For example:
 
 
Alternatively, you can use
 
If you want to first check that  includes a valid language
code, then you can instead use:
 
For example:
 
The datetime2 package assumes that any unknown package option is a
language identifier. It could simply do:
 
If  contains a sub-language tag, this will be set
as the 639-3 code for the dialect label. Note that this is
different to the root language codes which are set using the
language label. For example:
 
Version 1.2 of texosquery provides the command  
Some of the predefined root language options listed
in Table 1.2 have an associated region
(denoted by †).
If  
(New to version 1.3.)
There’s a similar command to  
Since tracklang is neither able to look up the POSIX locale
tables nor interpret file locales, if the result is  
 
If the operating system locale can’t be obtained from environment variables, then
tracklang will use  
Plain TeX example:
 
LaTeX example:
 
If the locale can’t be determined, there will be warning messages.
These can be suppressed using
 
For example, I have the environment variable  
With LaTeX documents I can do
 
The  
If the command:
 
 
For example:
 
If the shell escape is unavailable 
(for example, your TeX installation prohibits it), you
can set this value when you invoke TeX. For example,
if the document file is called myDoc.tex (and it’s
in Plain TeX):
 
The  
The language code is stored in:
 
The territory (if present) is stored in:
 
The code-set (if present) is stored in:
 
The modifier (if present) is stored in:
 
If you want to query the language environment, but don’t
want to track the result, you can just use:
 
The above queries  
Since this sets  
It’s also possible to just parse the value of  
Example (Plain TeX):
 
Compare this with:
 
 
If  
For example, tracklang doesn’t recognise  
 
In addition to the main tracklang.tex file and
tracklang.sty LaTeX wrapper, the tracklang package
also provides supplementary files for region and script mappings.
 
 
 
 
 
 
 
 
 
Mappings are established with:
 
When tracklang-region-codes.tex is input, it can load
additional files that provide supplementary mappings.
 
 
 
Plain TeX:
 
 
This command defines:
 
See Table A.2 for a summary of all the mappings 
that are provided by the file tracklang-scripts.tex.
 
 
 
 
 
 
 
 
 
 
 
 
The tracklang package tries to track the loaded languages and
the option names used to identify those languages. For want of a better
term, the language option names are referred to as dialects even if
they’re only a synonym for the language rather than an actual
dialect. For example, if the user
has requested british, the root language label is
english and the dialect is british, whereas if the
user requested UKenglish, the root language label is
english and the dialect is UKenglish. The
exceptions to this are the tracklang package options that have been
specified in the form - (listed
in Table 1.2). For
example, the package option en-GB behaves as though the
user requested the package option british.
 
If  
 
In addition to the root language label and the dialect identifier,
many of the language options also have corresponding ISO codes. In
most cases there is an ISO 639-1 or an ISO 639-2 code (or both), and in some
cases there is an ISO 3166-1 code identifying the dialect region.
Where a language has different ISO 639-2 (T) and 639-2 (B) codes, 
the “T” version is assumed.
 
When the tracklang.sty LaTeX package is loaded, it first attempts to find the
language options through the package options supplied to
tracklang. This means that any languages that have been
supplied in the document class options should get identified
(provided that the document class has used the standard option
declaration mechanism). If no languages have been supplied in this
way, tracklang.sty then attempts to identify language settings in
the following order:
 
 
 
 
 
 
 
 
 
 
Each identified language and dialect is added to the tracked
language and tracked dialect lists. Note that the tracked
language and tracked dialect are labels rather than proper nouns.
If a dialect label is identical to its root language label, the
label will appear in both lists.
 
You can check whether or not any languages have been detected using:
 
You can check whether or not any regions have been detected using:
 
If you want to find out if any of the tracked dialects
matches a particular language tag, you can use:
 
For example (Plain TeX):
 
Here’s an example that doesn’t have an exact match, but does have a
partial match:
 
You can iterate through each tracked dialect using:
 
You can iterate through each tracked language using:
 
You can iterate through each tracked region using:
 
The above for-loops use the same internal mechanism as LaTeX’s
 
The provided control sequence  is updated at the
start of each iteration to the current element. The loop is
terminated when this control sequence is set to  
You can test if a root language has been detected using:
 
You can test if a particular dialect has been detected using:
 
For example:
 
“british’’ has been specified.
 
“flemish’’ hasn’t been specified.
 
“dutch’’ has been specified.
 
“english’’ or an English variant has been specified.
 
You can find the root language label for a given tracked dialect
using:
 
You can find the tracked dialects from a given root language
using:
 
You can test if a language or dialect has a corresponding ISO code using:
 
Alternatively, you can test if a particular ISO code has been
defined using:
 
You can fetch the language (or dialect) label associated with a
given ISO code using:
 
You can fetch the ISO code for a given code type using:
 
The above commands do nothing in the event of an unknown code or
code type,
so if you accidentally get the wrong code type, you won’t get an error.
If you’re unsure of the code type, you can use the following commands:
 
 
 
 
The  
As from v1.3, the language tag for a given dialect can be obtained
using:
 
As from v1.3, each tracked dialect may also have an associated 
modifier, which can be fetched using:
 
You can test if a dialect has an associated modifier using:
 
For example:
 
Dialects: american (ISO 3166-1: “US’’; root: english).
british (ISO 3166-1: “GB’’; root: english).
canadian (ISO 3166-1: “CA’’; root: english).
canadien (ISO 3166-1: “CA’’; root: french).
dutch (no specific region; root: dutch).
francais (no specific region; root: french).
 
Language for ISO 3166-1 “GB’’: british.
 
Language for ISO 3166-1 “CA’’: canadian,canadien.
 
Country ISO 3166-1 code for “canadian’’: CA.
 
As from v1.3, each tracked dialect may also have an associated 
variant, which can be fetched using:
 
You can test if a dialect has an associated variant using:
 
As from v1.3, each tracked dialect may also have an associated 
script, which can be fetched using:
 
You can test if a dialect has an associated script using:
 
Note that the script should be a recognised four-letter ISO 15924
code, such as Latn or Cyrl. If a dialect
doesn’t have an associated script then the default for the root
language should be assumed. For example, Latn for English dialects or
Cyrl for Russian dialects. The default script for
known languages can be obtained using:
 
There’s a convenient expandable command for testing the script:
 
The supplementary package tracklang-scripts provides some
additional commands relating to writing systems, including commands 
in the form  
For example, the following defines a command to check if
the given dialect should use a Latin script:
 
 
As from v1.3, each tracked dialect may also have a sub-language
identifier (for example, arevela), which can be fetched
using:
 
You can test if a dialect has an associated sub-tag using:
 
As from v1.3, each tracked dialect may also have additional
information, which can be fetched using:
 
You can test if a dialect has additional information using:
 
Most packages that implement multilingual support have a set of
language definition files for each supported language or dialect.
It may be that only the root language is needed, if there are no
variations between that language’s dialect (for the purposes of that
package), or it may be that separate definition files are required
for each dialect. However it can be awkward trying to map the
requested dialect or language label to the file name. Should, say,
the file containing the French code be called
-french- or 
-frenchb- or 
-francais-?
Should, say, the file containing the British English code be called
-british- or 
-UKenglish-?
If you want to modularise the language support for your package so
that each language module has a different maintainer will the
maintainers know what tag to use for their language?
 
To help with this, tracklang provides:
 
Sometimes the dialect label can cause a problem, especially if it
happens to be identical to the root label. The solo region code
check may also be problematic, so the following analoguous commands are
also provided.
 
 
 
 
There’s a convenient shortcut command new to version 1.3:
 
There are analogous commands
 
 
 
The optional argument  is the code that actually
inputs the required file. This defaults to
 
The  
 
 
 
 
 
 
 
 
 
 
 
 
The ordered set of possible values of  is determined from
the given dialect.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
For example (pre v1.3):
 
If, for example,  
 
 
 
If, for example,  
 
 
 
 
 
If, for example,  
If the dialect label is identical to the root language label then it
means that all associated information is the default
for that language. For example, in the above case of french,
the script is Latn and the region is unspecified. The root
language label can therefore be used as the fallback in the event of
no other match but for the specific case where the dialect is
identical to the root language then all unnecessary file name checks
can be skipped.
 
If you’re only providing support for the root languages (pre v1.3):
 
The following  
Within the resource file -.ldf, 
you can identify the file using (new to version 1.3):
 
If  
The resource file can load another resource file 
-.ldf, 
using (new to version 1.3):
 
It may be that you want to load a file depending on the input
encoding. The inputenc package defines
 
If you require the resource file and want to perform
 if it’s loaded at this point or  if it’s
already been loaded then you can use:
 
If you want to load a resource file if it exists (without an
error if it doesn’t exist), then you can use
 
 
The above restriction on the resource files loaded through
 
The polyglossia package has language caption hooks in the form 
 
Instead, tracklang provides a command
to perform this set of conditionals using generic code:
 
Note that this command is enabled through
 
Since captions is a commonly used hook type, there’s 
a shortcut command provided:
 
There may be some hooks, such as  
Note that no expansion is performed on  when appending or
redefining a hook.
 
 
The examples in this section illustrate the above commands.
 
 
This example is for a trivial package called animals.sty
that defines three textual commands:  
Here’s the code for animals.sty:
 
The animals-english.ldf file valid for both the Plain TeX and LaTeX formats contains:
 
This means that if babel or polyglossia are loaded, the
redefinitions are automatically performed whenever the language is
changed, but if there’s no caption mechanism the user can switch
the fixed names using the  
Here’s an example LaTeX document that doesn’t have any caption
hooks:
 
There is some redundancy with the above resource files. Consider the
babel example above. The american dialect is the
first option, so in that case animals-en-US.ldf is loaded
followed by animals-english.ldf. This means that the
 
If this redundancy is an issue (for example, there are so many
redefinitions needed that it significantly slows the document build
process), then it can be addressed with the following modifications.
The animals-en-GB.ldf file is now:
 
Note that polyglossia has a  
 
Earlier, I mentioned the search order for
 
 
 
 
The reason for including just the country code as the  in the 
file search is to allow for region rather than language dependent
settings. For example, suppose I want to write a package that needs
to know whether to use imperial or metric measurements in the
document, but I also want to provide multilingual support. The
language alone won’t tell me whether to use imperial or metric (for
example, the US uses imperial and the UK uses metric for most
product attributes). I could provide ldf files for every
language and region combination, but this would result in a lot
redundancy.
 
 
The example package (regions.sty) below illustrates this.
 
 
 
 
 
 
 
 
 
Here’s an example document that uses this package:
 
This works because the  search looks for the
country code before the root language label. However, this will fail if 
the dialect label is the same as a root language label that has an
associated territory, marked with † in
Table 1.2, as then it will be picked up before the
country code.
 
In the above example, 
regions-CA.ldf is matched rather than
regions-french.ldf, so regions-CA.ldf is loaded by
 
This assumes that there’s a country code ldf file
available. This example needs a little modification to use default
units in case the region is missing:
 
Here’s another document that sets up dialects with
tracklang labels that aren’t recognised by babel.
This means that there’s no corresponding  
 
units: kg, mm, EUR.
 
units: kg, mm, GBP.
 
Note that these mappings aren’t needed if babel
is loaded with the root language labels instead. For example:
 
Some of the predefined tracklang dialects come with
a mapping to the closest matching babel dialect label.
For example, the option ngermanDE listed in
Table 1.3 automatically provides a mapping
to ngerman. Since a tracklang dialect label 
can only map to one babel label, this can be problematic
for synonymous labels such as
british/UKenglish or
american/USenglish. The default mappings used
by tracklang are shown in Table 1.3.
 
 
If you are writing a package that sets up the document languages (rather
than a package that provides multilingual support if the user has
already loaded a language package) then you can load tracklang
and use the commands below to help other packages track your
provided languages. (See also:
Integrating
tracklang.tex into Language Packages.)
 
The tracklang package can be loaded using
 
When using LaTeX, there’s a difference between the two.
The first case prevents tracklang from picking up
the document class options but skips the check for known
language packages. This check is redundant since your package is
the language package, so you need to decide whether or
not to allow the user to set up the localisation information
through the document class options.
 
There’s a hook that, if defined, is performed by
tracklang.sty after the package options have been loaded but
before known language packages are checked:
 
If you prefer  
If you just use  
To integrate tracklang into your language package, you need 
to consider the following steps:
 
If yes, then skip this step. Otherwise create a file with the
relevant  
 
If yes, then skip this step.
 
If your package is setting up a language that tracklang
doesn’t recognise then you will need to define the root language
using  
This usually won’t be the case as tracklang should support all
languages that have an official ISO 639-1 alpha-2 code.
 
If you simply have a different label from tracklang
identifying the root language, then you can just set up your label
as a dialect using  
 
If yes, then skip this step. Otherwise create a file with the
relevant  
 
If no, then skip this step. Otherwise you can use
 
 
 
 
When the user requests a particular dialect through your language
package, you can notify tracklang of this choice using
 
If there’s no matching dialect predefined by tracklang, you
can just use  
If you are providing a captions hook mechanism
in the form  
 
When the document author switches to a different language or
dialect, the current localisation information can be set with:
 
This will make the following commands available which may be
of use to other packages:
 
 
 
 
 
 
 
 
 
 
 
 
The tracklang-scripts.tex file isn’t automatically loaded,
but if it is then, as from v1.4, it contains a hook at the end of
the file that can be used to load additional files that define
supplementary scripts. This entails creating a file called, say,
mypackage-scripts.tex that contains:
 
The supplementary file should be identified with:
 
Additional information can be found in §4.
 
 
The tracklang-region-codes.tex file isn’t automatically loaded,
but if it is then, as from v1.4, it contains a hook at the end of
the file that can be used to load additional files that define
supplementary regions. This entails creating a file called, say,
mypackage-regions.tex that contains:
 
The supplementary file should be identified with:
 
Additional information can be found in §4.
 
 
(New to version 1.3.)
If the root language isn’t recognised by tracklang
(not listed in Table 1.2), then
it can be defined (but not tracked at this point) using:
 
You can then track this language using: 
 
 
A dialect label may be predefined with associated information that
allows that particular combination to be easily tracked with
 
If the dialect label doesn’t match the root language label then use:
 
For compatibility with pre version 1.3, 
if the dialect isn’t predefined by
tracklang, then you can use:
 
(New to version 1.3.) Many of the tracklang dialect
labels don’t have a corresponding match in various language packages. For 
example, tracklang provides ngermanDE but the
closest match in babel is ngerman. This means that
the caption hook  
(New to version 1.3.)
If the root language label is recognised by tracklang, you
can add the ISO codes using:
 
As from v1.3, you can also provide a modifier for a given
dialect using:
 
Note that no sanitization is performed on  when the
modifier is set explicitly through  
The modifier is typically obtained by parsing locale information in
POSIX format.
 
The information provided in the commands below (such as the script)
are typically obtained by parsing the language tag. For example,
with Serbian in the Latin alphabet the modifier would be latin
whereas the script would be Latn:
 
As from v1.3, you can provide a script (for example,
Latn or Cyrl) using:
 
As from v1.3, you can provide a variant for a given
dialect using:
 
As from v1.3, you can also provide a sub-language using:
 
As from v1.3, you can also provide additional information using:
 
 
Suppose I want to create a language package alien.sty that defines the
martian language with regional dialects
lowermartian and uppermartian. First, let’s
suppose that tracklang recognises the root language
martian:
 
The resource files may need to set the mapping between the
tracklang dialect label and the alien dialect
label. For example, in alien-xx-YY.ldf:
 
Now let’s consider the case where tracklang doesn’t know
about the martian language. In this case the user can’t 
track the dialect until the root language has been defined, so the
user can’t use  
With tracklang v1.3. The new root language can be defined
with a minor adjustment to the above code:
 
Now other package writers who want to provide support
for the Martian dialects can easily detect which language options
the user requested through my package, without needing to know
anything about my alien package.
 
 
 
 
Region mappings are listed in Table A.1, and
script mappings are listed in Table A.2.
 
 
 
 
Provided by tracklang.sty to declare  as a package option that tracks . Provided by tracklang.tex, if not already defined, to ignore its argument. §3; 19
 
 
 
If defined before tracklang.sty v1.3.8+ is loaded, this command will be done after package options have been processed but before the check for language packages, such as babel and polyglossia. §6; 72
 
 
Adds the ISO 3166-1 code.
 
 
Tracks a dialect. This command defines  
 
Adds a mapping between the given ISO code and language name.
 
 
Shortcut for  
 
Adds the ISO 639-1, 639-2 and 639-3 codes, which must have previously been declared using  
 
Expands to  if there are any tracked languages, otherwise expands to . §5; 35
 
 
Expands to  if there are any tracked regions, otherwise expands to . §5; 36
 
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Defined by  
 
Expands to the current tracked tag. §5; 45
 
 
Iterates through the list of tracked dialects. On each iteration  is set to the dialect tag and  is performed. §5; 37
 
 
Iterates through the list of tracked languages. On each iteration  is set to the language tag and  is performed. §5; 37
 
 
Iterates through the list of tracked regions. On each iteration  is set to the region code and  is performed. §5; 37
 
 
Expands to the extra information for . §5; 44
 
 
Finds the tracked dialect that matches the given language tag and stores the dialect label in . If no match found,  will be empty. §5; 36
 
 
Expands to the modifier for the given dialect. §5; 41
 
 
Expands to the script for . §5; 42
 
 
Expands to the sub-language for . §5; 44
 
 
Expands to the modifier for . §5; 42
 
 
Gets the language tag for . §5; 40
 
 
Expands to  if there’s extra information for , otherwise expands to . §5; 44
 
 
Expands to  if there’s a modifier for the given dialect, otherwise expands to . §5; 41
 
 
Expands to  if there’s a script for , otherwise expands to . §5; 43
 
 
Expands to  if there’s a sub-language for , otherwise expands to . §5; 44
 
 
Expands to  if there’s a modifier for , otherwise expands to . §5; 42
 
 
Does  if the dialect identified by  has been tracked, otherwise does . §5; 38
 
 
If the given tracked dialect has an associated script and that script code matches the replacement text for the control sequence  then do  otherwise to . If the tracked dialect doesn’t have an associated script then the default script for the root language is tested. §5; 43
 
 
Does  if the given ISO code has been defined otherwise does . §5; 39
 
 
Does  if the language identified by  has been tracked, otherwise does . §5; 38
 
 
Does  
 
As  
 
As  
 
As  
 
Does  if the given language or dialect has a corresponding ISO code of the given type, otherwise does . §5; 39
 
 
Conditional that indicates whether or not to show information messages.
 
 
Conditional that indicates whether or not to show verbose messages.
 
 
Conditional that indicates whether or not to show warnings.
 
 
Sets the current tracked dialect. §6.2; 74
 
 
Sets the extra information for  to . §6.6; 80
 
 
Defines a mapping between a tracklang dialect label and the corresponding dialect label used by a language hook, such as  
 
Sets the modifier for the given  to . §6.6; 78
 
 
Sets the script for  to . §6.6; 79
 
 
Sets the sub-language for  to . §6.6; 80
 
 
Sets the modifier for  to . §6.6; 79
 
 
Expands to 639-3 (should not be redefined). §5; 40
 
 
Expands to 639-2 (should not be redefined). §5; 40
 
 
Defined by  
 
Expands to a comma-separated list of the tracked dialects with the given language. §5; 39
 
 
Expands to the code associated with the given language or dialect identified by . §5; 40
 
 
Expands to the language from the given dialect. §5; 39
 
 
Expands to a comma-separated list of language or dialect labels associated with the given code. §5; 39
 
 
As  
 
Adds  to the list of extra region code files that should be input by tracklang-region-codes.tex. §4; 31
 
 
Adds  to the list of files that should be input by tracklang-scripts.tex. §4; 33
 
 
A shortcut that just does  
 
For use within resource files, this can be used to add  to the appropriate hook. §5; 55
 
 
Expands to the numeric code corresponding to the given alpha-3 code. §4; 30
 
 
Expands to the numeric code corresponding to the given alpha-2 code. §4; 30
 
 
Defines a predefined dialect label that can be used by  
 
Defines a new root language that’s declared as an option.
 
 
Expands to  
 
May be defined using the same format as  
 
Set by  
 
Set by  
 
Set by  
 
Set by  
 
Queries environment variable if  
 
Expands to the default script for the given language. §5; 43
 
 
Expands to the ISO 3166-1 country code for the given language.
 
 
Expands to the ISO 639-2 language code associated with .
 
 
Expands to the ISO 639-2 (B) language code associated with .
 
 
Expands to the ISO 639-1 language code associated with .
 
 
Expands to the root language label from the given ISO code (639-1 or 639-2 or 639-3).
 
 
Does  if the argument is a single alphanumeric character otherwise does .
 
 
Does  if the given language has a default script (but is not necessarily tracked), otherwise does .
 
 
Does  if the given language has an ISO 3166-1 country code (but is not necessarily tracked), otherwise does .
 
 
Expands to  if there’s a known mapping for the given , otherwise expands to . §4; 31
 
 
Expands to  if there’s a known mapping for the given alpha-2 region code, otherwise expands to . §4; 30
 
 
Does  if  has an ISO 639-2 code (but is not necessarily tracked), otherwise does .
 
 
Does  if  has an ISO 639-2 (B) code (but is not necessarily tracked), otherwise does .
 
 
Does  if  has an ISO 639-1 code (but is not necessarily tracked), otherwise does .
 
 
Does  if  is known (but not necessarily tracked), otherwise does .
 
 
Does  if the given language code (639-1 or 639-2 or 639-3) is recognised (but not necessarily tracked), otherwise does .
 
 
Expands to  if there’s a known mapping for the given numeric region code, otherwise expands to . §4; 30
 
 
Does  if the argument is a language tag otherwise does .
 
 
Does  if the argument is a region tag otherwise does .
 
 
Does  if the argument is a script tag otherwise does .
 
 
Does  if the argument is a variant tag otherwise does .
 
 
Expands to the label of the last tracked dialect. §6.5; 77
 
 
Identifies a new language that may be tracked. Apart from , the other arguments may be empty if the information is unavailable. §6.5; 76
 
 
Expands to the alpha-3 code corresponding to the given numeric code. §4; 31
 
 
Expands to the alpha-2 code corresponding to the given numeric code. §4; 30
 
 
Attempts to obtain locale information from the expansion of  
 
Defines a predefined dialect label that can be used by  
 
Sets up a language label for use with  
 
Analogous to  
 
Attempts to obtain locale information from the  
 
Attempts to obtain locale information from the  
 
Similar to  
 
Establishes a mapping between a numeric region code and alpha-2 and alpha-3 codes. §4; 31
 
 
As  
 
Loads the dialect for the given package using  
 
Loads the dialect for the given package using  
 
Loads the dialect for the given package using  
 
Loads the dialect for the given package using  
 
Defined by  
 
Loads the appropriate ldf file if it hasn’t already been loaded. §5; 54
 
 
As  
 
Expands to the direction associated with the given alpha script code. §4; 32
 
 
Expands to the name associated with the given alpha script code. §4; 32
 
 
Expands to the numeric script code corresponding to the given alpha code. §4; 32
 
 
Set by  
 
Expands to the parent of the given alpha script code. §4; 33
 
 
Expands to  if the given alpha script code has a parent otherwise expands to . §4; 33
 
 
Expands to  if there’s a known mapping for the given alpha script code otherwise expands to . §4; 32
 
 
Expands to  if there’s a known mapping for the given numeric script code otherwise expands to . §4; 32
 
 
Defines a mapping between an alpha code and a numeric code. §4; 32
 
 
Expands to the alpha script code corresponding to the given numeric code. §4; 32
 
 
Sets the parent for the given alpha script code. §4; 33
 
 
Sets  
 
Sets  
 
Parse , which should be a regular, well-formed RFC 5646 language tag (not an irregular grandfather tag) and track the dialect. Note that the tag must start with a language identifier and can’t simply be a region code. §3; 21
 
 
Tracks the dialect identified by the given , which may either be a predefined language/dialect or in the same format as  
 
Tracks a predefined language or dialect. §3; 20
 
 
Expands to 3166-1 (should not be redefined). §5; 40
 
 
Expands to 639-1 (should not be redefined). §5; 40
 
 
Any dialect label listed in Table 1.1 may be used as a package option.
 
 
Any ISO tag listed in Table 1.1 may be used as a package option.
 
 
Switches off verbose setting (default). §3; 19
 
 
Switches off warning setting. §3; 19
 
 
Switches on verbose setting. §3; 19
 
 
Switches on warning setting (default). §3; 19
 
 
 
List of Tables[link]
1. Introduction[link]
\LocaleForEach and, if defined, will
use that command to iterate over all languages that have currently
been loaded either via package option or using \babelprovide.
Note that “lazy loading” a language via \selectlanguage
in the document is too late for tracklang to detect.
\xpg@bcp@loaded is defined and, if so, will iterate over that
list. Older versions of babel and polyglossia that lack
these convenient commands are much harder for tracklang to
work with.
is equivalent to
\usepackage[british]{translator}
\usepackage{tracklang}
This means that \usepackage[british]{translator}
\usepackage[english,british]{tracklang}
\ForEachTrackedDialect will iterate
through the list “english,british” instead of just
“british”, which can result in some redundancy.
then the dialect list will just consist of “british” rather than
“english,british”. This does, however, mean that if the user mixes
class and package options, only the class options will be detected.
For example:
\documentclass[british]{article}
\usepackage{translator}
\usepackage{tracklang}
In this case, only the british option will be detected. The user
can therefore use the document class option (or tracklang
package option) to override the dialect and set the country code
(where provided). For example:
\documentclass[british]{article}
\usepackage[french]{babel}
\usepackage{tracklang}
This sets the dialect to mexicanspanish and the root language to
spanish. 
\documentclass[es-MX]{article}
\usepackage[spanish]{babel}
\usepackage{tracklang}
\TrackPredefinedDialect, as illustrated above. 
\TrackPredefinedDialect)
 
ISO Tag 
Dialect Label 
ISO Tag 
Dialect Label 
 
cy-GB 
GBwelsh
 de-AT 
austrian 
 
de-AT-1996 
naustrian
 de-BE 
belgiangerman 
 
de-CH 
swissgerman
 de-CH-1996 
nswissgerman 
 
de-DE 
germanDE
 de-DE-1996 
ngermanDE 
 
en-AU 
australian
 en-CA 
canadian 
 
en-GB 
british
 en-GG 
guernseyenglish 
 
en-IE 
IEenglish
 en-IM 
isleofmanenglish 
 
en-JE 
jerseyenglish
 en-MT 
maltaenglish 
 
en-NZ 
newzealand
 en-US 
american 
 
es-AR 
argentinespanish
 es-BO 
bolivianspanish 
 
es-CL 
chilianspanish
 es-CO 
columbianspanish 
 
es-CR 
costaricanspanish
 es-CU 
cubanspanish 
 
es-DO 
dominicanspanish
 es-EC 
ecudorianspanish 
 
es-ES 
spainspanish
 es-GT 
guatemalanspanish 
 
es-HN 
honduranspanish
 es-MX 
mexicanspanish 
 
es-NI 
nicaraguanspanish
 es-PA 
panamaspanish 
 
es-PE 
peruvianspanish
 es-PR 
puertoricospanish 
 
es-PY 
paraguayspanish
 es-SV 
elsalvadorspanish 
 
es-UY 
uruguayspanish
 es-VE 
venezuelanspanish 
 
fr-BE 
belgique
 fr-CA 
canadien 
 
fr-CH 
swissfrench
 fr-FR 
france 
 
fr-GG 
guernseyfrench
 fr-JE 
jerseyfrench 
 
ga-GB 
GBirish
 ga-IE 
IEirish 
 
gd-GB 
GBscottish
 hr-HR 
croatia 
 
hu-HU 
hungarian
 id-IN 
bahasa 
 
it-CH 
swissitalian
 it-HR 
istriacountyitalian 
 
it-IT 
italy
 it-SI 
sloveneistriaitalian 
 
it-SM 
sanmarino
 it-VA 
vatican 
 
ms-MY 
malay
 mt-MT 
maltamaltese 
 
nl-BE 
flemish
 nl-NL 
netherlands 
 
pt-BR 
brazilian
 pt-PT 
portugal 
 rm-CH 
swissromansh
 sl-SI 
slovenia Other combinations need to be set with  \TrackLocale
or \TrackLanguageTag
\GetTrackedLanguageTag{}
 
abkhaz (ab)
 afar (aa)
 afrikaans (af) 
 
akan (ak)
 albanian (sq)
 amharic† (am-ET) 
 
anglosaxon (ang)
 apache (apa)
 arabic (ar) 
 
aragonese† (an-ES)
 armenian (hy)
 assamese (as) 
 
asturian (ast)
 avaric (av)
 avestan (ae) 
 
aymara (ay)
 azerbaijani (az)
 bahasai† (id-IN) 
 
bahasam† (ms-MY)
 bambara† (bm-ML)
 bashkir (ba) 
 
basque (eu)
 belarusian (be)
 bengali (bn) 
 
berber (ber)
 bihari (bh)
 bislama† (bi-VU) 
 
bokmal† (nb-NO)
 bosnian (bs)
 breton† (br-FR) 
 
bulgarian (bg)
 burmese (my)
 catalan (ca) 
 
chamorro (ch)
 chechen (ce)
 chichewa (ny) 
 
chinese (zh)
 churchslavonic (cu)
 chuvash† (cv-RU) 
 
coptic (cop)
 cornish† (kw-GB)
 corsican (co) 
 
cree (cr)
 croatian (hr)
 czech (cs) 
 
danish (da)
 divehi† (dv-MV)
 dutch (nl) 
 
dzongkha† (dz-BT)
 easternpunjabi† (pa-IN)
 english (en) 
 
esperanto (eo)
 estonian (et)
 ewe (ee) 
 
faroese (fo)
 farsi (fa)
 fijian† (fj-FJ) 
 
finnish (fi)
 french (fr)
 friulan† (fur-IT) 
 
fula (ff)
 galician (gl)
 ganda† (lg-UG) 
 
georgian (ka)
 german (de)
 greek (el) 
 
guarani (gn)
 gujarati (gu)
 haitian† (ht-HT) 
 
hausa (ha)
 hebrew (he)
 herero (hz) 
 
hindi (hi)
 hirimotu† (ho-PG)
 icelandic† (is-IS) 
 
ido (io)
 igbo (ig)
 interlingua (ia) 
 
interlingue (ie)
 inuktitut (iu)
 inupiaq (ik) 
 
irish (ga)
 italian (it)
 japanese (ja) 
 
javanese (jv)
 kalaallisut (kl)
 kannada† (kn-IN) 
 
kanuri (kr)
 kashmiri† (ks-IN)
 kazakh (kk) 
 
khmer (km)
 kikuyu (ki)
 kinyarwanda (rw) 
 
kirundi (rn)
 komi† (kv-RU)
 kongo (kg) 
 
korean (ko)
 kurdish (ku)
 kwanyama (kj) 
 
kyrgyz (ky)
 lao (lo)
 latin (la) 
 
latvian (lv)
 limburgish (li)
 lingala (ln) 
 
lithuanian (lt)
 lsorbian† (dsb-DE)
 lubakatanga† (lu-CD) 
 
luxembourgish (lb)
 macedonian (mk)
 magyar (hu) 
 
malagasy (mg)
 malayalam† (ml-IN)
 maltese (mt) 
 
manx† (gv-IM)
 maori† (mi-NZ)
 marathi† (mr-IN) 
 
marshallese† (mh-MH)
 mongolian (mn)
 nauruan† (na-NR) 
 
navajo† (nv-US)
 ndonga (ng)
 nepali (ne) 
 
nko (nqo)
 norsk (no)
 northernndebele (nd) 
 
northernsotho (nso)
 nuosu† (ii-CN)
 nynorsk† (nn-NO) 
 
occitan (oc)
 ojibwe (oj)
 oriya (or) 
 
oromo (om)
 ossetian (os)
 pali (pi) 
 
pashto (ps)
 piedmontese† (pms-IT)
 polish (pl) 
 
portuges (pt)
 quechua (qu)
 romanian (ro) 
 
romansh† (rm-CH)
 russian (ru)
 samin (se) 
 
samoan (sm)
 sango (sg)
 sanskrit (sa) 
 
sardinian† (sc-IT)
 scots (sco)
 scottish (gd) 
 
serbian (sr)
 shona (sn)
 sindhi (sd) 
 
sinhalese† (si-LK)
 slovak (sk)
 slovene (sl) 
 
somali (so)
 southernndebele† (nr-ZA)
 southernsotho (st) 
 
spanish (es)
 sudanese (su)
 swahili (sw) 
 
swati (ss)
 swedish (sv)
 syriac (syr) 
 
tagalog† (tl-PH)
 tahitian† (ty-PF)
 tai (tai) 
 
tajik (tg)
 tamil (ta)
 tatar (tt) 
 
telugu† (te-IN)
 thai† (th-TH)
 tibetan (bo) 
 
tigrinya (ti)
 tonga† (to-TO)
 tsonga (ts) 
 
tswana (tn)
 turkish (tr)
 turkmen (tk) 
 
twi† (tw-GH)
 ukrainian† (uk-UA)
 undetermined (und) 
 
urdu (ur)
 usorbian† (hsb-DE)
 uyghur† (ug-CN) 
 
uzbek (uz)
 venda† (ve-ZA)
 vietnamese (vi) 
 
volapuk (vo)
 walloon (wa)
 welsh (cy) 
 
westernfrisian† (fy-NL)
 wolof (wo)
 xhosa (xh) 
 
yiddish (yi)
 yoruba (yo)
 zhuang† (za-CN) 
 zulu (zu) 
\GetTrackedLanguageTag{}\captions or
\date, this is also included after the tag following a
slash.
 
acadian (fr)
 american† (en-US)
 argentinespanish† (es-AR) 
 
australian† (en-AU)
 austrian† (de-AT)
 bahasa† (id-IN) 
 
belgiangerman† (de-BE)
 belgique† (fr-BE)
 bolivianspanish† (es-BO) 
 
brazil† (pt-BR)
 brazilian† (pt-BR)
 british† (en-GB) 
 
canadian† (en-CA)
 canadien† (fr-CA)
 chilianspanish† (es-CL) 
 
columbianspanish† (es-CO)
 costaricanspanish† (es-CR)
 croatia† (hr-HR) 
 
cubanspanish† (es-CU)
 cymraeg (cy)
 deutsch (de) 
 
dominicanspanish† (es-DO)
 ecudorianspanish† (es-EC)
 elsalvadorspanish† (es-SV) 
 
flemish† (nl-BE)
 francais (fr)
 france† (fr-FR) 
 
frenchb (fr)
 friulano† (fur-IT)
 friulian† (fur-IT) 
 
furlan† (fur-IT)
 gaeilge (ga)
 gaelic (gd) 
 
galicien (gl)
 GBirish† (ga-GB)
 GBscottish† (gd-GB) 
 
GBwelsh† (cy-GB)
 germanb (de)
 germanDE† (de-DE) 
 
guatemalanspanish† (es-GT)
 guernseyenglish† (en-GG / british)
 guernseyfrench† (fr-GG) 
 
honduranspanish† (es-HN)
 hungarian† (hu-HU)
 IEenglish† (en-IE / british) 
 
IEirish† (ga-IE)
 indon† (id-IN)
 indonesian† (id-IN) 
 
isleofmanenglish† (en-IM / british)
 istriacountycroatian† (hr-HR)
 istriacountyitalian† (it-HR) 
 
italy† (it-IT)
 jerseyenglish† (en-JE / british)
 jerseyfrench† (fr-JE) 
 
kurmanji (ku)
 latein (la)
 lowersorbian† (dsb-DE) 
 
malay† (ms-MY)
 maltaenglish† (en-MT / british)
 maltamaltese† (mt-MT) 
 
mexicanspanish† (es-MX)
 meyalu† (ms-MY)
 naustrian† (de-AT-1996) 
 
nbelgiangerman† (de-BE-1996 / ngerman)
 netherlands† (nl-NL)
 newzealand† (en-NZ) 
 
ngerman (de-1996)
 ngermanb (de-1996 / ngerman)
 ngermanDE† (de-DE-1996 / ngerman) 
 
nicaraguanspanish† (es-NI)
 nil (und)
 norwegian† (no-NO) 
 
nswissgerman† (de-CH-1996 / ngerman)
 panamaspanish† (es-PA)
 paraguayspanish† (es-PY) 
 
persian (fa)
 peruvianspanish† (es-PE)
 piemonteis† (pms-IT) 
 
polutoniko (el)
 polutonikogreek (el)
 portugal† (pt-PT) 
 
portuguese (pt)
 puertoricospanish† (es-PR)
 romanche (rm-CH) 
 
romansch (rm-CH)
 rumantsch (rm-CH)
 russianb (ru) 
 
sanmarino† (it-SM)
 serbianc (sr-Cyrl)
 serbianl (sr-Latn) 
 
sloveneistriaitalian† (it-SI)
 sloveneistriaslovenian† (sl-SI / slovenian)
 slovenia† (sl-SI / slovenian) 
 
slovenian (sl)
 spainspanish† (es-ES)
 swissfrench† (fr-CH) 
 
swissgerman† (de-CH)
 swissitalian† (it-CH)
 swissromansh† (rm-CH) 
 
UKenglish† (en-GB)
 ukraine† (uk-UA)
 ukraineb† (uk-UA) 
 
uppersorbian† (hsb-DE)
 uruguayspanish† (es-UY)
 USenglish† (en-US) 
 
valencian (ca)
 valencien (ca)
 vatican† (it-VA) 
 venezuelanspanish† (es-VE) 2. Summary of Use[link]
\descriptionname or datetime2 to provide localised 
formats or time zone information);
2.1. Document Level[link]
2.1.1. Generic TeX[link]
\input. See §2.1.2 for LaTeX use.
\input tracklang.tex % v1.3
\TrackLangFromEnv
% load packages that use tracklang for localisation
Or (texosquery v1.2)
\input texosquery.tex
\input tracklang.tex % v1.3
\TrackLangFromEnv
% load packages that use tracklang for localisation
A Unix-like user who may or may not have texosquery setup to run in the
shell escape:
\input texosquery.tex % v1.2
\input tracklang.tex % v1.3
\TeXOSQueryLangTag{\langtag}
\TrackLanguageTag{\langtag}
% load packages that use tracklang for localisation
\input texosquery.tex
\input tracklang.tex % v1.3
\ifdefined\TeXOSQueryLangTag
 \TeXOSQueryLangTag{\langtag}
 \TrackLanguageTag{\langtag}
\else
 \TrackLangFromEnv
\fi
% load packages that use tracklang for localisation
\input tracklang.tex % v1.3
\TrackLanguageTag{hy-Latn-IT-arevela}
% load packages that use tracklang for localisation
\input tracklang.tex
\TrackPredefinedDialect{british}
% load packages that use tracklang for localisation
\languagename):
Additional information about the script can be obtained by
also loading tracklang-scripts:
\SetCurrentTrackedDialect{\languagename}
Dialect: \CurrentTrackedDialect.
Language: \CurrentTrackedLanguage.
ISO Code: \CurrentTrackedIsoCode.
Region: \CurrentTrackedRegion.
Modifier: \CurrentTrackedDialectModifier.
Variant: \CurrentTrackedDialectVariant.
Script: \CurrentTrackedDialectScript.
Sub-Lang: \CurrentTrackedDialectSubLang.
Additional: \CurrentTrackedDialectAdditional.
Language Tag: \CurrentTrackedLanguageTag.
The name, numeric code and direction can now be obtained:
\input tracklang-scripts.tex
Name: 
Test for a specific script (in this case Latn):
\TrackLangScriptAlphaToName{\CurrentTrackedDialectScript}.
Numeric: 
\TrackLangScriptAlphaToNumeric{\CurrentTrackedDialectScript}.
Direction: 
\TrackLangScriptAlphaToDir{\CurrentTrackedDialectScript}.
Latin?
\ifx\CurrentTrackedDialectScript\TrackLangScriptLatn
 Yes
\else
 No
\fi
2.1.2. LaTeX[link]
\xpg@bcp@loaded
is defined, you just need to make sure the languages are set before
tracklang is loaded:
For older versions of polyglossia where the regional
information is required, use recognised class options:
\documentclass{article}
\usepackage{polyglossia}
\setmainlanguage[variant=uk]{english}
% load packages that use tracklang for localisation
\documentclass[en-GB]{article}
\usepackage{polyglossia}
\setmainlanguage[variant=uk]{english}
% load packages that use tracklang for localisation
With tracklang v1.6.4+ there is now a check for
\documentclass[british,canadien]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
% load packages that use tracklang for localisation
\LocaleForEach, which allows tracklang to pick up locales
set with \babelprovide. For example:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[british]{babel}
\babelprovide{canadianfrench}
% load packages that use tracklang for localisation
\documentclass[en-IE,ga-IE]{article}
\usepackage[english,irish]{babel}
% load packages that use tracklang for localisation
\TrackLanguageTag and map the new
dialect label to the nearest matching \captions:
This ensures that the \documentclass{article}
\usepackage{tracklang}% v1.3
\TrackLanguageTag{en-MT}
\SetTrackedDialectLabelMap
 {\TrackLangLastTrackedDialect}{UKenglish}
\usepackage[UKenglish]{babel}
% load packages that use tracklang for localisation
\captionsUKenglish hook is detected
by the localisation packages. This mapping isn’t needed
for polyglossia as the caption hooks use the root language
label. This mapping also isn’t needed if british is used
instead of UKenglish since the en-MT
(maltaenglish)
predefined dialect automatically sets up a mapping to
british. (The default mappings are shown in
Table 1.3.)
2.2. Locale-Sensitive Packages[link]
(Most of the commands used in this section require at least
tracklang version 1.3 but 1.4 is better if you want to
include the script tag in the ldf files.)
Note that tracklang.tex has a check to determine if
it’s already been loaded, so you don’t need to worry about that.
\input tracklang.tex
This will picked up any language options supplied in the document
class options and will also detect if babel or
polyglossia have been loaded.
\RequirePackage{tracklang}[2019/11/30]% at least v1.4
This means the user can do, say,
\DeclareOption*{\TrackLanguageTag{\CurrentOption}}
With at least version 1.4, it’s better to use \usepackage[hy-Latn-IT-arevela]{mypackage}
\TrackIfKnownLanguage:
\DeclareOption*{% 
 \TrackIfKnownLanguage{\CurrentOption}% 
 {% successful
  \PackageInfo{mypackage}{Tracking language `\CurrentOption'}% 
 }% 
 {% failed
  \PackageError{mypackage}% 
  {Unknown language specification `\CurrentOption'}% 
  {You need to supply either a known dialect label 
   or a valid language tag}% 
 }% 
}
\def and
\ifx with more appropriate LaTeX commands.
\AnyTrackedLanguages
{}
{% fetch locale information from the operating system
  \ifdefined\TeXOSQueryLangTag
    % texosquery v1.2 available
    \TeXOSQueryLangTag{\langtag}
    \TrackLanguageTag{\langtag}
  \else
    % texosquery v1.2 not available
    \TrackLangFromEnv
  \fi
}
\def\fooname{Foo}
\def\barname{Bar}
\AnyTrackedLanguages
{% 
  \ForEachTrackedDialect{\thisdialect}{% 
    \TrackLangRequireDialect{mypackage}{\thisdialect}% 
  }% 
}
{}% no tracked languages, default already set up
\IfTrackedLanguageFileExists below for further
details.)
% identify this file:
This sets up appropriate the \TrackLangProvidesResource{english}[2016/10/06 v1.0]
\TrackLangAddToCaptions{% 
  \def\fooname{Foo}% 
  \def\barname{Bar}% 
}
\captions hook (if it’s
found). For other hooks, such as \date, use 
\TrackLangAddToHook or \TrackLangRedefHook instead.
\CurrentTrackedDialectScript).
Here’s an example for a language with different writing systems.
The resource file for Serbian mypackage-serbian.ldf:
% identify file:
The file mypackage-serbian-Latn.ldf sets up
the Latin script (Latn):
\TrackLangProvidesResource{serbian}[2016/10/06 v1.0]
\TrackLangRequestResource{serbian-\CurrentTrackedDialectScript}
{}% file not found, do something sensible here
The file mypackage-serbian-Cyrl.ldf sets up
the Cyrillic script (Cyrl):
\TrackLangProvidesResource{serbian-Latn}[2016/10/06 v1.0]
\TrackLangAddToCaptions{% 
  \def\fooname{...}% provide appropriate Latin translations
  \def\barname{...}% 
}
With v1.4+ you just need mypackage-sr-Latn.ldf and
mypackage-sr-Cyrl.ldf for the regionless versions.
\TrackLangProvidesResource{serbian-Cyrl}[2016/10/06 v1.0]
\TrackLangAddToCaptions{% 
  \def\fooname{...}% provide appropriate Cyrillic translations
  \def\barname{...}% 
}
2.3. Language Packages[link]
Alternative LaTeX use:
\input tracklang
Unlike \RequirePackage{tracklang}[2019/11/30]% v1.4
\input, \RequirePackage will allow tracklang
to pick up the document class options, but using \RequirePackage
will also trigger the tests for known language packages.
(If you want to find out if tracklang has already been
loaded and locales have already been tracked, you can use the
same code as in the previous section.)
\TrackPredefinedDialect or \TrackLanguageTag.
For example, if the user requests british, that’s a
predefined dialect so you can just do:
Alternatively
\TrackPredefinedDialect{british}
If your package uses caption hooks, then you can set up 
a mapping between tracklang’s internal dialect label
and your caption label. For example, let’s suppose the
closest match to English used in Malta (en-MT) is the 
dialect UKenglish (for example, the date format is 
similar between GB and MT):
\TrackLanguageTag{en-GB}
(The predefined maltaenglish option provided by
tracklang automatically sets the mapping to
british, but the above method will change that mapping
to UKenglish.)
\TrackLanguageTag{en-MT}
\SetTrackedDialectLabelMap{\TrackLangLastTrackedDialect}{UKenglish}
\def\captionsUKenglish{% 
  \def\contentsname{Contents}% 
  % ...
}
\TrackLangAddToHook and \TrackLangRedefHook commands can
find your language hooks. You don’t need the map if your dialect
label is the same as tracklang’s root language label
for that locale. For example:
\TrackLanguageTag{en-MT}
\def\captionsenglish{% 
  \def\contentsname{Contents}% 
  % ...
}
\selectlanguage it would be useful to also use
\SetCurrentTrackedDialect{}\SetTrackedDialectLabelMap. It
may also be the root language label, in which case
tracklang will search for the last dialect to be
tracked with that language. For example:
See the example in §2.1 or the example in 
Integrating
tracklang.tex into Language Packages.
\def\selectlanguage#1{% 
  \SetCurrentTrackedDialect{#1}% 
  % set up hyphenation patterns etc
}
3. Generic Use[link]
or for TeX formats that have an argument form for \input tracklang
\input:
As from version 1.3, you don’t need to change the category
code of \input{tracklang}
@ before loading tracklang.tex
as it will automatically be changed to 11 and switched
back at the end (if required).
If \DeclareOption{}{\TrackPredefinedDialect{}}
\@tracklang@declareoption isn’t defined when
tracklang.tex is input, it will be defined to ignore its
argument.
\@tracklang@declareoption
to use something analogous to \DeclareOption, if appropriate.
Otherwise, the document languages need
to be explicitly identified (using any of the following commands)
so that tracklang knows about them.
is the Plain TeX alternative to:
\input tracklang
\TrackPredefinedDialect{british}
\documentclass[british]{article}
\usepackage{tracklang}
\TrackPredefinedDialect, otherwise 
needs to be in one the following formats:
where  is the ISO 639-1 or 639-2 code identifying
the language (lower case),  is the 3166-1
ISO code identifying the territory (upper case) and 
 is the modifier or variant. The hyphen
(-) may be replaced by an underscore character 
(_). Code-set information in the
form .de (modifier is
new) or -DE.utf8@newen (modifier is missing).
The code-set will be ignored if present, but it won’t interfere
with the parsing.
-GB.utf8
indicates German in Namibia using the new spelling.
\TrackLocale{de-NA@new}
deu may be used instead of de, but ger
won’t be recognised.)
\TrackLanguageTag and \TrackIfKnownLanguage will check if
 is a predefined option. (This saves parsing the tag if
it’s recognised.)
This will track hy-Latn-IT-arevela and brazilian
(pt-BR) but not Latn-ME (because it doesn’t contain a
valid language code) even though it’s a valid script and country
code. The above is just for illustrative purposes. Typically the
language tracking isn’t performed within the document text.
\TrackLanguageTag{hy-Latn-IT-arevela}
Latn-ME: \TrackIfKnownLanguage{Latn-ME}{success}{fail}.
brazilian: \TrackIfKnownLanguage{brazilian}{success}{fail}.
but users can make mistakes sometimes and this won’t provide any
helpful information if they, for example, misspelt a package option
or forgot the “=” part of a = setting. Instead (as from v1.5.5) datetime2 now does:
\TrackLanguageTag{\CurrentOption}
This will now give the user some guidance. 
\TrackIfKnownLanguage{\CurrentOption}
{...}% known language
{\PackageError{...}{...}{...}}
creates a new dialect with the label \TrackLanguageTag{zh-cmn-Hans-CN}
zhcmnHansCN.
The root language chinese has the 639-1 code
zh and the dialect zhcmnHansCN has the
ISO 639-3 code cmn.
ISO 639-1: 
\TrackedIsoCodeFromLanguage{639-1}{chinese}.
ISO 639-3: \TrackedIsoCodeFromLanguage{639-3}{zhcmnHansCN}.
\TeXOSQueryLangTag,
which may be used to fetch the operating system’s regional
information as a language tag. These commands can be used as
follows:
(If the shell escape is disabled, \input tracklang % v1.3
\input texosquery % v1.2
\TeXOSQueryLangTag{\langtag}
\TrackLanguageTag{\langtag}
\langtag will be empty, which
will trigger a warning but no errors.)
\TrackLocale is used with just the language ISO code,
no region is tracked for that language. For example
will track the IM (Isle of Man) ISO 3166-1 code but
\TrackLocale{manx}
won’t track the region.
Similarly for \TrackLocale{gv}
\TrackLanguageTag.
\TrackLocale that doesn’t take an argument:
\directlua is
available, this will try to get the language information from the
system environment variables LC_ALL or LANG and, if
successful, track that.
C or
POSIX or starts with a forward slash / then
the locale value is treated as empty.
\TeXOSQueryLocale as a fallback if
texosquery has been loaded. Since texosquery requires
both the shell escape and the Java runtime environment,
tracklang doesn’t automatically load it.
Document build:
\input texosquery
\input tracklang
\TrackLangFromEnv
etex --shell-escape 
Document build:
\usepackage{texosquery}
\usepackage{tracklang}
\TrackLangFromEnv
pdflatex --shell-escape 
LANG set to 
en on my Linux system so instead of
_GB.utf8
I can use
\TrackPredefinedDialect{british}
\TrackLangFromEnv
However, this only helps subsequently loaded packages that
use tracklang to determine the required regional 
settings. For example:
\documentclass{article}
\usepackage{tracklang}
\TrackLangFromEnv
In my case, with the \documentclass{article}
\usepackage{tracklang}
\TrackLangFromEnv
\usepackage[useregional]{datetime2}
LANG environment variable set to
en and the
shell escape enabled, this automatically switches on the 
en-GB date style.
Naturally this doesn’t help locale-sensitive packages that don’t use
tracklang.
_GB.utf8\TrackLangFromEnv command also incidentally sets
\TrackLangEnv
to the value of the environment variable or empty if the
query was unsuccessful (for example, the shell escape is
unavailable).
\TrackLangFromEnv is used, then the
environment variable won’t be queried and the value of
\TrackLangEnv will be parsed instead.
_ with its usual category code 8, then tries splitting 
on a hyphen - with category code 12, and then tries 
splitting on the underscore _ with category code 12.
This doesn’t perform a shell escape since \def\TrackLangEnv{en-GB}
\TrackLangFromEnv
\TrackLangEnv
is already defined. In this case, you may just as well use:
(unless you happen to additionally require the component
commands that are set by \TrackLocale{en-GB}
\TrackLangFromEnv, see below.)
tex "
\\def\\TrackLangEnv{$LANG}\\input myDoc"
\TrackLangFromEnv command also happens to store the
component parts of the environment variable value in the
following commands. (These aren’t provided by \TrackLocale.)
If the information is unavailable, the relevant commands will be set
to empty.
\TrackLangEnv (empty if 
unsuccessful). Unlike \TrackLangFromEnv, this doesn’t check if
\TrackLangEnv already exists. A warning will occur if the shell
escape is unavailable. For systems that store the locale information in
environment variables, this is more efficient than using
texosquery’s \TeXOSQueryLocale command (which is what’s
used as the fallback).
LC_ALL and, if that is unsuccessful,
then queries LANG (before optionally falling back on 
texosquery). If you want another environment
variable tried after LC_ALL and before LANG,
you can instead use:
LC_MONETARY:
\TrackLangQueryOtherEnv{LC_MONETARY}
\TrackLangEnv, you can use it before
\TrackLangFromEnv. For example:
Remember that if you only want to do the shell escape if
\TrackLangQueryOtherEnv{LC_MONETARY}
\TrackLangFromEnv
\TrackLangEnv hasn’t already been defined, you can test for this
first:
\ifdefined\TrackLangEnv
\else
  \TrackLangQueryOtherEnv{LC_MONETARY}
\fi
\TrackLangFromEnv
\TrackLangEnv
without tracking the result using:
\TrackLangFromEnv but assumes that 
\TrackLangEnv has already been set and doesn’t track the 
result. The component parts are stored as for \TrackLangFromEnv.
This produces:
\input tracklang
\def\TrackLangEnv{fr-BE.utf8@euro}
\TrackLangParseFromEnv
Language: \TrackLangEnvLang.
Territory: \TrackLangEnvTerritory.
Codeset: \TrackLangEnvCodeSet.
Modifier: \TrackLangEnvModifier.
Any tracked languages? \AnyTrackedLanguages{Yes}{No}.
This produces:
\input tracklang
\def\TrackLangEnv{fr-BE.utf8@euro}
\TrackLangFromEnv
Language: \TrackLangEnvLang.
Territory: \TrackLangEnvTerritory.
Codeset: \TrackLangEnvCodeSet.
Modifier: \TrackLangEnvModifier.
Any tracked languages? \AnyTrackedLanguages{Yes}{No}.
Tracked dialect(s):% 
\ForEachTrackedDialect{\thisdialect}{\space\thisdialect}.
\TrackLangFromEnv doesn’t recognise the given language and
territory combination, it will define a new dialect and add that.
en-BE, so
the sample document below defines a new dialect labelled
enBEeuro:
This now produces:
\input tracklang
\def\TrackLangEnv{en-BE.utf8@euro}
\TrackLangFromEnv
Language: \TrackLangEnvLang.
Territory: \TrackLangEnvTerritory.
Codeset: \TrackLangEnvCodeSet.
Modifier: \TrackLangEnvModifier.
Any tracked languages? \AnyTrackedLanguages{Yes}{No}.
Tracked dialect(s):% 
\ForEachTrackedDialect{\thisdialect}{\space\thisdialect}.
4. Supplementary Packages[link]
\TrackLanguageTag
encounters a numeric region code, it will automatically input
tracklang-region-codes.tex, if it hasn’t already been input.
This file provides the following commands.
There’s a simple wrapper package tracklang-scripts.sty for
LaTeX users:
\input tracklang-scripts
\usepackage{tracklang-scripts}
\IfTrackedDialectIsScriptCs.
\TrackLangScriptSetParent then it will be
considered defined, but if the  argument was empty in 
\TrackLangScriptMap, then it will be undefined.
5. Detecting the User’s Requested Languages[link]
\TrackLocale or \TrackLangFromEnv are used and the locale
isn’t recognised a new dialect is created with the label formed from
the ISO codes (and modifier, if present). 
Similarly for \TrackLanguageTag a new
dialect is created with a label that’s essentially the language tag
without the hyphen separators. For example, 
will add a new dialect with the label \TrackLocale{xx-YY}
xxYY,
will add a new dialect with the label \TrackLocale{xx-YY@mod}
xxYYmod and 
will add a new dialect with the label \TrackLanguageTag{xx-Latn-YY}
xxLatnYY.
\TrackLocale or \TrackLangFromEnv find a modifier, the 
value will be sanitized to allow it to be used as a label. If the
modifier is set explicitly using \SetTrackedDialectModifier, 
no sanitization is performed.
The check for ngerman/german is retained
for backward-compatibility.\LocaleForEach is defined (babel),
tracklang will use it to iterate over each dialect label
and fetch the associated BCP 47 tag;
\bbl@loaded is defined (babel), tracklang
will iterate over each label in that command definition;
\trans@languages is defined (translator), 
tracklang will iterate over each label in that command
definition;
\xpg@bcp@loaded has been defined, tracklang
will iterate over the BCP 47 tags in that command definition;
\xpg@loaded has been defined, tracklang will
iterate over each language label in that command definition;
\GetTrackedDialectFromLanguageTag).
This will be empty if no tracked dialects match on the root
language or if there’s a tracked dialect label that exactly matches
the label formed by concatenating the language code, sub-language,
script, region, modifier and variant.
This matches because the territory code 826 is recognised as
equivalent to the code GB, and the default script for
english is Latn. In this case, the dialect
label is british. Note that this doesn’t require
the use of \input tracklang
\TrackLanguageTag{en-826}
Has en-Latn-GB been tracked?
\GetTrackedDialectFromLanguageTag{en-Latn-GB}{\thisdialect}% 
\ifx\thisdialect\empty
 No!
\else
 Yes! Dialect label: \thisdialect.
\fi
\bye
\TrackLanguageTag to track the dialect. 
It also works if the dialect has been tracked using other commands,
such as \TrackLocale.
In this case the result is:
\input tracklang
\TrackLanguageTag{de-CH-1996}
Has de-DE-1996 been tracked?
\GetTrackedDialectFromLanguageTag{de-DE-1996}{\thisdialect}% 
\ifx\thisdialect\empty
 No!
  \ifx\TrackedDialectClosestSubMatch\empty
    No match on root language.
  \else
    Closest match: \TrackedDialectClosestSubMatch.
  \fi
\else
 Yes! Dialect label: \thisdialect.
\fi
\bye
\@for loop. Since this isn’t defined by TeX, a similar command
(\@tracklang@for) will be defined that works in the same way.
\@nil. This
special control sequence should never been used as it’s just a
marker and isn’t actually defined. If you get an error message
stating that \@nil is undefined, then it’s most likely due to a
loop control sequence being used outside the loop. This can occur if
the loop contains code that isn’t expanded until later. For example,
if the loop code includes \AtBeginDocument, you need to ensure
that the loop control sequence is expanded before being added to the
hook.
This produces:
\documentclass[british,dutch]{article}
\usepackage{tracklang}
\begin{document}
``english'' \IfTrackedDialect{english}{has}{hasn't} been specified.
``british'' \IfTrackedDialect{british}{has}{hasn't} been specified.
``flemish'' \IfTrackedDialect{flemish}{has}{hasn't} been specified.
``dutch'' \IfTrackedDialect{dutch}{has}{hasn't} been specified.
``english'' or an English variant 
\IfTrackedLanguage{english}{has}{hasn't} been specified.
\end{document}
\TrackLanguageTag.
\TrackedLanguageFromIsoCode, this
command only expands to a single label rather than a comma-separated
list.
\TrackLanguageTag.
\Get… commands below are designed to be expandable.
If the supplied  is unrecognised they expand to empty.
Remember that the dialect must first be identified as a tracked 
language for it to be recognised.
\TrackLocale or \TrackLangFromEnv but may be set explicitly.
(See §6 for setting this value. Likewise for
the following commands.)
This produces:
\documentclass[british,francais,american,canadian,canadien,dutch]{article}
\usepackage{tracklang}
\begin{document}
Languages:
\ForEachTrackedLanguage{\ThisLanguage}{\ThisLanguage\space
(ISO \TwoLetterIsoLanguageCode: 
``\TrackedIsoCodeFromLanguage
    {\TwoLetterIsoLanguageCode}{\ThisLanguage}''). }
Dialects:
\ForEachTrackedDialect{\ThisDialect}{\ThisDialect\space 
(\IfTrackedLanguageHasIsoCode
  {\TwoLetterIsoCountryCode}{\ThisDialect}% 
 {ISO \TwoLetterIsoCountryCode: 
  ``\TrackedIsoCodeFromLanguage
      {\TwoLetterIsoCountryCode}{\ThisDialect}''} {no specific region};
root: \TrackedLanguageFromDialect{\ThisDialect}). }
Language for ISO \TwoLetterIsoCountryCode\ ``GB'':
\TrackedLanguageFromIsoCode
  {\TwoLetterIsoCountryCode}{GB}.
Language for ISO \TwoLetterIsoCountryCode\ ``CA'': 
\TrackedLanguageFromIsoCode
  {\TwoLetterIsoCountryCode}{CA}.
Country ISO \TwoLetterIsoCountryCode\ code for ``canadian'':
\TrackedIsoCodeFromLanguage
  {\TwoLetterIsoCountryCode}{canadian}.
\end{document}
\TrackLanguageTag but may be set explicitly.
\TrackLangScript where
 is the ISO 15924 four-letter code. If the dialect
doesn’t have an associated script,  is done.
This package isn’t
loaded automatically, so you’ll need to explicitly load it. The
generic code is in tracklang-scripts.tex:
There’s a convenient LaTeX wrapper tracklang-scripts.sty:
\input tracklang-scripts
See §4 for further details of
that package.
\usepackage{tracklang-scripts}
\input tracklang-scripts
\def\islatin#1#2#3{% 
  \IfTrackedDialectIsScriptCs{#1}{\TrackLangScriptLatn}{#2}{#3}% 
}
\CurrentTrackedTag is set to the final attempt at determining
.
\IfTrackedLanguageFileExists but omits the test for the
dialect label. Note that if the dialect label happens to be
identical to the root language label, it will still be checked, but
at the very end instead of near the start.
\IfTrackedLanguageFileExists but omits the test for just the
region code.
\IfTrackedLanguageFileExists but omits the tests for the
dialect label and for just the region code.
\IfTrackedLanguageFileExists to input the resource
file if found. The prefix is given by - and
the suffix is .ldf. A warning is issued if no resource file
is found. Note that while it makes sense for 
to be the same as the base name of the package that uses these
resource files, they don’t have to be the same. This command
additionally defines:
to , which allows the prefix to be picked up by
resource file commands, such as \TrackLangProvidesResource
and \TrackLangRequireResource. (See below.)
\IfTrackedLanguageFileExistsOmitDialectLabel.
\IfTrackedLanguageFileExistsOmitDialectLabelOmitOnlyRegion.
\IfTrackedLanguageFileExistsOmitOnlyRegion.
\TrackLangRequireResource{\CurrentTrackedTag}
\IfTrackedLanguageFileExists command sets up the current
tracked dialect with:
which enables the following commands that may be used within 
 or :
Expands to the dialect label.
\SetCurrentTrackedDialect{}
\CurrentTrackedRegion will expand to that code, otherwise it
will be empty.
\CurrentTrackedTag.
\IfTrackedLanguageFileExists behaves as follows:
\CurrentTrackedTag is empty.
\CurrentTrackedTag is set to the current  in the
set. The rest of the set of possible values of  is skipped.
\CurrentTrackedTag is set to the final  in the
set (the language label).
\IfTrackedLanguageFileExists. Note that the set may contain
repetitions (for example, if the dialect label is the same as the
root language label). If an item contains an element that hasn’t
been set (such as the ISO 639-3 code or a sub-language
 or variant) then
that item is skipped.
\CurrentTrackedLanguageTag.
\IfTrackedLanguageFileExistsOmitDialectLabel
and \IfTrackedLanguageFileExistsOmitDialectLabelOmitOnlyRegion.
---.
--.
-- (if there’s no script or if
the script is the default for the given language).
- (if there’s no script or if
the script is the default for the given language).
--.
-.
-.
---.
--.
--region (if there’s no script or if
the script is the default for the given language).
- (if there’s no script or if
the script is the default for the given language).
--.
-.
-.
---.
--.
-- (if there’s no script or if
the script is the default for the given language).
- (if there’s no script or if
the script is the default for the given language).
--.
-.
-.
\IfTrackedLanguageFileExistsOmitOnlyRegion
and \IfTrackedLanguageFileExistsOmitDialectLabelOmitOnlyRegion.
--
or - if  is missing.
--
or - if  is missing.
--
or - if  is missing.
\CurrentTrackedLanguage
(the root language label).
With version 1.3 onwards, this can be written more concisely as:
\AnyTrackedLanguages
{% 
 \ForEachTrackedDialect{\ThisDialect}% 
 {% 
  % try to load the language file for this dialect
  \IfTrackedLanguageFileExists{\ThisDialect}% 
  {mypackage-}% file prefix
  {.ldf}% file suffix
  {\input mypackage-\CurrentTrackedTag.ldf}% file found
  {% file not found
    \PackageWarning{mypackage}
      {No support for language `\ThisDialect'}% 
  }% 
 }% 
}
{% no languages detected so use defaults
}
which additionally enables the tracklang version 1.3 commands described below,
such as \AnyTrackedLanguages
{% 
 \ForEachTrackedDialect{\ThisDialect}% 
 {% 
  % try to load the language file for this dialect
  \TrackLangRequireDialect{mypackage}{\ThisDialect}% 
 }% 
}
{% no languages detected so use defaults
}
\TrackLangRequireResource.
\ThisDialect is british, then the file search will
be in the order:
\ThisDialect is naustrian, then the file search will
be in the order:
\ThisDialect is francais, then the file search will
be in the order: 
This is because the predefined francais option has no
region assigned to it. Be careful if the dialect label is the actual
root language. For example, if\ThisDialect is french,
then the file search will be in the order:
Note that the last try will always fail in this case since if the
file exists, it will be found on the second try.
With version 1.3 onwards, this can be written more concisely as:
\AnyTrackedLanguages
{% 
 \ForEachTrackedLanguage{\ThisLanguage}% 
 {% try to load the language file for this root language
   \IfTrackedLanguageFileExists{\ThisLanguage}% 
   {mypackage-}% file prefix
   {.ldf}% file suffix
   {\input mypackage-\CurrentTrackedTag.ldf}% file found
   {% file not found
     \PackageWarning{mypackage}{No support for language
      `\ThisLanguage'}% 
   }% 
 }% 
}
{% no languages detected so use defaults
}
which additionally enables the commands described below.
Note that in this case, if more than one dialect for the same
language has been tracked, only the hooks for the last dialect for
that language will be adjusted, so it’s usually best to iterate over
the dialects.
\AnyTrackedLanguages
{% 
 \ForEachTrackedLanguage{\ThisLanguage}% 
 {% try to load the language file for this root language
   \TrackLangRequireDialect{mypackage}{\ThisLanguage}% 
 }% 
}
{% no languages detected so use defaults
}
\TrackLang…Resource… commands may 
only be used in resource files that are loaded using
\TrackLangRequireDialect. An error will occur if the file is
input through some other method.
\ProvidesFile is defined (through the LaTeX kernel) this is
used, otherwise a simplified generic alternative is used that’s 
suitable for other TeX formats.
% (In file foo-en-GB.ldf)
% Declare this regional file:
If foo-english.ldf is also identified with
\TrackLangProvidesResource{en-GB}
% load root language file foo-english.ldf:
\TrackLangRequireResource{english}
\TrackLangProvidesResource, this will ensure that it’s only
loaded once.
\inputencodingname, but this is only used with pdfLaTeX. To
avoid repeated tests to determine whether or not \inputencodingname
has been defined, you can use:
utf8 if \inputencodingname hasn’t
been defined (or has been set to \relax), otherwise it will 
expand to \inputencodingname.
For example:
\InputIfFileExists{foo-\TrackLangEncodingName.ldf}
{% support available for the document encoding
}
{% no support for the document encoding
}
\…Resource… commands are only
permitted within the resource files. They are internally enabled
through \TrackLangRequireDialect.
\TrackLangRequireDialect, and the fact that it internally uses
\IfTrackedLanguageFileExists, means that commands like
\CurrentTrackedLanguage or \CurrentTrackedDialect may be
used in those files. This means that the name of the captions hook
can be obtained through them. (Remember that the file
foo-en-GB.ldf might have been loaded with, say, the
british dialect or with the synonymous UKenglish
dialect or with a dialect label that doesn’t have a corresponding
caption hook, such as enGBLatn.)
\captions (where  is the root language
label) whereas babel has dialect captions hooks
in the form \captions (where  is the
dialect label). This leads to a rather
cumbersome set of conditionals:
Note that the above has been simplified through the use of
etoolbox commands, which isn’t suitable for generic use.
It also doesn’t query the mapping from tracklang’s dialect
label to the closest matching babel dialect label.
\ifcsundef{captions\CurrentTrackedLanguage}
{% 
  \ifcsundef{captions\CurrentTrackedDialect}% 
  {}% 
  {% 
    \csgappto{captions\CurrentTrackedDialect}{% 
      % code to append to hook
    }% 
  }% 
}% 
{% 
  \csgappto{captions\CurrentTrackedLanguage}{% 
    % code to append to hook
  }% 
}
% do code now to initialise
\captionsngerman when the package is loaded, not at the start of
the document).
\TrackLangRequireDialect so should only be used inside resource
files.
\TrackLangAddToHook{}{captions}
\date, that need
redefining rather than appending to, so there’s an
analogous command:
5.1. Examples[link]
5.1.1. animals.sty[link]
\catname, \dogname
and \ladybirdname. The default values are: “cat”, “dog” and
“bishy-barney-bee”.1
The supported languages are defined in files
animals-.ldf.
% Example package animals.sty
Here’s a Plain TeX version that picks up the language from the
locale environment variable:
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{animals}
\RequirePackage{tracklang}[2019/11/30]% v1.4
% Any undeclared options are language settings:
\DeclareOption*{% 
 \TrackIfKnownLanguage{\CurrentOption}% 
 {% successful
  \PackageInfo{animals}{Tracking language `\CurrentOption'}% 
 }% 
 {% failed
   \PackageError{animals}% 
   {Unknown language specification `\CurrentOption'}% 
   {You need to supply either a known dialect label 
    or a valid language tag}% 
 }% 
}
\ProcessOptions
% Default definitions
\newcommand\catname{cat}
\newcommand\dogname{dog}
\newcommand\ladybirdname{bishy-barney-bee}
\AnyTrackedLanguages
{% 
  \ForEachTrackedDialect{\this@dialect}{% 
    \TrackLangRequireDialect{animals}{\this@dialect}% 
  }% 
}
{% no tracked languages, default already set up
}
\endinput
In the event that a user or supplementary package for some 
reason wants to load a resource
file for a language that hasn’t been tracked, it might be worth
providing a command for this purpose:
\input tracklang
\TrackLangFromEnv
% Default definitions
\def\catname{cat}
\def\dogname{dog}
\def\ladybirdname{bishy-barney-bee}
\AnyTrackedLanguages
{% 
  \ForEachTrackedDialect{\thisdialect}{% 
    \TrackLangRequireDialect{animals}{\thisdialect}% 
  }% 
}
{% no tracked languages, default already set up
}
The loop can then be changed to:
\newcommand*{\RequireAnimalsDialect}[1]{% 
  \TrackLangRequireDialect{animals}{#1}% 
}
\ForEachTrackedDialect{\this@dialect}{% 
  \RequireAnimalsDialect\this@dialect
}% 
The animals-en-GB.ldf file contains:
\TrackLangProvidesResource{english}
\def\englishanimals{% 
  \def\catname{cat}% 
  \def\dogname{dog}% 
  \def\ladybirdname{bishy-barney-bee}% 
}
\TrackLangAddToCaptions{\englishanimals}
The animals-en-US.ldf file contains:
\TrackLangProvidesResource{en-GB}
\TrackLangRequireResource{english}
\def\enGBanimals{% 
  \englishanimals
  \def\ladybirdname{ladybird}% 
}
\TrackLangAddToCaptions{\enGBanimals}
Here’s a German version in the file animals-german.ldf:
\TrackLangProvidesResource{en-US}
\TrackLangRequireResource{english}
\def\enUSanimals{% 
  \englishanimals
  \def\ladybirdname{ladybug}% 
}
\TrackLangAddToCaptions{\enUSanimals}
\TrackLangProvidesResource{german}
\def\germananimals{% 
  \def\catname{Katze}% 
  \def\dogname{Hund}% 
  \def\ladybirdname{Marienk\"afer}% 
}
\TrackLangAddToCaptions{\germananimals}
\…animals commands.
Here’s a babel example document:
\documentclass[english,german]{article}
\usepackage{animals}
\begin{document}
\englishanimals
\catname.
\dogname.
\ladybirdname.
\germananimals
\catname.
\dogname.
\ladybirdname.
\end{document}
\documentclass[american,german,british]{article}
\usepackage{babel}
\usepackage{animals}
\begin{document}
\selectlanguage{american}
\catname.
\dogname.
\ladybirdname.
\selectlanguage{german}
\catname.
\dogname.
\ladybirdname.
\selectlanguage{british}
\catname.
\dogname.
\ladybirdname.
\end{document}
\captionsamerican hook now includes
Since \englishanimals
\enUSanimals
\enUSanimals includes \englishanimals, there is
redundant code. However, when the british dialect is
processed, this loads the file animals-en-GB.ldf but not
the file animals-english.ldf (since it’s already been loaded). This
means that \captionsbritish contains \enGBanimals but not 
\englishanimals.
The animals-en-US.ldf file is now:
\TrackLangProvidesResource{en-GB}
\def\enGBanimals{% 
  \englishanimals
  \def\ladybirdname{ladybird}% 
}
\TrackLangRequireResourceOrDo{english}% 
{
  \TrackLangAddToCaptions{% 
    \def\ladybirdname{ladybird}% 
  }% 
}
{
  \TrackLangAddToCaptions{\enGBanimals}
}
This means that the document that has the dialects listed in the
order american, british now has
\TrackLangProvidesResource{en-US}
\providecommand*{\enUSanimals}{% 
  \englishanimals
  \renewcommand*{\ladybirdname}{ladybug}% 
}
\TrackLangRequireResourceOrDo{english}
{
  \TrackLangAddToCaptions{% 
    \renewcommand*{\ladybirdname}{ladybird}% 
  }% 
}
{
  \TrackLangAddToCaptions{\enUSanimals}
}
in the \englishanimals
\def\ladybirdname{ladybird}
\captionsbritish hook and just \enUSanimals in the
\captionsamerican hook, which has removed most of the redundancy.
\captionsenglish hook but not
\captionsamerican or \captionsbritish, so this code doesn’t
allow for switching between variants of the same language with
polyglossia.
5.1.2. regions.sty[link]
\IfTrackedLanguageFileExists where if, for example, the dialect
is british, the file search (v1.4+) will be:
You may have wondered why
mypackage-GB.ldf is included in the search given that some
countries have multiple official languages, which means that the country code on its
own may not indicate the language.\TrackLangRequireDialect has an optional argument for adjusting
the way the resource files are loaded. Suppose I have
regions-.ldf resource files, then
loads the resource file for the dialect given by \TrackLangRequireDialect{regions}{\this@dialect}
\this@dialect
using:
I can use the optional argument to also load the resource file for the
root language as well:
\TrackLangRequireResource{\CurrentTrackedTag}
% custom file loader for regions.sty
Now the dialect british can load both
regions-GB.ldf and regions-english.ldf.
\newcommand*{\RequireRegionsDialect}[1]{% 
 \TrackLangRequireDialect
  [\TrackLangRequireResource{\CurrentTrackedTag}% 
   \TrackLangRequireResource
     {\CurrentTrackedLanguage}% 
  ]% 
  {regions}{#1}% 
}
% Example package regions.sty
There are separate ldf files for region and language.
First are the regions.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{regions}
\RequirePackage{tracklang}[2016/10/07]% v1.3+
\DeclareOption*{\TrackLanguageTag{\CurrentOption}}
\ProcessOptions
\newcommand*{\weightunit}{kg}
\newcommand*{\lengthunit}{mm}
\newcommand*{\currencyunit}{EUR}
\newcommand*{\unitname}{units}
\newcommand*{\RequireRegionsDialect}[1]{% 
 \TrackLangRequireDialect
  [\TrackLangRequireResource{\CurrentTrackedTag}% 
   \TrackLangRequireResource
     {\CurrentTrackedLanguage}% 
  ]% 
  {regions}{#1}% 
}
\AnyTrackedLanguages
{% 
 \ForEachTrackedDialect{\this@dialect}{% 
   \RequireRegionsDialect\this@dialect
 }% 
}
{% no tracked languages, default already set up
}
\endinput
Now the language files:\TrackLangProvidesResource{BE}
\providecommand*{\BEunits}{% 
  \renewcommand*{\weightunit}{kg}% 
  \renewcommand*{\lengthunit}{mm}% 
  \renewcommand*{\currencyunit}{EUR}% 
}
\TrackLangAddToCaptions{\BEunits}
\TrackLangProvidesResource{CA}
\providecommand*{\CAunits}{% 
  \renewcommand*{\weightunit}{kg}% 
  \renewcommand*{\lengthunit}{mm}% 
  \renewcommand*{\currencyunit}{CAD}% 
}
\TrackLangAddToCaptions{\CAunits}
\TrackLangProvidesResource{GB}
\providecommand*{\GBunits}{% 
  \renewcommand*{\weightunit}{kg}% 
  \renewcommand*{\lengthunit}{mm}% 
  \renewcommand*{\currencyunit}{GBP}% 
}
\TrackLangAddToCaptions{\GBunits}
\TrackLangProvidesResource{US}
\providecommand*{\USunits}{% 
  \renewcommand*{\weightunit}{lb}% 
  \renewcommand*{\lengthunit}{in}% 
  \renewcommand*{\currencyunit}{USD}% 
}
\TrackLangAddToCaptions{\USunits}
\TrackLangProvidesResource{dutch}
\providecommand*{\dutchnames}{% 
  \renewcommand*{\unitname}{meeteenheden}% 
}
\TrackLangAddToCaptions{\dutchnames}
\TrackLangProvidesResource{english}
\providecommand*{\englishnames}{% 
  \renewcommand*{\unitname}{units}% 
}
\TrackLangAddToCaptions{\englishnames}
\TrackLangProvidesResource{french}
\providecommand*{\frenchnames}{% 
  \renewcommand*{\unitname}{unit\'es}% 
}
\TrackLangAddToCaptions{\frenchnames}
\TrackLangProvidesResource{french}
\providecommand*{\germannames}{% 
  \renewcommand*{\unitname}{Ma\ss einheiten}% 
}
\TrackLangAddToCaptions{\germannames}
\documentclass[canadien]{article}
\usepackage{regions}
\begin{document}
\unitname: \weightunit, \lengthunit, \currencyunit.
\end{document}
After this, the language file regions-french.ldf is then loaded:
\TrackLangRequireResource{\CurrentTrackedTag}
\TrackLangRequireResource{\CurrentTrackedLanguage}
% Modified example package regions.sty
 
Note that we still have a problem for dialect labels that are
identical to root language labels with an associated territory (such
as manx). This case can be checked with the following
adjustment:
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{regions}
% Pass all options to tracklang.sty:
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{tracklang}}
\ProcessOptions
\RequirePackage{tracklang}
\newcommand*{\weightunit}{kg}
\newcommand*{\lengthunit}{mm}
\newcommand*{\currencyunit}{EUR}
\newcommand*{\unitname}{units}
\newcommand*{\defaultunits}{% 
  \renewcommand*{\weightunit}{kg}% 
  \renewcommand*{\lengthunit}{mm}% 
  \renewcommand*{\currencyunit}{EUR}% 
}
\newcommand*{\RequireRegionsDialect}[1]{% 
 \TrackLangRequireDialect
  [\TrackLangRequireResource{\CurrentTrackedTag}% 
    \ifx\CurrentTrackedTag\CurrentTrackedLanguage
      \TrackLangAddToCaptions{\defaultunits}% 
    \else
      \TrackLangRequireResource
        {\CurrentTrackedLanguage}% 
    \fi
  ]% 
  {regions}{#1}% 
}
\AnyTrackedLanguages
{% 
  \ForEachTrackedDialect{\this@dialect}% 
    \RequireRegionsDialect\this@dialect
  % 
}
{% no tracked languages, default already set up
}
\endinput
In the case where both the dialect and root language label are
manx with the resource files regions-manx.ldf
and regions-IM.ldf, then \newcommand*{\RequireRegionsDialect}[1]{% 
 \TrackLangRequireDialect
 [\TrackLangRequireResource{\CurrentTrackedTag}% 
  \ifx\CurrentTrackedTag\CurrentTrackedLanguage
    \ifx\CurrentTrackedRegion\empty
      \TrackLangAddToCaptions{\defaultunits}% 
    \else
      \TrackLangRequireResource
        {\CurrentTrackedRegion}% 
    \fi
  \else
    \TrackLangRequireResource
       {\CurrentTrackedLanguage}% 
  \fi
 ]% 
 {regions}{#1}% 
}
\CurrentTrackedTag will be
manx (the dialect label) so regions-manx.ldf will
be loaded with:
In this case \TrackLangRequireResource{\CurrentTrackedTag}
\CurrentTrackedRegion is IM (that is, it’s
not empty) so then regions-IM.ldf will be loaded with:
\TrackLangRequireResource{\CurrentTrackedRegion}
\captions hook
for either the dialect label or the root language label,
so mappings need to be defined from the tracklang dialect
label to the matching babel dialect label.
This produces:
\documentclass{article}
\usepackage{tracklang}
\TrackLanguageTag{de-US-1996}
\SetTrackedDialectLabelMap
  {\TrackLangLastTrackedDialect}{ngerman}
\TrackLanguageTag{en-MT}
\SetTrackedDialectLabelMap
  {\TrackLangLastTrackedDialect}{UKenglish}
\usepackage[main=ngerman,UKenglish]{babel}
\usepackage{regions}
\begin{document}
\selectlanguage{ngerman}
\unitname: \weightunit, \lengthunit, \currencyunit.
\selectlanguage{UKenglish}
\unitname: \weightunit, \lengthunit, \currencyunit.
\end{document}
which produces:
\documentclass{article}
\usepackage[main=ngerman,UKenglish]{babel}
\usepackage{regions}
\begin{document}
\selectlanguage{ngerman}
\unitname: \weightunit, \lengthunit, \currencyunit.
\selectlanguage{UKenglish}
\unitname: \weightunit, \lengthunit, \currencyunit.
\end{document}
No mapping is required for the en-MT locale as
it can pick up \documentclass{article}
\usepackage{tracklang}
\TrackLanguageTag{de-US-1996}
\SetTrackedDialectLabelMap
 {\TrackLangLastTrackedDialect}{ngerman}
\TrackLanguageTag{en-MT}
\usepackage[main=ngerman,english]{babel}
\usepackage{regions}
\begin{document}
\selectlanguage{ngerman}
\unitname: \weightunit, \lengthunit, \currencyunit.
\selectlanguage{english}
\unitname: \weightunit, \lengthunit, \currencyunit.
\end{document}
\captionsenglish when \TrackLangAddToHook
(used by \TrackLangAddToCaptions)
queries the root language label after failing to find the
language hook from the dialect label.
6. Adding Support for Language Tracking[link]
or (LaTeX only)
\input tracklang
\RequirePackage{tracklang}
\RequirePackage over \input but you want to make 
tracklang.sty skip the check for known
language packages then (as from v1.3.8) define the pre-language
package check hook as follows:
This will still pick up languages supplied through the
document class options.
\providecommand\@tracklang@prelangpkgcheck@hook{\endinput}
\RequirePackage{tracklang}[2019/10/06]% v1.3.8+
\input, there’s a test at the start of
tracklang.tex to determine if it’s already been loaded, so
you don’t need to worry if the document has already input it.
\TrackLangScriptMap command for each unknown script and identify
this new file with \TrackLangAddExtraScriptFile (see
§6.3). This usually
won’t be necessary unless you have a custom script or a child script
(a script that’s a sub-category of another script).
\TrackLangNewLanguage (see §6.5).
\TrackLangProvidePredefinedDialect.
\TrackLangRegionMap command for each new region and
identify this new file with \TrackLangAddExtraRegionFile (see
§6.4). This usually won’t be necessary as
tracklang should recognise all countries that have an alpha-2
region code, but you may require it if you need a broader region,
such as EU.
\TrackPredefinedDialect?
\TrackLangProvidePredefinedLanguage for root languages
and \TrackLangProvidePredefinedDialect for dialects with
additional information, such as a region, sub-language or script
(see §6.6).
\TrackPredefinedDialect for recognised dialect labels or
use the \AddTracked set of commands). See
§6.1.
\selectlanguage), add
\SetCurrentTrackedDialect{} to allow the document
author to easily query the current localisation settings (such as
the region). See §6.2.
6.1. Initialising a New Language or Dialect[link]
provided the dialect label is recognised by tracklang (all those
listed in Tables 1.1, 1.2 & 1.3).
\TrackPredefinedDialect{}
\TrackLocale or \TrackLanguageTag 
(described in §3) 
with the appropriate ISO codes if you’re not providing caption
hooks.
\captions, then if 
doesn’t match the corresponding tracklang dialect label,
you can provide a mapping using
\SetTrackedDialectLabelMap, described below.
6.2. Switching Language or Dialect[link]
\SetTrackedDialectLabelMap,
described below, or the language label (in which case the
last dialect to be tracked with that root language will
be assumed).
(Without this automated use of\CurrentTrackedDialect The dialect label recognised
by tracklang (which may not be the same as ).
\CurrentTrackedLanguage
The root language label used by tracklang.
\CurrentTrackedDialectModifier The dialect modifier.
\CurrentTrackedDialectVariant The dialect variant.
\CurrentTrackedDialectScript The dialect script.
Note that if tracklang-scripts is also loaded, this allows the
script direction to be accessed using
See §4 for further details.
\TrackLangScriptAlphaToDir
 {\CurrentTrackedDialectScript}
\CurrentTrackedDialectSubLang The dialect sub-language
code.
\GetTrackedDialectAdditional The dialect’s additional
information.
\CurrentTrackedIsoCode The dialect’s root language 
ISO code. (The first found in the sequence 639-1,
639-2, 639-3.)
\CurrentTrackedRegion The dialect’s ISO 3166-1 region 
code.
\CurrentTrackedLanguageTag The dialect’s language tag.
\SetCurrentTrackedDialect,
the same information can be picked up using commands
like \GetTrackedDialectScript, but that’s less convenient,
especially if \languagename needs to be converted
to . See the accompanying sample file
sample-setlang.tex for an example.)
6.3. Defining New Scripts[link]
The first argument  is the four-letter ISO 15924 code (such as
Latn), the second argument is the numeric code (such as
215), the third argument  is the name of the script (such
as Latin), the fourth argument is the direction (such as
LR for left-to-right) and the final argument is the parent
script (leave blank if there’s no parent). Note that this command will override any previous
mapping for those codes. No check is performed to determine if they
have already been defined.
\TrackLangScriptMap{}{}{}{}{}
\TrackLangAddExtraScriptFile{}
6.4. Defining New Regions[link]
where the first argument is the numeric region code (such as 826),
the second argument is the alpha-2 region code (such as \TrackLangRegionMap{}{}{}
GB)
and the third argument is the alpha-3 region code (such as
GBR). Note that this command will override any previous
mapping for those codes. No check is performed to determine if they
have already been defined.
\TrackLangAddExtraRegionFile{}
6.5. Defining a New Language[link]
Note that \AddTrackedDialect{}{}
\AddTrackedDialect defines:
to the dialect label, which makes it easier to reference the last
dialect to be tracked.
6.6. Defining New tracklang Labels[link]
\TrackPredefinedDialect. In the case of a dialect label that
only requires the information provided in \TrackLangNewLanguage
you can use:
\TrackLangNewLanguage. This allows
to not only track the root language but also the associated ISO codes.
\TrackPredefinedDialect{}
where  is the label for the dialect’s root
language (Table 1.2) and  matches
the captions hook. If the dialect is already in the tracked dialect
list, it won’t be added again. If the root language is already in
the tracked language list, it won’t be added again. As from version
1.3 this additionally defines
\AddTrackedDialect{}{}
\TrackLangLastTrackedDialect
to  for convenient reference if required.
Note that \AddTrackedDialect is internally used by commands like
\TrackPredefinedDialect, \TrackLocale and
\TrackLanguageTag.
\captionsngerman can’t be accessed
through:
in the resource files. In this case, a mapping may be defined
between the tracklang dialect label and the closest
matching label used by the language hooks. This is done through
where  is the tracklang label and
 is the language hook label. For example:
\csname captions\CurrentTrackedDialect\endcsname
[fontupper=]
Since \TrackLanguageTag{de-AR-1996}
\SetTrackedDialectLabelMap
{\TrackLangLastTrackedDialect}{ngerman}
\TrackLanguageTag internally uses \AddTrackedDialect
the dialect label created by tracklang can be accessed
using \TrackLangLastTrackedDialect. This means that
\TrackLangAddToCaptions can now find the \captionsngerman
hook even though the tracklang dialect label isn’t ngerman.
\AddTrackedDialect{oldgerman}{german}
\AddTrackedLanguageIsoCodes{german}
\SetTrackedDialectModifier{oldgerman}{old}
\SetTrackedDialectModifier,
since it’s assumed that any package that specifically sets the
modifier in this way is using a sensible labelling system. If the
modifier is obtained through commands like \TrackLocale, then
the modifier is sanitized as the value may have been obtained from
the operating system and there’s no guarantee that it won’t contain
problematic characters.
[
whereas the variant is typically obtained by parsing the language
tag.
_][.][@]
\AddTrackedDialect{serbianlatin}{serbian}
\AddTrackedLanguageIsoCodes{serbian}
\SetTrackedDialectModifier{serbianlatin}{latin}
\SetTrackedDialectScript{serbianlatin}{Latn}
\AddTrackedDialect{serbiancyrl}{serbian}
\AddTrackedLanguageIsoCodes{serbian}
\SetTrackedDialectScript{serbiancyrl}{Cyrl}
\AddTrackedDialect{german1901}{german}
\SetTrackedDialectVariant{german1901}{1901}
\AddTrackedDialect{mandarin}{chinese}
\AddTrackedLanguageIsoCodes{chinese}
\SetTrackedDialectSubLang{mandarin}{cmn}
\AddTrackedIsoLanguage{639-3}{cmn}{mandarin}
6.7. Example (alien.sty)[link]
The caption commands and language set up are in the files
alien-.ldf as in the examples from
§5.1. This allows for the user having already
loaded tracklang before alien and used \ProvidesPackage{alien}
\inputtracklang% v1.3
\DeclareOption{martian}{% 
 \TrackPredefinedDialect{martian}
}
\DeclareOption{lowermartian}{% 
 \AddTrackedDialect{lowermartian}{martian}
 \AddTrackedLanguageIsoCodes{martian}
 \AddTrackedIsoLanguage{3166-1}{YY}{lowermartian}
 % other attributes such as
 % \SetTrackedDialectVariant{lowermartian}{...}
}
\DeclareOption{uppermartian}{% 
 \AddTrackedDialect{uppermartian}{martian}
 \AddTrackedLanguageIsoCodes{martian}
 \AddTrackedIsoLanguage{3166-1}{XX}{uppermartian}
 % other attributes such as
 % \SetTrackedDialectVariant{uppermartian}{...}
}
\ProcessOptions
\newcommand*{\selectlanguage}[1]{% 
 \def\languagename{#1}% 
 % other stuff
 \SetCurrentTrackedDialect{#1}% 
 
}
\AnyTrackedLanguages
{
 \ForEachTrackedDialect{\thisdialect}
 {% 
  \TrackLangRequireDialect{alien}{\thisdialect}
 }
}
\TrackLangFromEnv to pick up
the locale from the operating system’s environment variables.
(For example, they may have LANG set to
xx.)
_YY\TrackLangProvidesResource{xx-YY}
\TrackLangRequireResource{martian}% load common elements
\newcommand{\captionslowermartian}{% 
 \captionsmartian
 \def\contentsname{X'flurp}% regional variation
}
\SetTrackedDialectLabelMap{\CurrentTrackedDialect}{lowermartian}
\TrackLangFromEnv before using the alien
package.
The rest is as before.
\ProvidesPackage{alien}
\input{tracklang}% needs v1.3
\TrackLangIfKnownLang{martian}
{% tracklang already knows about the martian language
}% 
{
 % tracklang doesn't known about the martian language,
 % so define it
 % with ISO 639-1 (xx) and ISO 639-2 (xxx) codes:
 \TrackLangNewLanguage{martian}{xx}{xxx}{}{}{}{Latn}
}
A. Region and Script Mappings[link]
 
Alpha-2 
Alpha-3 
Numeric 
Alpha-2 
Alpha-3 
Numeric 
 
AD 
AND 
020
 AE 
ARE 
784 
 
AF 
AFG 
004
 AG 
ATG 
028 
 
AI 
AIA 
660
 AL 
ALB 
008 
 
AM 
ARM 
051
 AO 
AGO 
024 
 
AQ 
ATA 
010
 AR 
ARG 
032 
 
AS 
ASM 
016
 AT 
AUT 
040 
 
AU 
AUS 
036
 AW 
ABW 
533 
 
AX 
ALA 
248
 AZ 
AZE 
031 
 
BA 
BIH 
070
 BB 
BRB 
052 
 
BD 
BGD 
050
 BE 
BEL 
056 
 
BF 
BFA 
854
 BG 
BGR 
100 
 
BH 
BHR 
048
 BI 
BDI 
108 
 
BJ 
BEN 
204
 BL 
BLM 
652 
 
BM 
BMU 
060
 BN 
BRN 
096 
 
BO 
BOL 
068
 BQ 
BES 
535 
 
BR 
BRA 
076
 BS 
BHS 
044 
 
BT 
BTN 
064
 BV 
BVT 
074 
 
BW 
BWA 
072
 BY 
BLR 
112 
 
BZ 
BLZ 
084
 CA 
CAN 
124 
 
CC 
CCK 
166
 CD 
COD 
180 
 
CF 
CAF 
140
 CG 
COG 
178 
 
CH 
CHE 
756
 CI 
CIV 
384 
 
CK 
COK 
184
 CL 
CHL 
152 
 
CM 
CMR 
120
 CN 
CHN 
156 
 
CO 
COL 
170
 CR 
CRI 
188 
 
CU 
CUB 
192
 CV 
CPV 
132 
 
CW 
CUW 
531
 CX 
CXR 
162 
 
CY 
CYP 
196
 CZ 
CZE 
203 
 
DE 
DEU 
276
 DJ 
DJI 
262 
 
DK 
DNK 
208
 DM 
DMA 
212 
 
DO 
DOM 
214
 DZ 
DZA 
012 
 
EC 
ECU 
218
 EE 
EST 
233 
 
EG 
EGY 
818
 EH 
ESH 
732 
 
ER 
ERI 
232
 ES 
ESP 
724 
 
ET 
ETH 
231
 FI 
FIN 
246 
 
FJ 
FJI 
242
 FK 
FLK 
238 
 
FM 
FSM 
583
 FO 
FRO 
234 
 
FR 
FRA 
250
 GA 
GAB 
266 
 
GB 
GBR 
826
 GD 
GRD 
308 
 
GE 
GEO 
268
 GF 
GUF 
254 
 
GG 
GGY 
831
 GH 
GHA 
288 
 
GI 
GIB 
292
 GL 
GRL 
304 
 
GM 
GMB 
270
 GN 
GIN 
324 
 
GP 
GLP 
312
 GQ 
GNQ 
226 
 
GR 
GRC 
300
 GS 
SGS 
239 
 
GT 
GTM 
320
 GU 
GUM 
316 
 
GW 
GNB 
624
 GY 
GUY 
328 
 
HK 
HKG 
344
 HM 
HMD 
334 
 
HN 
HND 
340
 HR 
HRV 
191 
 
HT 
HTI 
332
 HU 
HUN 
348 
 
ID 
IDN 
360
 IE 
IRL 
372 
 
IL 
ISR 
376
 IM 
IMN 
833 
 
IN 
IND 
356
 IO 
IOT 
086 
 
IQ 
IRQ 
368
 IR 
IRN 
364 
 
IS 
ISL 
352
 IT 
ITA 
380 
 
JE 
JEY 
832
 JM 
JAM 
388 
 
JO 
JOR 
400
 JP 
JPN 
392 
 
KE 
KEN 
404
 KG 
KGZ 
417 
 
KH 
KHM 
116
 KI 
KIR 
296 
 
KM 
COM 
174
 KN 
KNA 
659 
 
KP 
PRK 
408
 KR 
KOR 
410 
 
KW 
KWT 
414
 KY 
CYM 
136 
 
KZ 
KAZ 
398
 LA 
LAO 
418 
 
LB 
LBN 
422
 LC 
LCA 
662 
 
LI 
LIE 
438
 LK 
LKA 
144 
 
LR 
LBR 
430
 LS 
LSO 
426 
 
LT 
LTU 
440
 LU 
LUX 
442 
 
LV 
LVA 
428
 LY 
LBY 
434 
 
MA 
MAR 
504
 MC 
MCO 
492 
 
MD 
MDA 
498
 ME 
MNE 
499 
 
MF 
MAF 
663
 MG 
MDG 
450 
 
MH 
MHL 
584
 MK 
MKD 
807 
 
ML 
MLI 
466
 MM 
MMR 
104 
 
MN 
MNG 
496
 MO 
MAC 
446 
 
MP 
MNP 
580
 MQ 
MTQ 
474 
 
MR 
MRT 
478
 MS 
MSR 
500 
 
MT 
MLT 
470
 MU 
MUS 
480 
 
MV 
MDV 
462
 MW 
MWI 
454 
 
MX 
MEX 
484
 MY 
MYS 
458 
 
MZ 
MOZ 
508
 NA 
NAM 
516 
 
NC 
NCL 
540
 NE 
NER 
562 
 
NF 
NFK 
574
 NG 
NGA 
566 
 
NI 
NIC 
558
 NL 
NLD 
528 
 
NO 
NOR 
578
 NP 
NPL 
524 
 
NR 
NRU 
520
 NU 
NIU 
570 
 
NZ 
NZL 
554
 OM 
OMN 
512 
 
PA 
PAN 
591
 PE 
PER 
604 
 
PF 
PYF 
258
 PG 
PNG 
598 
 
PH 
PHL 
608
 PK 
PAK 
586 
 
PL 
POL 
616
 PM 
SPM 
666 
 
PN 
PCN 
612
 PR 
PRI 
630 
 
PS 
PSE 
275
 PT 
PRT 
620 
 
PW 
PLW 
585
 PY 
PRY 
600 
 
QA 
QAT 
634
 RE 
REU 
638 
 
RO 
ROU 
642
 RS 
SRB 
688 
 
RU 
RUS 
643
 RW 
RWA 
646 
 
SA 
SAU 
682
 SB 
SLB 
090 
 
SC 
SYC 
690
 SD 
SDN 
729 
 
SE 
SWE 
752
 SG 
SGP 
702 
 
SH 
SHN 
654
 SI 
SVN 
705 
 
SJ 
SJM 
744
 SK 
SVK 
703 
 
SL 
SLE 
694
 SM 
SMR 
674 
 
SN 
SEN 
686
 SO 
SOM 
706 
 
SR 
SUR 
740
 SS 
SSD 
728 
 
ST 
STP 
678
 SV 
SLV 
222 
 
SX 
SXM 
534
 SY 
SYR 
760 
 
SZ 
SWZ 
748
 TC 
TCA 
796 
 
TD 
TCD 
148
 TF 
ATF 
260 
 
TG 
TGO 
768
 TH 
THA 
764 
 
TJ 
TJK 
762
 TK 
TKL 
772 
 
TL 
TLS 
626
 TM 
TKM 
795 
 
TN 
TUN 
788
 TO 
TON 
776 
 
TR 
TUR 
792
 TT 
TTO 
780 
 
TV 
TUV 
798
 TW 
TWN 
158 
 
TZ 
TZA 
834
 UA 
UKR 
804 
 
UG 
UGA 
800
 UM 
UMI 
581 
 
US 
USA 
840
 UY 
URY 
858 
 
UZ 
UZB 
860
 VA 
VAT 
336 
 
VC 
VCT 
670
 VE 
VEN 
862 
 
VG 
VGB 
092
 VI 
VIR 
850 
 
VN 
VNM 
704
 VU 
VUT 
548 
 
WF 
WLF 
876
 WS 
WSM 
882 
 
YE 
YEM 
887
 YT 
MYT 
175 
 
ZA 
ZAF 
710
 ZM 
ZMB 
894 
 ZW 
ZWE 
716 
 
Alpha-2 
Numeric 
Direction 
Description 
 
Adlm 
166 
RL 
Adlam. 
 
Afak 
439 
varies 
Afaka. 
 
Aghb 
239 
LR 
Caucasian Albanian. 
 
Ahom 
338 
LR 
Ahom, Tai Ahom. 
 
Arab 
160 
RL 
Arabic. 
 
Aran 
161 
RL 
Arabic (Nastaliq variant). 
 
Armi 
124 
RL 
Imperial Aramaic. 
 
Armn 
230 
LR 
Armenian. 
 
Avst 
134 
RL 
Avestan. 
 
Bali 
360 
LR 
Balinese. 
 
Bamu 
435 
LR 
Bamum. 
 
Bass 
259 
LR 
Bassa Vah. 
 
Batk 
365 
LR 
Batak. 
 
Beng 
334 
LR 
Bhaiksuki. 
 
Blis 
550 
varies 
Blissymbols. 
 
Bopo 
285 
LR 
Bopomofo. 
 
Brah 
300 
LR 
Brahmi. 
 
Brai 
570 
LR 
Braille. 
 
Bugi 
367 
LR 
Buginese. 
 
Buhd 
372 
LR 
Buhid. 
 
Cakm 
349 
LR 
Chakma. 
 
Cans 
440 
LR 
Unified Canadian Aboriginal Syllabics. 
 
Cari 
201 
LR 
Carian. 
 
Cham 
358 
LR 
Cham. 
 
Cher 
445 
LR 
Cherokee. 
 
Cirt 
291 
varies 
Cirth. 
 
Copt 
204 
LR 
Coptic. 
 
Cprt 
403 
RL 
Cypriot. 
 
Cyrl 
220 
LR 
Cyrillic. 
 
Cyrs 
221 
varies 
Cyrillic (Old Church Slavonic variant). 
 
Deva 
315 
LR 
Devanagari (Nagari). 
 
Dsrt 
250 
LR 
Deseret (Mormon). 
 
Dupl 
755 
LR 
Duployan shorthand, Duployan stenography. 
 
Egyd 
070 
RL 
Egyptian demotic. 
 
Egyh 
060 
RL 
Egyptian hieratic. 
 
Egyp 
050 
LR 
Egyptian hieroglyphs. 
 
Elba 
226 
LR 
Elbasan. 
 
Ethi 
430 
LR 
Ethiopic (Ge’ez). 
 
Geok 
241 
LR 
Khutsuri (Asomtavruli and Nuskhuri). 
 
Geor 
240 
LR 
Georgian (Mkhedruli). 
 
Glag 
225 
LR 
Glagolitic. 
 
Goth 
206 
LR 
Gothic. 
 
Gran 
343 
LR 
Grantha. 
 
Grek 
200 
LR 
Greek. 
 
Gujr 
320 
LR 
Gujarati. 
 
Guru 
310 
LR 
Gurmukhi. 
 
Hanb 
503 
LR 
Han with Bopomofo (alias for Han + Bopomofo). 
 
Hang 
286 
LR 
Hangul. 
 
Hani 
500 
LR 
Han (Hanzi, Kanji, Hanja). 
 
Hano 
371 
LR 
Hanunoo. 
 
Hans 
501 
varies 
Han (Simplified variant). 
 
Hant 
502 
varies 
Han (Traditional variant). 
 
Hatr 
127 
RL 
Hatran. 
 
Hebr 
125 
RL 
Hebrew. 
 
Hira 
410 
LR 
Hiragana. 
 
Hluw 
080 
LR 
Anatolian Hieroglyphs (Luwian Hieroglyphs, Hittite Hieroglyphs). 
 
Hmng 
450 
LR 
Pahawh Hmong. 
 
Hrkt 
412 
varies 
Japanese syllabaries (alias for Hiragana + Katakana). 
 
Hung 
176 
RL 
Old Hungarian (Hungarian Runic). 
 
Inds 
610 
RL 
Indus (Harappan). 
 
Ital 
210 
LR 
Old Italic (Etruscan, Oscan, etc.) 
 
Jamo 
284 
LR 
Jamo (alias for Jamo subset of Hangul). 
 
Java 
361 
LR 
Javanese. 
 
Jpan 
413 
varies 
Japanese (alias for Han + Hiragana + Katakana). 
 
Jurc 
510 
LR 
Jurchen. 
 
Kali 
357 
LR 
Kayah Li. 
 
Kana 
411 
LR 
Katakana. 
 
Khar 
305 
RL 
Kharoshthi. 
 
Khmr 
355 
LR 
Khmer. 
 
Khoj 
322 
LR 
Khojki. 
 
Kitl 
505 
LR 
Khitan large script. 
 
Kits 
288 
TB 
Khitan small script. 
 
Knda 
345 
LR 
Kannada. 
 
Kore 
287 
LR 
Korean (alias for Hangul + Han). 
 
Kpel 
436 
LR 
Kpelle. 
 
Kthi 
317 
LR 
Kaithi. 
 
Lana 
351 
LR 
Tai Tham (Lanna). 
 
Laoo 
356 
LR 
Lao. 
 
Latf 
217 
varies 
Latin (Fraktur variant). 
 
Latg 
216 
LR 
Latin (Gaelic variant). 
 
Latn 
215 
LR 
Latin. 
 
Leke 
364 
LR 
Leke. 
 
Lepc 
335 
LR 
Lepcha. 
 
Limb 
336 
LR 
Limbu. 
 
Lina 
400 
LR 
Linear A. 
 
Linb 
401 
LR 
Linear B. 
 
Lisu 
399 
LR 
Lisu (Fraser). 
 
Loma 
437 
LR 
Loma. 
 
Lyci 
202 
LR 
Lycian. 
 
Lydi 
116 
RL 
Lydian. 
 
Mahj 
314 
LR 
Mahajani. 
 
Mand 
140 
RL 
Mandaic, Mandaean. 
 
Mani 
139 
RL 
Manichaean. 
 
Marc 
332 
LR 
Marchen. 
 
Maya 
090 
varies 
Mayan hieroglyphs. 
 
Mend 
438 
RL 
Mende Kikakui. 
 
Merc 
101 
RL 
Meroitic Cursive. 
 
Mero 
100 
RL 
Meroitic Hieroglyphs. 
 
Mlym 
347 
LR 
Malayalam. 
 
Modi 
324 
LR 
Modi. 
 
Mong 
145 
TB 
Mongolian. 
 
Moon 
218 
varies 
Moon (Moon code, Moon script, Moon type). 
 
Mroo 
199 
LR 
Mro, Mru. 
 
Mtei 
337 
LR 
Meitei Mayek (Meithei, Meetei). 
 
Mult 
323 
LR 
Multani. 
 
Mymr 
350 
LR 
Myanmar (Burmese). 
 
Narb 
106 
RL 
Old North Arabian (Ancient North Arabian). 
 
Nbat 
159 
RL 
Nabataean. 
 
Newa 
333 
LR 
Newa, Newar, Newari. 
 
Nkgb 
420 
LR 
Nakhi Geba. 
 
Nkoo 
165 
RL 
N’Ko. 
 
Nshu 
499 
LR 
Nushu. 
 
Ogam 
212 
varies 
Ogham. 
 
Olck 
261 
LR 
Ol Chiki. 
 
Orkh 
175 
RL 
Old Turkic, Orkhon Runic. 
 
Orya 
327 
LR 
Oriya. 
 
Osge 
219 
LR 
Osage. 
 
Osma 
260 
LR 
Osmanya. 
 
Palm 
126 
RL 
Palmyrene. 
 
Pauc 
263 
LR 
Pau Cin Hau. 
 
Perm 
227 
LR 
Old Permic. 
 
Phag 
331 
TB 
Phags-pa. 
 
Phli 
131 
RL 
Inscriptional Pahlavi. 
 
Phlp 
132 
RL 
Psalter Pahlavi. 
 
Phlv 
133 
RL 
Book Pahlavi. 
 
Phnx 
115 
RL 
Phoenician. 
 
Piqd 
293 
LR 
Klingon (KLI plqaD). 
 
Plrd 
282 
LR 
Miao (Pollard). 
 
Prti 
130 
RL 
Inscriptional Parthian. 
 
Qaaa 
900 
varies 
Reserved for private use (start). 
 
Qaai 
908 
varies 
Private use. 
 
Qabx 
949 
varies 
Reserved for private use (end). 
 
Rjng 
363 
LR 
Rejang (Redjang, Kaganga). 
 
Roro 
620 
varies 
Rongorongo. 
 
Runr 
211 
LR 
Runic. 
 
Samr 
123 
RL 
Samaritan. 
 
Sara 
292 
varies 
Sarati. 
 
Sarb 
105 
RL 
Old South Arabian. 
 
Saur 
344 
LR 
Saurashtra. 
 
Sgnw 
095 
TB 
SignWriting. 
 
Shaw 
281 
LR 
Shavian (Shaw). 
 
Shrd 
319 
LR 
Sharada. 
 
Sidd 
302 
LR 
Siddham. 
 
Sind 
318 
LR 
Khudawadi, Sindhi. 
 
Sinh 
348 
LR 
Sinhala. 
 
Sora 
398 
LR 
Sora Sompeng. 
 
Sund 
362 
LR 
Sundanese. 
 
Sylo 
316 
LR 
Syloti Nagri. 
 
Syrc 
135 
RL 
Syriac. 
 
Syre 
138 
RL 
Syriac (Estrangelo variant). 
 
Syrj 
137 
RL 
Syriac (Western variant). 
 
Syrn 
136 
RL 
Syriac (Eastern variant). 
 
Tagb 
373 
LR 
Tagbanwa. 
 
Takr 
321 
LR 
Takri. 
 
Tale 
353 
LR 
Tai Le. 
 
Talu 
354 
LR 
New Tai Lue. 
 
Taml 
346 
LR 
Tamil. 
 
Tang 
520 
LR 
Tangut. 
 
Tavt 
359 
LR 
Tai Viet. 
 
Telu 
340 
LR 
Telugu. 
 
Teng 
290 
LR 
Tengwar. 
 
Tfng 
120 
LR 
Tifinagh (Berber). 
 
Tglg 
370 
LR 
Tagalog (Baybayin, Alibata). 
 
Thaa 
170 
RL 
Thaana. 
 
Thai 
352 
LR 
Thai. 
 
Tibt 
330 
LR 
Tibetan. 
 
Tirh 
326 
LR 
Tirhuta. 
 
Ugar 
040 
LR 
Ugaritic. 
 
Vaii 
470 
LR 
Vai. 
 
Visp 
280 
LR 
Visible Speech. 
 
Wara 
262 
LR 
Warang Citi (Varang Kshiti). 
 
Wole 
480 
RL 
Woleai. 
 
Xpeo 
030 
LR 
Old Persian. 
 
Xsux 
020 
LR 
Cuneiform, Sumero-Akkadian. 
 
Yiii 
460 
LR 
Yi. 
 
Zinh 
994 
inherited 
Inherited script. 
 
Zmth 
995 
LR 
Mathematical notation. 
 
Zsye 
993 
varies 
Symbols (emoji variant). 
 
Zsym 
996 
varies 
Symbols. 
 
Zxxx 
997 
varies 
Unwritten documents. 
 
Zyyy 
998 
varies 
Undetermined script. 
 Zzzz 
999 
varies 
Uncoded script. Symbols[link]
Glossary[link]
Command Summary[link]
@[link]
A[link]
\TrackLangLastTrackedDialect to provide a convenient way to reference the last dialect to be tracked. §6.5; 76
\AddTrackedDialect{}{}\TrackLangNewLanguage. §6.6; 78
C[link]
\SetCurrentTrackedDialect to the dialect label, which may be the supplied  label or the mapped label or, if  is a root language label, the last tracked dialect for the given root language. §5; 47
\SetCurrentTrackedDialect to the additional part associated with the dialect (may be empty). §5; 47
\SetCurrentTrackedDialect to the associated modifier (may be empty). §5; 47
\SetCurrentTrackedDialect to the script associated with the dialect, or to the default script for the language. §5; 48
\SetCurrentTrackedDialect to the sub language associated with the dialect (may be empty). §5; 47
\SetCurrentTrackedDialect to the associated variant (may be empty). §5; 47
\SetCurrentTrackedDialect to the ISO 639-1 or 639-2 or 639-3 language code (may be empty). §5; 47
\SetCurrentTrackedDialect to the associated root language label. §5; 47
\SetCurrentTrackedDialect to the language tag that identifies the dialect or und if no match. §5; 47
\SetCurrentTrackedDialect to the ISO 3166-1 region code associated with the dialect (may be empty). §5; 47
F[link]
G[link]
I[link]
\SetCurrentTrackedDialect{}\CurrentTrackedTag is set to  and  is done, otherwise  is done. §5; 45
\IfTrackedLanguageFileExists but skips the dialect label check. Note that if the dialect label happens to be the same as the root label, it will still be checked but at the end instead of near the start. §5; 45
\IfTrackedLanguageFileExists but skips the dialect label check and just the region code check. Note that if the dialect label happens to be the same as the root label, it will still be checked but at the end instead of near the start. §5; 45
\IfTrackedLanguageFileExists but skips the solo region code check. §5; 45
S[link]
\captions. §6.6; 78
T[link]
\GetTrackedDialectFromLanguageTag to the closest match. §5; 36
\TrackLanguageTag but does  if the tag doesn’t contain a valid language code. If successful, does  after tracking the language. §3; 21
\TrackLangAddToHook{}{captions}\TrackPredefinedDialect.
\inputencodingname if it has been defined or utf8 otherwise. §5; 54
LC_ALL before using \TrackLangParseFromEnv to skip the environment variable query. §3; 25
\TrackLangParseFromEnv to the code-set. §3; 26
\TrackLangParseFromEnv to the language code. §3; 26
\TrackLangParseFromEnv to the modifier. §3; 26
\TrackLangParseFromEnv to the territory. §3; 26
\TrackLangEnv not already set, parses \TrackLangEnv if it has been set, and adds the dialect if it’s recognised. §3; 23
\TrackLangEnv. §3; 27
\TrackPredefinedDialect. §6.6; 77
\TrackPredefinedDialect. §6.6; 77
\ProvidesFile. §5; 53
LC_ALL environment variable via the shell escape or, with LuaTeX, \directlua. §3; 26
LC_ALL environment variable and then by the  environment variable via the shell escape or, with LuaTeX, \directlua. §3; 27
\TrackLangAddToHook but redefines the hook rather than appending to it. §5; 56
\TrackLangRequireResource but does  if the file doesn’t exist. §5; 54
\IfTrackedLanguageFileExists. §5; 46
\IfTrackedLanguageFileExistsOmitDialectLabel. §5; 46
\IfTrackedLanguageFileExistsOmitDialectLabelOmitOnlyRegion. §5; 46
\IfTrackedLanguageFileExistsOmitOnlyRegion. §5; 46
\TrackLangRequireDialect. §5; 46
\TrackLangRequireResource but does  if the file is now loaded or  if the file has already been loaded. §5; 54
\TrackLangScriptMap to the associated alpha code . §4; 32
\ifTrackLangShowWarnings to false. §3; 24
\ifTrackLangShowWarnings to true. §3; 24
\TrackLangEnv. §3; 20
Package Option Summary[link]
Index[link]
Symbols[link]
@[link]
A[link]
B[link]
C[link]
D[link]
E[link]
F[link]
G[link]
H[link]
I[link]
J[link]
K[link]
L[link]
M[link]
N[link]
O[link]
P[link]
Q[link]
R[link]
S[link]
T[link]
U[link]
V[link]
W[link]
X[link]
Y[link]
Z[link]
1Thass Broad Norfolk, my bewties
:-P