summaryrefslogtreecommitdiff
path: root/macros/unicodetex/latex/polyglossia
diff options
context:
space:
mode:
Diffstat (limited to 'macros/unicodetex/latex/polyglossia')
-rw-r--r--macros/unicodetex/latex/polyglossia/README.md9
-rw-r--r--macros/unicodetex/latex/polyglossia/polyglossia.dtx6507
-rw-r--r--macros/unicodetex/latex/polyglossia/polyglossia.pdfbin269164 -> 279264 bytes
3 files changed, 6079 insertions, 437 deletions
diff --git a/macros/unicodetex/latex/polyglossia/README.md b/macros/unicodetex/latex/polyglossia/README.md
index 79b922ef93..780c3929cc 100644
--- a/macros/unicodetex/latex/polyglossia/README.md
+++ b/macros/unicodetex/latex/polyglossia/README.md
@@ -1,10 +1,9 @@
-# THE POLYGLOSSIA PACKAGE v1.49
+# THE POLYGLOSSIA PACKAGE v1.50
## Multilingual typesetting with XeLaTeX and LuaLaTeX
-This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX
-(with a few languages incompletely supported for the latter). This version
-includes support for over 70 different languages, some of which in different
-regional or national varieties, or using a different writing system.
+This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX.
+This version includes support for over 70 different languages, some of which in
+different regional or national varieties, or using a different writing system.
Polyglossia makes it possible to automate the following tasks:
diff --git a/macros/unicodetex/latex/polyglossia/polyglossia.dtx b/macros/unicodetex/latex/polyglossia/polyglossia.dtx
index 246c37edb0..d8c35b3242 100644
--- a/macros/unicodetex/latex/polyglossia/polyglossia.dtx
+++ b/macros/unicodetex/latex/polyglossia/polyglossia.dtx
@@ -8,13 +8,12 @@
\iffalse
%</internal>
%<*README>
-# THE POLYGLOSSIA PACKAGE v1.49
+# THE POLYGLOSSIA PACKAGE v1.50
## Multilingual typesetting with XeLaTeX and LuaLaTeX
-This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX
-(with a few languages incompletely supported for the latter). This version
-includes support for over 70 different languages, some of which in different
-regional or national varieties, or using a different writing system.
+This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX.
+This version includes support for over 70 different languages, some of which in
+different regional or national varieties, or using a different writing system.
Polyglossia makes it possible to automate the following tasks:
@@ -95,6 +94,21 @@ to track the issues and follow progress.
\endpostamble
\let\MetaPrefix\DoubleperCent
\askforoverwritefalse
+\generate{\file{polyglossia.sty}{\from{polyglossia.dtx}{polyglossia.sty}}}
+\generate{\file{farsical.sty}{\from{polyglossia.dtx}{farsical.sty}}}
+\generate{\file{hebrewcal.sty}{\from{polyglossia.dtx}{hebrewcal.sty}}}
+\generate{\file{hijrical.sty}{\from{polyglossia.dtx}{hijrical.sty}}}
+\generate{\file{polyglossia-french.lua}{\from{polyglossia.dtx}{polyglossia-french.lua}}}
+\generate{\file{polyglossia-korean.lua}{\from{polyglossia.dtx}{polyglossia-korean.lua}}}
+\generate{\file{polyglossia-latin.lua}{\from{polyglossia.dtx}{polyglossia-latin.lua}}}
+\generate{\file{polyglossia-punct.lua}{\from{polyglossia.dtx}{polyglossia-punct.lua}}}
+\generate{\file{polyglossia-sanskrit.lua}{\from{polyglossia.dtx}{polyglossia-sanskrit.lua}}}
+\generate{\file{polyglossia-tibt.lua}{\from{polyglossia.dtx}{polyglossia-tibt.lua}}}
+\generate{\file{polyglossia.lua}{\from{polyglossia.dtx}{polyglossia.lua}}}
+\generate{\file{babel-hebrewalph.def}{\from{polyglossia.dtx}{babel-hebrewalph.def}}}
+\generate{\file{babelsh.def}{\from{polyglossia.dtx}{babelsh.def}}}
+\generate{\file{cal-util.def}{\from{polyglossia.dtx}{cal-util.def}}}
+\generate{\file{xgreek-fixes.def}{\from{polyglossia.dtx}{xgreek-fixes.def}}}
\generate{\file{gloss-acadien.ldf}{\from{polyglossia.dtx}{gloss-acadien.ldf}}}
\generate{\file{gloss-aeb.ldf}{\from{polyglossia.dtx}{gloss-aeb.ldf}}}
\generate{\file{gloss-af.ldf}{\from{polyglossia.dtx}{gloss-af.ldf}}}
@@ -346,11 +360,11 @@ to track the issues and follow progress.
%<*internal>
\generate{\file{polyglossia.ins}{\from{polyglossia.dtx}{batchfile}}}
\nopreamble\nopostamble
-\generate{\file{../README.md}{\from{polyglossia.dtx}{../README.md}}}
\generate{\file{Changelog}{\from{polyglossia.dtx}{Changelog}}}
\generate{\file{examples.tex}{\from{polyglossia.dtx}{examples.tex}}}
\generate{\file{example-arabic.tex}{\from{polyglossia.dtx}{example-arabic.tex}}}
\generate{\file{example-thai.tex}{\from{polyglossia.dtx}{example-thai.tex}}}
+\generate{\file{README.md}{\from{polyglossia.dtx}{README}}}
\endgroup
%</internal>
%
@@ -424,6 +438,12 @@ to track the issues and follow progress.
\xpgvalue{=} \meta{code} (default value: \texttt{#3})\par%
}
+% arguments: #1 version number, #2 key name, #3 value type, #4 default value
+\NewDocumentCommand\xpgoptkey{ommo}{%
+ \xpgoption{#2}\IfValueT{#1}{\new{#1}}
+ \xpgvalue{=} \meta{#3} (default value: \texttt{#4})\par%
+}
+
%% Sidenotes << copied from fontspec.dtx
\newcommand\new[1]{%
\edef\thisversion{v#1}%
@@ -509,7 +529,7 @@ to track the issues and follow progress.
% \section{Introduction}
%
% \pkg{Polyglossia} is a package for facilitating multilingual typesetting with
-% \XeLaTeX\ and (with some exceptions) \LuaLaTeX. Basically, it
+% \XeLaTeX\ and \LuaLaTeX. Basically, it
% can be used as an alternative to \pkg{babel} for performing the following
% tasks automatically:
%
@@ -908,11 +928,19 @@ to track the issues and follow progress.
% option \xpgoption{nolocalmarks} which used to switch off the previous default, and
% now equals the default, is still available.
%
-% \item \xpgoption{quiet} turns off most info messages and some of the warnings issued
-% by \LaTeX, \pkg{fontspec} and \pkg{polyglossia}.
+% \item \xpgoptkey[1.50]{luatexrenderer}{renderer}[Harfbuzz] determines which font renderer is used
+% with \LuaTeX\ output. The correct font renderer is essential particularly for non-Latin scripts.
+% By default, \pkg{polyglossia} uses the \xpgvalue{Harfbuzz} renderer that has been introduced to
+% \LuaTeX\ in 2019 (\TeX Live 2020), as this gives the best results generally. If you want to use
+% a different renderer, you can specify this here (or individually for specific fonts via the optional
+% argument of the font selection commands). Please refer to the \pkg{fontspec} manual for supported
+% values and for details on how to change the renderer for individual fonts.\\
+% \xpgoption{luatexrenderer=none} disables \pkg{polyglossia}'s automatic renderer setting.
+%
+% \item \xpgboolkeytrue{verbose} determines whether info messages and (some of the) warnings issued
+% by \LaTeX, \pkg{fontspec} and \pkg{polyglossia} are output.
% \end{itemize}
%
-% \pagebreak
% \section{Language-switching commands}\label{languageswitching}
%
% \subsection{Recommended commands}\label{sec:langcmds}
@@ -977,17 +1005,22 @@ to track the issues and follow progress.
% \item \DescribeMacro{\foreignlanguage}\cmd{\foreignlanguage\oarg{options}\marg{lang}\marg{…}}
% \item \DescribeEnv{otherlanguage}\cmd{\begin\{otherlanguage\}\oarg{options}\marg{lang}} \dots{} \cmd{\end\{otherlanguage\}}
% \item \DescribeEnv{otherlanguage*}\cmd{\begin\{otherlanguage*\}\oarg{options}\marg{lang}} \dots{} \cmd{\end\{otherlanguage*\}}
+% \item \DescribeEnv{hyphenrules}\cmd{\begin\{hyphenrules\}\oarg{options}\marg{lang}} \dots{} \cmd{\end\{hyphenrules\}}\new{1.50}
% \end{itemize}
% ^^A
% \cmd\selectlanguage\marg{lang} and the ¦otherlanguage¦ environment are identical to the
-% the \meta{lang} environment, except that \cmd\selectlanguage\marg{lang}
+% \meta{lang} environment, except that \cmd\selectlanguage\marg{lang}
% does not need to be explicitly closed. The command \cmd\foreinlanguage\marg{lang}\marg{…} and the ¦otherlanguage*¦
% environment are identical with the use of the \cmd\text\meta{lang} or \cmd\textlang\ command, with the one
% notable exception that they do not translate the date with \cmd\today.
%
+% The \meta{hyphenrules} environment only switches the hyphenation patterns to the one associated with the language \meta{lang}
+% (or the language variety as specified via \meta{options}). It does no further language-specific change.
+%
% Since the \XeLaTeX\ and \LuaLaTeX\ format incorporate \pkg{babel}’s \file{hyphen.cfg},
-% the low-level commands for hyphenation and language switching
-% defined there are also accessible.
+% the low-level commands for hyphenation and language switching defined there are in principal also accessible.
+% Note, however, that the availability of such low-level commands is not guaranteed, as \file{hyphen.cfg}, which is
+% out of \pkg{polyglossia}'s control, is (or at least has been) subject to regular change.
%
% \subsection{Other commands}
% The following commands are probably of lesser interest to the end user, but
@@ -1075,25 +1108,49 @@ to track the issues and follow progress.
% which override the hyphenation patterns for specified words. The command takes as argument a space-separated
% list of words where hyphenation points are marked by a dash (if no dash is used, the respective word is not
% hyphenated at all):
-% \begin{Verbatim}
+% \begin{quote}
+% \begin{minipage}{\textwidth}
+% \begin{verbatim}
% \hyphenation{%
% po-ly-glos-sia
% LaTeX
% }
-% \end{Verbatim}
+% \end{verbatim}
+% \end{minipage}
+% \end{quote}
% ^^A
% These exceptions, however, apply to all languages. In addition to this, \pkg{polyglossia} provides
% the command\new{1.45}
-% \displaycmd{\xpghyphenation\oarg{options}\marg{lang}\marg{exceptions}}{\xpghyphenation}
+% \displaycmd{\pghyphenation\oarg{options}\marg{lang}\marg{exceptions}}{\pghyphenation}
% which can be used to define exceptions that only apply to a specific language or language variant,
% respectively.
%
+% \subsection{Hyphenation thresholds}
+%
+% \pkg{Polyglossia} sets reasonable defaults for the hyphenation thresholds of each language,
+% \ie the number of characters that must at least be there at the beginning or end of a
+% word before it is hyphenated (\cmd\lefthyphenmin\ and \cmd\righthyphenmin\ in \TeX).
+% For instance, with English, this threshold is 2 at the beginning (`left') and 3 at the end (`right'),
+% so a word will not be hyphenated within the first two characters at the beginning and the last three
+% characters at the end.
+%
+% To change this value, \pkg{polyglossia} provides the command\new{1.50}
+% \displaycmd{\setlanghyphenmins\oarg{options}\marg{lang}\marg{l}\marg{r}}{\setlanghyphenmins}
+% ^^A
+% where \meta{lang} is to be replaced with the respective language name or alias, \meta{options}
+% can be used to delimit the modification to a particular variety (\eg via \texttt{variant} or \texttt{spelling}),
+% \meta{l} with the left threshold value (\eg \texttt{3}), and \meta{r} with the right
+% threshold value (\eg \verb|\setlanghyphenmins[spelling=old]{german}{4}{4}|).
+% This setting can be changed repeatedly in the preamble and the document body.
+% It applies to all subsequent text in the respective language (variety), but only after the
+% next language switch.
+%
% \subsection{Hyphenation disabling}
%
-% In some very specific contexts (such as music score creation), \TeX{} hyphenation
-% is something to avoid as it may cause troubles. \pkg{polyglossia} provides two
-% functions: \Cmd\disablehyphenation\ and \Cmd\enablehyphenation. Note that if
-% you select a new language while hyphenation is disabled, it will remain disabled.
+% In some very specific contexts (such as music score creation), \TeX\ hyphenation
+% is something to avoid completely as it may cause troubles.
+% \pkg{Polyglossia} provides two functions: \Cmd\disablehyphenation\ and \Cmd\enablehyphenation.
+% Note that if you select a new language while hyphenation is disabled, it will remain disabled.
% If you re-enable it, the hyphenation patterns of the currently selected language
% will be activated.
%
@@ -1143,15 +1200,23 @@ to track the issues and follow progress.
% as well as the form of the numerals (unless overriden by the following option).
% \item \xpgchoicekey{numerals}{\xpgpresetvalue{mashriq} or \xpgvalue{maghrib}}
% The latter is the default when \xpgvalue{locale=algeria}, \xpgvalue{tunisia}, or \xpgvalue{morocco}.
+% \item \xpgboolkeyfalse[1.50]{abjadalph}
+% Set this to true if you want the alphabetic counters to be output using \cmd\abjadalph\ rather than \cmd\abjad.
+% Note that this limits the counter scope to 28 (see \cmd\abjadalph\ below).
% \item \xpgboolkeyfalse[1.0.3]{abjadjimnotail}
% Set this to true if you want the \textit{abjad} form of the number three to be \textarabic{ج‍} – as in the manuscript tradition – instead of the modern usage \textarabic{ج}.
% \end{itemize}
% \paragraph*{Commands:}
% \begin{itemize}
-% \item \Cmd\abjad and \Cmd\abjadmaghribi (see section \ref{abjad})
-% \item \Cmd\aemph to emphasize text with \cmd\overline.\new{1.2.0}
-% ¦\textarabic{\aemph{اب}}¦ yields \textarabic{\aemph{اب}}.
-% This command is also available for Farsi, Urdu, etc.
+% \item \Cmd\abjad outputs Arabic \textit{abjad} numbers according to the Mashriq varieties.
+% Example: ¦\abjad{1863}¦ yields \textarabic{\abjad{1863}}.
+% \item \Cmd\abjadmaghribi outputs Arabic \textit{abjad} numbers according to the Maghrib varieties.
+% Example: ¦\abjadmaghribi{1863}¦ yields \textarabic{\abjadmaghribi{1863}}.
+% \item \Cmd\abjadalph\new{1.50} steps through the Arabic alphabet, thus it can only be used up to 28.
+% Example: ¦\textarabic{\abjadalph{18}}¦ yields \textarabic{\abjadalph{18}}.
+% \item \Cmd\aemph to emphasize text with \cmd\overline.\new{1.2.0}
+% ¦\textarabic{\aemph{اب}}¦ yields \textarabic{\aemph{اب}}.
+% This command is also available for Farsi, Urdu, etc.
% \end{itemize}
%
% \subsection{armenian}\label{armenian}
@@ -1169,20 +1234,32 @@ to track the issues and follow progress.
% If this is turned on, the following shorthands are activated:
% \begin{shorthands}
% \item[¦"-¦] adds a hyphenation point that does still allow for hyphenation at the points preset
-% in the hyphenation patterns (as opposed to \cmd\-).
+% in the hyphenation patterns (as opposed to \cmd\-).
+% \item[¦"=¦] adds an explicit hyphen with a breakpoint, allowing for hyphenation at the
+% other points preset in the hyphenation patterns (as opposed to plain ¦-¦).
% \item[\texttt{"\textasciitilde}] for a hyphen sign without a breakpoint. Useful for
-% cases where the hyphen should stick at the following syllable.
+% cases where the hyphen should stick at the following syllable.
% \item[¦"|¦] disables a ligature at this position.
% \item[¦""¦] allows for a line break at this position (without hyphenation sign).
-% \item[¦"---¦] Cyrillic emdash in plain text.
-% \item[¦"--~¦] Cyrillic emdash in compound names (surnames).
-% \item[¦"--*¦] Cyrillic emdash for denoting direct speech.
% \item[¦",¦] thinspace for initials with a breakpoint in following surname.
% \item[¦"‘¦] for German left double quotes (looks like ,,).
% \item[¦"’¦] for German right double quotes (looks like “).
% \item[¦"<¦] for French left double quotes (looks like <<).
% \item[¦">¦] for French right double quotes (looks like >>).
% \end{shorthands}
+%
+% There are also three shorthands for the Cyrillic dash (\textrussian{тире}), which is shorter than the
+% emdash but longer than the endash (namely 0.8\,em).
+% Note that, since it is not covered by unicode, this character is faked by telescoping two endashes:
+% \begin{shorthands}
+% \item[¦"---¦] Cyrillic dash for the use in normal text. This requires preceding space
+% in input (trailing space is optional) and prints with a non-breakable thin space before
+% and after the dash.
+% \item[¦"--\textasciitilde¦] Cyrillic dash for the use in compound names (surnames).
+% As opposed to ¦"---¦ this removes any space before and after the dash.
+% \item[¦"--*¦] Cyrillic dash for denoting direct speech. This adds a larger space after
+% the dash. Space before the dash is output as is.
+% \end{shorthands}
% \item \xpgchoicekey{numerals}{\xpgpresetvalue{arabic}, \xpgvalue{cyrillic-alph} or \xpgvalue{cyrillic-trad}}
% Uses either Arabic numerals or Cyrillic alphanumerical numbering. The two Cyrillic variants differ as follows:
% \begin{itemize}
@@ -1195,7 +1272,8 @@ to track the issues and follow progress.
% With ¦spelling=classic¦, captions and dates adhere to the Taraškievica (or
% Belarusian classical) orthography rather than the standard orthography.
% \end{itemize}
-% ^^A
+%
+% \condbreak{\baselineskip}
% \paragraph*{Commands:}
% \begin{itemize}
% \item \Cmd\Asbuk: produces uppercased Cyrillic alphanumerals, for environments such as ¦enumerate¦.
@@ -1437,20 +1515,31 @@ to track the issues and follow progress.
% If this is turned on, the following shorthands are activated:
% \begin{shorthands}
% \item[¦"-¦] adds a hyphenation point that does still allow for
-% hyphenation at the points preset in the hyphenation patterns (as opposed
-% to \cmd\-).
+% hyphenation at the points preset in the hyphenation patterns (as opposed to \cmd\-).
+% \item[¦"=¦] adds an explicit hyphen with a breakpoint, allowing for hyphenation at the
+% other points preset in the hyphenation patterns (as opposed to plain ¦-¦).
% \item[\texttt{"\textasciitilde}] for a hyphen sign without a breakpoint. Useful for
% cases where the hyphen should stick at the following syllable.
% \item[¦"|¦] disables a ligature at this position.
% \item[¦""¦] allows for a line break at this position (without hyphenation sign).
-% \item[¦"---¦] Cyrillic emdash in plain text.
-% \item[¦"--~¦] Cyrillic emdash in compound names (surnames).
-% \item[¦"--*¦] Cyrillic emdash for denoting direct speech.
% \item[¦",¦] thinspace for initials with a breakpoint in following surname.
-% \item[¦"‘¦] for German left double quotes (looks like ,,).
-% \item[¦"’¦] for German right double quotes (looks like “).
-% \item[¦"<¦] for French left double quotes (looks like <<).
-% \item[¦">¦] for French right double quotes (looks like >>).
+% \item[¦"‘¦] for German-style left double quotes (looks like ,,).
+% \item[¦"’¦] for German-style right double quotes (looks like “).
+% \item[¦"<¦] for French-style left double quotes (looks like <<).
+% \item[¦">¦] for French-style right double quotes (looks like >>).
+% \end{shorthands}
+%
+% There are also three shorthands for the Cyrillic dash (\textrussian{тире}), which is shorter than the
+% emdash but longer than the endash (namely 0.8\,em).
+% Note that, since it is not covered by unicode, this character is faked by telescoping two endashes:
+% \begin{shorthands}
+% \item[¦"---¦] Cyrillic dash for the use in normal text. This requires preceding space
+% in input (trailing space is optional) and prints with a non-breakable thin space before
+% and after the dash.
+% \item[¦"--\textasciitilde¦] Cyrillic dash for the use in compound names (surnames).
+% As opposed to ¦"---¦ this removes any space before and after the dash.
+% \item[¦"--*¦] Cyrillic dash for denoting direct speech. This adds a larger space after
+% the dash. Space before the dash is output as is.
% \end{shorthands}
% \item \xpgchoicekey{numerals}{\xpgpresetvalue{arabic} or \xpgvalue{georgian}}
% Uses either Arabic numerals or Georgian alphanumerical numbering.
@@ -1490,10 +1579,10 @@ to track the issues and follow progress.
%
% There are also four shorthands for quotation signs:
% \begin{shorthands}
-% \item[¦"`¦] for German left double quotes („)
-% \item[¦"'¦] for German right double quotes (“)
-% \item[¦"<¦] for French left double quotes («)
-% \item[¦">¦] for French right double quotes (»).
+% \item[¦"`¦] for German-style left double quotes („)
+% \item[¦"'¦] for German-style right double quotes (“)
+% \item[¦"<¦] for French-style left double quotes («)
+% \item[¦">¦] for French-style right double quotes (»).
% \end{shorthands}
% \item \xpgchoicekey[1.2.0]{script}{\xpgpresetvalue{latin} or \xpgvalue{blackletter}\new{1.46} (= \xpgvalue{fraktur})}
% Setting ¦script=blackletter¦ adapts the captions for typesetting German in blackletter type (using the long s (ſ)
@@ -1809,18 +1898,30 @@ to track the issues and follow progress.
% \begin{shorthands}
% \item[¦"-¦] adds a hyphenation point that does still allow for hyphenation at the points preset
% in the hyphenation patterns (as opposed to \cmd\-).
+% \item[¦"=¦] adds an explicit hyphen with a breakpoint, allowing for hyphenation at the
+% other points preset in the hyphenation patterns (as opposed to plain ¦-¦).
% \item[\texttt{"\textasciitilde}] for a hyphen sign without a breakpoint. Useful for
% cases where the hyphen should stick at the following syllable.
% \item[¦"|¦] disables a ligature at this position.
% \item[¦""¦] allows for a line break at this position (without hyphenation sign).
-% \item[¦"---¦] Cyrillic emdash in plain text.
-% \item[¦"--~¦] Cyrillic emdash in compound names (surnames).
-% \item[¦"--*¦] Cyrillic emdash for denoting direct speech.
% \item[¦",¦] thinspace for initials with a breakpoint in following surname.
-% \item[¦"‘¦] for German left double quotes (looks like ,,).
-% \item[¦"’¦] for German right double quotes (looks like “).
-% \item[¦"<¦] for French left double quotes (looks like <<).
-% \item[¦">¦] for French right double quotes (looks like >>).
+% \item[¦"‘¦] for German-style left double quotes (looks like ,,).
+% \item[¦"’¦] for German-style right double quotes (looks like “).
+% \item[¦"<¦] for French-style left double quotes (looks like <<).
+% \item[¦">¦] for French-style right double quotes (looks like >>).
+% \end{shorthands}
+%
+% There are also three shorthands for the Cyrillic dash (\textrussian{тире}), which is shorter than the
+% emdash but longer than the endash (namely 0.8\,em).
+% Note that, since it is not covered by unicode, this character is faked by telescoping two endashes:
+% \begin{shorthands}
+% \item[¦"---¦] Cyrillic dash for the use in normal text. This requires preceding space
+% in input (trailing space is optional) and prints with a non-breakable thin space before
+% and after the dash.
+% \item[¦"--\textasciitilde¦] Cyrillic dash for the use in compound names (surnames).
+% As opposed to ¦"---¦ this removes any space before and after the dash.
+% \item[¦"--*¦] Cyrillic dash for denoting direct speech. This adds a larger space after
+% the dash. Space before the dash is output as is.
% \end{shorthands}
% \item \xpgchoicekey{numerals}{\xpgpresetvalue{arabic}, \xpgvalue{cyrillic-alph} or \xpgvalue{cyrillic-trad}}
% Uses either Arabic numerals or Cyrillic alphanumerical numbering. The two Cyrillic variants differ as follows:
@@ -1881,13 +1982,25 @@ to track the issues and follow progress.
% \begin{shorthands}
% \item[¦"-¦] adds a hyphenation point that does still allow for hyphenation at the points preset
% in the hyphenation patterns (as opposed to \cmd\-).
-% \item[\texttt{"\textasciitilde}] for a hyphen sign without a breakpoint. Useful for
+% \item[¦"=¦] adds an explicit hyphen with a breakpoint, allowing for hyphenation at the
+% other points preset in the hyphenation patterns (as opposed to plain ¦-¦).
+% \item[\texttt{"\textasciitilde}] adds an explicit hyphen without a breakpoint. Useful for
% cases where the hyphen should stick at the following syllable.
% \item[¦"|¦] disables a ligature at this position.
% \item[¦""¦] allows for a line break at this position (without hyphenation sign).
-% \item[¦"---¦] Cyrillic emdash in plain text.
-% \item[¦"--~¦] Cyrillic emdash in compound names (surnames).
-% \item[¦"--*¦] Cyrillic emdash for denoting direct speech.
+% \end{shorthands}
+%
+% There are also three shorthands for the Cyrillic dash (\textrussian{тире}), which is shorter than the
+% emdash but longer than the endash (namely 0.8\,em).
+% Note that, since it is not covered by unicode, this character is faked by telescoping two endashes:
+% \begin{shorthands}
+% \item[¦"---¦] Cyrillic dash for the use in normal text. This requires preceding space
+% in input (trailing space is optional) and prints with a non-breakable thin space before
+% and after the dash.
+% \item[¦"--\textasciitilde¦] Cyrillic dash for the use in compound names (surnames).
+% As opposed to ¦"---¦ this removes any space before and after the dash.
+% \item[¦"--*¦] Cyrillic dash for denoting direct speech. This adds a larger space after
+% the dash. Space before the dash is output as is.
% ^^A These are commented out in gloss-russian
% ^^A \item[¦",¦] thinspace for initials with a breakpoint in following surname.
% ^^A \item[¦"‘¦] for German left double quotes (looks like ,,).
@@ -1895,6 +2008,10 @@ to track the issues and follow progress.
% ^^A \item[¦"<¦] for French left double quotes (looks like <<).
% ^^A \item[¦">¦] for French right double quotes (looks like >>).
% \end{shorthands}
+% \item \xpgboolkeytrue[1.50]{forceheadingpunctuation}
+% By default, chapter and section numbers always have a trailing punctuation in Russian
+% (as in \emph{1.1.} as opposed to \emph{1.1}). If this option is set to false, \textsf{polyglossia}
+% will not touch heading punctuation, so this will be whatever the class or a package determines.
% \item \xpgboolkeytrue[1.46]{indentfirst}
% By default, all paragraphs are indented in Russian, also those after a
% chapter or section heading. If this option is false, the latter paragraphs
@@ -2091,14 +2208,13 @@ to track the issues and follow progress.
% If this is turned on, the following shorthands are activated:
% \begin{shorthands}
% \item[¦"-¦] adds a hyphenation point that does still allow for hyphenation at the points preset
-% in the hyphenation patterns (as opposed to \cmd\-).
+% in the hyphenation patterns (as opposed to \cmd\-).
+% \item[¦"=¦] adds an explicit hyphen with a breakpoint, allowing for hyphenation at the
+% other points preset in the hyphenation patterns (as opposed to plain ¦-¦).
% \item[\texttt{"\textasciitilde}] for a hyphen sign without a breakpoint. Useful for
-% cases where the hyphen should stick at the following syllable.
+% cases where the hyphen should stick at the following syllable.
% \item[¦"|¦] disables a ligature at this position.
% \item[¦""¦] allows for a line break at this position (without hyphenation sign).
-% \item[¦"---¦] Cyrillic emdash in plain text.
-% \item[¦"--~¦] Cyrillic emdash in compound names (surnames).
-% \item[¦"--*¦] Cyrillic emdash for denoting direct speech.
% ^^A These are commented out in gloss-ukrainian
% ^^A \item[¦",¦] thinspace for initials with a breakpoint in following surname.
% ^^A \item[¦"‘¦] for German left double quotes (looks like ,,).
@@ -2106,6 +2222,19 @@ to track the issues and follow progress.
% ^^A \item[¦"<¦] for French left double quotes (looks like <<).
% ^^A \item[¦">¦] for French right double quotes (looks like >>).
% \end{shorthands}
+%
+% There are also three shorthands for the Cyrillic dash (\textrussian{тире}), which is shorter than the
+% emdash but longer than the endash (namely 0.8\,em).
+% Note that, since it is not covered by unicode, this character is faked by telescoping two endashes:
+% \begin{shorthands}
+% \item[¦"---¦] Cyrillic dash for the use in normal text. This requires preceding space
+% in input (trailing space is optional) and prints with a non-breakable thin space before
+% and after the dash.
+% \item[¦"--\textasciitilde¦] Cyrillic dash for the use in compound names (surnames).
+% As opposed to ¦"---¦ this removes any space before and after the dash.
+% \item[¦"--*¦] Cyrillic dash for denoting direct speech. This adds a larger space after
+% the dash. Space before the dash is output as is.
+% \end{shorthands}
% \item \xpgchoicekey{numerals}{\xpgpresetvalue{arabic}, \xpgvalue{cyrillic-alph} or \xpgvalue{cyrillic-trad}}
% Uses either Arabic numerals or Cyrillic alphanumerical numbering. The two Cyrillic variants differ as follows:
% \begin{itemize}
@@ -2391,7 +2520,7 @@ to track the issues and follow progress.
% Note also that the rule switches might interfere in bad ways with packages or classes that redefine footnotes themselves. This is also the reason
% why \cmd\autofootnoterule\ is not used by default.
%
-% \condbreak{5\baselineskip}
+%
% \section{Calendars}
%
% \subsection{Hebrew calendar (hebrewcal.sty)}
@@ -2529,9 +2658,9 @@ to track the issues and follow progress.
% In alphabetical order: \TA{Ignas Anikevicius}, \TA{Sina Ahmadi}, \TA{Wouter Bolsterlee}, \TA{Christian Buhtz},
% \TA{Zgarbul Andrey}, \TA{Oleg Domanov}, \TA{Philipp Gesang}, \TA{Kevin Godby}, \TA{Enrico Gregorio},
% \TA{Khaled Hosny}, \TA{Najib Idrissi}, user \TA{julroy67}, \TA{Dohyun Kim}, \TA{Phil Kime}, \TA{Mike Kroutikov},
-% \TA{Ivan Kokan}, \TA{Caleb Maclennan}, \TA{José Mancera}, \TA{Yevgen Pogribnyi}, \TA{Will Robertson}, \TA{Maïeul Rouquette},
-% \TA{Elie Roux}, \TA{Hugo Roy}, \TA{Guy Rutenberg}, \TA{Philipp Stephani}, \TA{Niranjan Tambe}, \TA{Keno Wehr},
-% \TA{Dominik Wujastyk}, \TA{Sertaç Ö. Yıldız}, \TA{Maksim Zholudev}, \TA{Yan Zhou}, and \TA{Stefan Zlatinov}.
+% \TA{Ivan Kokan}, \TA{Caleb Maclennan}, \TA{José Mancera}, \TA{Miquel Ortega}, \TA{Yevgen Pogribnyi}, \TA{Will Robertson},
+% \TA{Maïeul Rouquette}, \TA{Elie Roux}, \TA{Hugo Roy}, \TA{Guy Rutenberg}, \TA{Philipp Stephani}, \TA{Niranjan Tambe},
+% \TA{Keno Wehr}, \TA{Dominik Wujastyk}, \TA{Sertaç Ö. Yıldız}, \TA{Maksim Zholudev}, \TA{Yan Zhou}, and \TA{Stefan Zlatinov}.
% Their respective contributions can be identified from the contributor statistics on
% \href{https://github.com/reutenauer/polyglossia/graphs/contributors}{GitHub}.
%
@@ -2550,6 +2679,5547 @@ to track the issues and follow progress.
% \StopEventually{}
% \section{Implementation}
% \iffalse
+%<*polyglossia.sty>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia.sty}
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{polyglossia}[2020/10/09 v1.50
+ Modern multilingual typesetting with XeLaTeX and LuaLaTeX]
+\RequirePackage{etoolbox}
+\RequirePackage{makecmds}
+\RequirePackage{xkeyval}[2008/08/13]
+% Will raise error if used with anything else than XeTeX or LuaTeX
+\RequirePackage{fontspec}[2010/06/08]% v2.0
+\RequirePackage{iftex}
+\RequirePackage{expl3}
+\RequirePackage{l3keys2e}
+\RequirePackage{xparse}
+\RequirePackage{filehook}
+
+% correct a bug in tracklang
+\AtBeginOfPackageFile*{tracklang}{
+ \@ifpackagelater{tracklang}{2019/08/30}{}{\global\def\AddTrackedLangage{\AddTrackedLanguage}}
+}
+
+
+% fontspec now uses LaTeX3 packages such as expl3, so we need this:
+\ExplSyntaxOn
+
+%% This is for compatibility with Babel-aware package:
+\cslet{ver@babel.sty}{\@empty} % this "fakes" babel
+\def\languageshorthands#1{\relax} %this is for scrlttr2 class
+\def\bbl@cs#1{\csname bbl@#1\endcsname}%
+\AtEndPreamble{\let\bbl@set@language\xpg@set@language@aux} %for biblatex
+\AtEndPreamble{\let\bbl@main@language\xpg@main@language} %for biblatex
+\providecommand\texorpdfstring[2]{#1}% dummy command if hyperref is not loaded
+
+\ifluatex
+ \RequirePackage{luatexbase} % already included by fontspec, but needed here
+ \RequireLuaModule{polyglossia}
+\fi
+
+% Which version of XeTeX do we use? What is the boudary class? 4095 or 255
+\@ifundefined{e@alloc@intercharclass@top}
+ {\chardef\xpg@boundaryclass=\@cclv}
+ {\let\xpg@boundaryclass=\e@alloc@intercharclass@top}
+
+% Useful for getting list of loaded languages and variants. Like babel's bbl@loaded
+\let\xpg@loaded\@empty% list of loaded languages (polyglossia name)
+\let\xpg@vloaded\@empty% list of loaded variants
+\let\xpg@bloaded\@empty% list of loaded languages (babel name)
+\let\xpg@bcp@loaded\@empty% list of loaded languages (bcp-47 id)
+
+% counter in latin
+\def\latinalph#1{\expandafter\latin@alph\csname c@#1\endcsname}
+\def\latinAlph#1{\expandafter\latin@Alph\csname c@#1\endcsname}
+
+% select language hook
+\cs_new_nopar:Nn \polyglossia@AtBeginDocument@selectlanguage: {}
+% \disablehyphenation hook
+\cs_new_nopar:Nn \polyglossia@AtBeginDocument@hyphenation: {}
+
+% hook to be executed at begin of document
+\cs_new_nopar:Nn \polyglossia@AtBeginDocument: {
+ % save various command
+ \let\latin@alph\@alph % TODO rename when we have the C locale
+ \let\latin@Alph\@Alph % TODO rename when we have the C locale
+ % push to C language gloss
+ \let\polyglossia@Clang@@arabic\@arabic
+ \let\polyglossia@Clang@arabic\arabic
+
+ \xpg@initial@setup
+ % apply \familydefault changes
+ \xpg@set@familydefault
+}
+
+\AtBeginDocument{
+ \polyglossia@AtBeginDocument:
+}
+
+% The following needs to go after any \AtBeginDocument (also of packages
+% loaded after \set[main|other]language
+\AfterEndPreamble{
+ % now we have the C locale definition: select the language
+ \polyglossia@AtBeginDocument@selectlanguage:
+ % If hyphenation disabling has been requested in preamble, do it now
+ \polyglossia@AtBeginDocument@hyphenation:
+}
+
+%% custom message macros
+\providecommand*{\xpg@error}[1]{%
+ \PackageError{polyglossia}{#1}{}%
+}
+
+\providecommand*{\xpg@warning}[1]{%
+ \PackageWarning{polyglossia}{#1}%
+}
+
+\providecommand*{\xpg@info}[1]{%
+ \PackageInfo{polyglossia}%
+ {#1\@gobble}%
+} %% the \@gobble is to prevent displaying the line nr
+
+%TODO change all instances of \xpg@nopatterns in gloss-*.ldf files
+\providecommand*{\xpg@nopatterns@fallback}[2][nohyphenation]{%
+ \xpg@warning{No~ hyphenation~ patterns~ were~ loaded~ for~ `#2'\MessageBreak
+ I~ will~ use~ \string\language=\string\l@ #1\space instead}%
+ \expandafter\adddialect\csname l@#2\expandafter\endcsname\csname l@#1\endcsname\relax}
+
+\providecommand*{\xpg@nopatterns}[1]{%
+ \xpg@warning{No~ hyphenation~ patterns~ were~ loaded~ for~ `#1'\MessageBreak
+ I~ will~ use~ \string\language=\string\l@nohyphenation\space instead}%
+ %%TODO? \expandafter\adddialect\csname l@#1\endcsname\l@nohyphenation\relax
+ }
+
+\def\xpg@ill@value#1#2{%
+ \xpg@warning{Illegal~ value~ (#1)~ for~ #2}}
+
+% error out if lang is not loaded
+\cs_new_nopar:Nn \polyglossia@error@iflangnotloaded:n
+{
+ \cs_if_exist:cF{#1@loaded}
+ {
+ \xpg@error{language~ #1~ is~ not~ loaded.~ Please~ load~ it~ before~ using~ it.}
+ }
+}
+
+
+% error do not use directly the gloss file
+\msg_new:nnn { polyglossia } { directloadgloss }
+{
+ You~ should~ not~ load~ directly~ the~ gloss~ file~ using~ `\string\usepackage'.
+ You~ must~ use~ `\string\setotherlanguage\{#1\}' or `\string\setmainlanguage\{#1\}'.
+}
+\msg_redirect_name:nnn { polyglossia } { directloadgloss } { critical }
+
+%% use macro if defined, else warn that it is not
+\def\csuse@warn#1{%
+ \ifcsundef{#1}{\xpg@warning{ \expandafter\string\csname #1\endcsname\space is~ not~ defined}}%
+ {\csname #1\endcsname}}
+
+%% ensure directionality if bidi is loaded, else ignore
+\def\@@ensure@dir#1{\ifcsundef{@ensure@dir}{#1}{\@ensure@dir{#1}}}
+\def\@@ensure@maindir#1{\ifcsundef{@ensure@maindir}{#1}{\@ensure@maindir{#1}}}
+
+%% Used by the language definitions files for right-to-left languages
+\def\RequireBidi{%
+ \str_case_e:nnF{\c_sys_engine_str}{
+ {luatex}{\ifx\@onlypreamble\@notprerr\else\RequirePackage{luabidi}\fi}
+ {xetex}{\ifx\@onlypreamble\@notprerr\else\RequirePackage{bidi}\fi}
+ }
+ {
+ \xpg@warning{You’re running a TeX engine that is not LuaTeX or XeTeX.\MessageBreak
+ That is almost guaranteed to cause problems.}
+ }
+}
+
+% (lua)bidi commands to change directionality for paragraphs
+% and inline text.
+% overwritten with correct package
+\cs_new_nopar:Nn{\polyglossia@setpardirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\relax}%
+ {RL}{\xpg@error{right-to-left,~ but~ (lua)bidi~ package~ was~ not~ loaded!}}%
+ }%
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(base~ wrapper)}}%
+}
+\cs_new_nopar:Nn{\polyglossia@settextdirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\relax}%
+ {RL}{\xpg@error{right-to-left,~ but~ (lua)bidi~ package~ was~ not~ loaded!}}%
+ }%
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(base~ wrapper)}}%
+}
+\AtEndOfPackageFile*{bidi}{%
+ \ExplSyntaxOn%
+ \cs_gset_nopar:Nn{\polyglossia@setpardirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\setLR}%
+ {RL}{\setRL}%
+ }%
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(bidi~ wrapper)}}%
+ }%
+ \cs_gset_nopar:Nn{\polyglossia@settextdirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\LRE}%
+ {RL}{\RLE}%
+ }%
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(bidi~ wrapper)}}%
+ }%
+ \ExplSyntaxOff%
+}
+\AtEndOfPackageFile*{luabidi}{%
+ \ExplSyntaxOn%
+ \cs_gset_nopar:Nn{\polyglossia@setpardirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\setLR}%
+ {RL}{\setRL}%
+ }
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(luabidi~ wrapper)}}%
+ }%
+ \cs_gset_nopar:Nn{\polyglossia@settextdirection:n}{%
+ \str_case_e:nnTF{#1}{%
+ {LR}{\LRE}%
+ {RL}{\RLE}%
+ }
+ {}%
+ {\xpg@error{Unknown~ language~ direction~ #1 ~(luabidi~ wrapper)}}%
+ }%
+ \ExplSyntaxOff%
+}
+
+%% compatibility with babel
+\let\addto\gappto% gappto is defined in etoolbox
+
+%% NEW EXPERIMENTAL SETUP INTERFACE FOR GLOSS FILES
+%% options currently available:
+%% language : the name of the language (as understood by fontspec)
+%% hyphennames : the different hyphenation patterns to try (comma separated list)
+%%% TODO: if pattern is prefixed by !, then it should be loaded as a fallback, with \xpg@nopatterns@fallback - i.e. with a warning: e.g. sanskrit for hindi, or catalan for asturian. – Also for languages with variants! (English and German, etc.)
+%% script : the name of the script (as understood by fontspec) – default is Latin
+%% scripttag : the OpenType tag for the script
+%% langtag : the OpenType tag for the language
+%% hyphenmins : the hyphenmins for this language (comma-sep list of two integers)
+%% frenchspacing : boolean
+%% indentfirst : boolean
+%% fontsetup : boolean
+%% TODO: nouppercase : boolean (for scripts like Arabic, Devanagari, etc which have no concept of uppercase/lowercase)
+%% TODO: localalph = {<alph_csname>,<Alph_csname>}
+%% TODO: localnumeral = <csname>
+%% or even better localdigits = {0123456789} for fully automatic setup
+\newif\if@xpg@language@really@defined@
+\newcommand*\PolyglossiaSetup[2]{%
+ \polyglossia@keys_define_lang:n{#1}%
+ \keys_set:nn { polyglossia / #1 } { #2 }%
+ \prop_log:N{\polyglossia@langsetup}
+ \polyglossia_setup_hyphen:n {#1}
+ %define booleans etoolbox style and set defaults
+ %% TODO ? \providetoggle{#1@setup@done}%
+ % we initialize these so that we can use \gappto below
+ \csgdef{init@extras@#1}{}%
+ \csgdef{init@noextras@#1}{}% we don't use this yet: remove?
+ % here we do the fontsetup:
+ \polyglossia@lang@autosetupfont:n{#1}
+ %% TODO? \toggletrue{#1@setup@done}%
+ % reinit \do
+ \def\do##1{\setotherlanguage{##1}}%
+}
+
+% Adjust language key setting after initial setup
+% This is needed, e.g., for languages with varying script
+\DeclareDocumentCommand \SetLanguageKeys { m m }
+{
+ \clist_map_inline:nn { #1 } { \keys_set:nn { polyglossia / ##1 } { #2 } }
+}
+
+
+% setup hyphennames from a str list of hyphen
+\cs_new:Nn \polyglossia_setup_hyphen:n {
+ \exp_args:Nne \clist_set:Nn{\l_tmpa_clist}{\prop_item:Nn \polyglossia@langsetup {#1 / hyphennames}}
+ \providebool{havehyphen}
+ \boolfalse{havehyphen}
+ % for each hyphen in the set until we find one that works
+ \clist_map_inline:Nn \l_tmpa_clist {
+ \ifbool{havehyphen}{}{%
+ % check if language hyphenname is defined
+ \polyglossia@check@ifdefined:NF{#1}{%
+ % if not, first consider nohyphenation
+ \str_if_eq:nnTF{##1}{nohyphenation}
+ {%
+ \cs_gset_eq:cc{l@#1}{l@##1}
+ \global\booltrue{havehyphen}
+ }{%
+ % then test if hyphenation is defined
+ \xpg@ifdefined{##1}{
+ % test if language hyphenation is nohyphenation
+ \cs_if_eq:cNF{l@#1}{\l@nohyphenation}{\global\booltrue{havehyphen}}{%
+ % if false define language to hyphenation if it is not equal...
+ \str_if_eq:nnF{#1}{##1}{\cs_gset_eq:cc{l@#1}{l@##1}}
+ % ...and load
+ \xpg@set@hyphenation@patterns{##1}
+ \global\booltrue{havehyphen}
+ }%
+ }{}%
+ }%
+ }%
+ }%
+ }%
+ % if l@#1 does not yet exist,
+ % we assign it to nohyphenation
+ % we do this here in case and if the hyphennames key was omitted
+ \ifbool{havehyphen}{}{%
+ \xpg@ifdefined{#1}{}%
+ {
+ \xpg@nopatterns{#1}
+ \expandafter\adddialect\csname l@#1\endcsname\l@nohyphenation\relax
+ }%
+ }%
+ \csdef{#1@language}{%
+ \polyglossia@setup@language@patterns{#1}%
+ }%
+ % setup hyphenmins
+ \exp_args:NNe \clist_set:Nn \l_tmpa_clist
+ { \prop_item:Nn \polyglossia@langsetup {#1 / hyphenmins} }
+ \cs_if_eq:cNF {l@#1} \l@nohyphenation
+ {
+ \use:x
+ {
+ \exp_not:N \setlocalhyphenmins {#1}
+ { \clist_item:Nn \l_tmpa_clist {1} }
+ { \clist_item:Nn \l_tmpa_clist {2} }
+ }
+ }
+}
+
+\newcommand*\polyglossia@setup@language@patterns[1]{%
+ \ifbool{xpg@hyphenation@disabled}{%
+ \xdef\xpg@lastlanguage{\the\csname l@#1\endcsname}%
+ }{%
+ % first, test if \l@#1 exists
+ % without that, \csname l@#1\endcsname will be defined as \relax
+ \cs_if_exist:cTF {l@#1}
+ {
+ \cs_if_eq:cNTF {l@#1} \l@nohyphenation
+ {
+ \language=\l@nohyphenation
+ }
+ {
+ \xpg@set@hyphenation@patterns{#1}
+ }
+ }
+ {%
+ % Since this function is sometimes called from the gloss files
+ % directly, we need to check whether the requested hyphenname exists.
+ \xpg@ifdefined{#1}{}%
+ {%
+ \xpg@nopatterns{#1}
+ \expandafter\adddialect\csname l@#1\endcsname\l@nohyphenation\relax%
+ }%
+ \xpg@set@hyphenation@patterns{#1}
+ }
+ }
+}
+
+\prop_new:N \polyglossia@langsetup
+
+\cs_new_protected:Npn \polyglossia@keys_define_lang:n #1 {
+ \keys_define:nn {polyglossia}{
+ % the script font
+ #1 / script
+ .code:n = {
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/script}{##1}
+ \prop_gput:Nnx{\polyglossia@langsetup}{#1/lcscript}
+ {\tl_if_empty:nF{##1}{\str_lowercase:n##1}}
+ },
+ #1 / script
+ .value_required:n = true,
+ #1 / script
+ .initial:n = latin,
+ % the opentype script tag
+ #1 / scripttag
+ .code:n = {\prop_gput:Nnn{\polyglossia@langsetup}{#1/scripttag}{##1}},
+ #1 / scripttag
+ .default:n = {},
+ #1 / scripttag
+ .initial:n = {},
+ % the language full name
+ #1 / language
+ .code:n = {\prop_gput:Nnn{\polyglossia@langsetup}{#1/language}{##1}},
+ #1 / language
+ .value_required:n = true,
+ #1 / language
+ .initial:x = {\str_upper_case:n#1},
+ % the language tag
+ #1 / langtag
+ .code:n = {\prop_gput:Nnn{\polyglossia@langsetup}{#1/langtag}{##1}},
+ #1 / langtag
+ .value_required:n = true,
+ #1 / langtag
+ .initial:n = {},
+ % the BCP-47 tag
+ #1 / bcp47
+ .code:n = {\prop_gput:Nnn{\polyglossia@langsetup}{#1/bcp47}{##1}},
+ #1 / bcp47
+ .value_required:n = true,
+ #1 / bcp47
+ .initial:n = {},
+ % hyphennames
+ #1 / hyphennames
+ .code:n = {
+ \clist_set:Nn{\l_tmpa_clist}{##1}
+ \prop_gput:Nnx{\polyglossia@langsetup}{#1/hyphennames}{\clist_use:Nn \l_tmpa_clist {,}}
+ },
+ #1 / hyphennames
+ .value_required:n = true,
+ #1 / hyphennames
+ .initial:x = {\c_empty_clist},
+ % direction
+ #1 / direction
+ . code:n = {
+ \str_case_e:nnTF{##1}{
+ {LR}{}
+ {RL}{\RequireBidi}
+ }
+ {\prop_gput:Nnn{\polyglossia@langsetup}{#1/direction}{##1}}
+ {\xpg@error{Unknown~ direction~ "##1"~ for~ language~ "#1"}}
+ },
+ #1 / direction
+ .value_required:n = true,
+ #1 / direction
+ .initial:n = {LR},
+ % minimal left and right hyphenation minima using
+ #1 / hyphenmins
+ .code:n = {
+ % check syntax
+ \int_compare:nNnF { \clist_count:n {##1} } = {2}
+ {\xpg@error{hypenmins~should~be~a~list~of~two~entries,~got~"##1"}}
+ % set prop
+ \prop_gput:Nnn \polyglossia@langsetup {#1/hyphenmins} {##1}
+ },
+ #1 / hyphenmins
+ .value_required:n = true,
+ #1 / hyphenmins
+ .initial:n = {2,3},
+ % minimal length for hyphenation (LuaTeX only)
+ #1 / totalhyphenmin
+ .code:n = {
+ % check syntax
+ \int_compare:nNnF { \clist_count:n {##1} } = {1}
+ {\xpg@error{totalhyphenhypenmin~should~be~a~single~entry,~got~"##1"}}
+ % set prop
+ \prop_gput:Nnn \polyglossia@langsetup {#1/totalhyphenmin} {##1}
+ },
+ #1 / totalhyphenmin
+ .value_required:n = false,
+ % frenchspacing
+ #1 / frenchspacing
+ .code:n = {
+ \str_case_e:nnTF{##1}{
+ {true}{}
+ {false}{}
+ }
+ {}
+ {\xpg@error{frenchspacing~should~be~true~or~false. Is~ "##1"~ for~ language~ "#1"}}
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/frenchspacing}{##1}
+ },
+ #1 / frenchspacing
+ .default:n = true,
+ #1 / frenchspacing
+ .initial:n = false,
+ % indent first line
+ #1 / indentfirst
+ .code:n = {
+ \str_case_e:nnTF{##1}{
+ {true}{}
+ {false}{}
+ }
+ {}
+ {\xpg@error{indentfirst~should~be~true~or~false. Is~ "##1"~ for~ language "#1"}}
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/indentfirst}{##1}
+ },
+ #1 / indentfirst
+ .default:n = true,
+ #1 / indentfirst
+ .initial:n = false,
+ % fontsetup
+ #1 / fontsetup
+ .code:n = {
+ \str_case_e:nnTF{##1}{
+ {true}{}
+ {false}{}
+ }
+ {}
+ {\xpg@error{fontsetup~should~be~true~or~false. Is "##1"~ for~ language~ "#1"}}
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/fontsetup}{##1}
+ },
+ #1 / fontsetup
+ .default:n = true,
+ #1 / fontsetup
+ .initial:n = false,
+ % environment name
+ #1 / envname
+ .code:n = {
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/envname}{##1}
+ },
+ #1/ envname.value_required:n = true,
+ #1/ envname.initial:n = {#1},
+ % babel name
+ #1 / babelname
+ .code:n = {
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/babelname}{##1}
+ },
+ #1/ babelname.value_required:n = true,
+ #1/ babelname.initial:n = {#1},
+ % default numerals
+ #1 / localnumeral
+ . code:n = {
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/localnumeral}{##1}
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/Localnumeral}{##1}
+ },
+ #1 / localnumeral.value_required:n = true,
+ #1 / localnumeral.initial:n = {polyglossia@C@localnumeral},
+ % uppercased
+ #1 / Localnumeral
+ . code:n = {
+ \prop_gput:Nnn{\polyglossia@langsetup}{#1/Localnumeral}{##1}
+ },
+ #1 / Localnumeral.value_required:n = true,
+ #1 / Localnumeral.initial:n = {polyglossia@C@localnumeral}
+ }
+}
+
+% TODO move to C module
+\newcommand*{\polyglossia@C@localnumeral}[2]{
+ \polyglossia@Clang@@arabic{#2}
+}
+
+% print using main language
+% #2 is the numeral to print
+% #3 is the mainlanguage (should be expanded)
+% #4 is the current language (should be expanded)
+% #1 is the option list (should be expanded)
+% #5 is the name of the field to use
+\cs_new:Nn \polyglossia_localnumeral_mainlang:nnnnn {
+ \foreignlanguage{#3}{\use:c {\prop_item:Nn \polyglossia@langsetup {#3/#5}} {#1} {#2}}
+}
+
+
+% print using local language
+% #2 is the numeral to print
+% #3 is the mainlanguage (should be expanded)
+% #4 is the current language (should be expanded)
+% #1 is the option list (should be expanded)
+% #5 is the name of the field to use
+\cs_new:Nn \polyglossia_localnumeral_locallang:nnnnn {
+ \use:c {\prop_item:Nn \polyglossia@langsetup {#4/#5}} {#1} {#2}
+}
+
+% this function try to resolve some simple parameter about lang
+% call #2 then branching if found
+% call parameter #3 if not found
+% (use curing)
+\cs_new:Npn \polyglossia_localnumeral_callshortcutorlong:nF #1#2 {
+ \str_case:nnF{#1}{
+ {lang=local}{\polyglossia_localnumeral_locallang:nnnnn}
+ }
+ {#2}
+}
+
+\cs_new:Npn \polyglossia_iii_map_csv_field_split_kv_iii_localnumeral:w #1 = #2 \q_stop {
+ \str_case:nnF{#2}{
+ {local} {\clist_map_break:n{\use_i:nn \polyglossia_localnumeral_locallang:nnnnn }}
+ {default}{\clist_map_break:n{\use_i:nn \polyglossia_localnumeral_locallang:nnnnn }}
+ {*} {\clist_map_break:n{\use_i:nn\polyglossia_localnumeral_mainlang:nnnnn }}
+ {main} {\clist_map_break:n{\use_i:nn\polyglossia_localnumeral_mainlang:nnnnn }}
+ }{
+ \clist_map_break:n{ \use_i_ii:nnn \polyglossia_localnumeral_langlang:nnnnnn {{#2}} }
+ }
+}
+
+
+% call the language
+% #3 is the numeral to print
+% #4 is the mainlanguage (should be expanded)
+% #5 is the current language (should be expanded)
+% #2 is the option list (should be expanded)
+% #6 is the name of the field to use
+% #1 is the language used
+\cs_new:Nn \polyglossia_localnumeral_langlang:nnnnnn {
+ \foreignlanguage{#1}{\use:c {\prop_item:Nn \polyglossia@langsetup {#1/#6}} {#2} {#3}}
+}
+
+
+% check if empty value
+\cs_new:Npn \polyglossia_iii_map_csv_field_split_kv_ii_localnumeral:w #1 #2 = #3 \q_stop {
+ \quark_if_no_value:NTF {#3}
+ {
+ \clist_map_break:n{\use_i:nn \polyglossia_localnumeral_locallang:nnnnn}
+ }
+ {
+ \polyglossia_iii_map_csv_field_split_kv_iii_localnumeral:w #1 \q_stop
+ }
+}
+
+\cs_new:Npn \polyglossia_iii_map_csv_field_split_kv_i_localnumeral:nw #1 #2 = #3 \q_stop {
+ % parse only lang tag
+ \tl_trim_spaces_apply:nN {#2} \str_if_eq:nnT {lang}
+ {
+ % if empty value
+ \quark_if_nil:nTF{#3}
+ {
+ \clist_map_break:n{\use_i:nn \polyglossia_localnumeral_locallang:nnnn}
+ }
+ {
+ % here we know what we have an equal sign
+ \polyglossia_iii_map_csv_field_split_kv_ii_localnumeral:w {#1} #1 \q_no_value \q_stop
+ }
+ }
+}
+
+% map function
+\cs_new:Nn \polyglossia_iii_map_csv_localnumeral:n {
+ % fast case is do nothing is empty
+ \tl_if_empty:nF{#1}
+ {
+ \polyglossia_iii_map_csv_field_split_kv_i_localnumeral:nw {#1} #1 = \q_nil \q_stop
+ }
+}
+
+
+% treat option is empty and option is lang=local
+% #2 number
+% #3 mainlanguage
+% #4 locallanguage
+% #5 field to call
+% #1 option
+% strip space to option
+\cs_new:Nn \polyglossia_iii_localnumeral:nnnnn {
+ \tl_if_blank:nTF{#1}
+ {
+ \polyglossia_localnumeral_mainlang:nnnnn
+ }
+ {
+ \str_if_eq:nnTF{#1}{lang=local}
+ {
+ \polyglossia_localnumeral_locallang:nnnnn
+ }
+ {
+ % use postscript like trick push to stack {#1} {#2} {#3} {#4}
+ \polyglossia_localnumeral_callshortcutorlong:nF {#1}
+ {
+ % same trick here if found we emit \use_i:nn
+ % thus discarding the default choice that is not lang specified thus local
+ \clist_map_function:nN {#1} {\polyglossia_iii_map_csv_localnumeral:n}
+ \polyglossia_localnumeral_locallang:nnnnn
+ }
+ }
+ {#1} {#2} {#3} {#4} {#5}
+ }
+}
+
+
+% internal helper useful for oeee and onnn
+% #1 number
+% #2 mainlanguage
+% #3 locallanguage
+% #4 option
+% #5 field to call
+% strip space to option
+\cs_new:Nn \polyglossia_ii_localnumeral:nnnnn {
+ \tl_trim_spaces_apply:nN {#4} \polyglossia_iii_localnumeral:nnnnn {#1}{#2}{#3}{#5}
+}
+\cs_generate_variant:Nn \polyglossia_ii_localnumeral:nnnnn {
+ eeenn, eeeon, eeeen
+}
+
+% convert the counter to value
+% #1 counter
+% #2 mainlanguage
+% #3 locallanguage
+% #4 option
+\cs_new:Nn \polyglossia_i_localnumeral:nnnnn
+{
+ \polyglossia_ii_localnumeral:eeeen {\int_value:w #1} {#2} {#3} {#4} {#5}
+}
+
+% print number usage \localnumeral[option]{numeral}
+% or \localnumeral*[option]{counter}
+% \Localnumeral[]{numeral} use main language
+% \localnumeral{numeral} use local language
+\NewExpandableDocumentCommand{\localnumeral}{som}
+{
+ \IfBooleanTF{#1}%
+ {% starred: take counter
+ \exp_args:Nc \polyglossia_i_localnumeral:nnnnn {c@#3}
+ {\mainlanguagename} {\languagename} {\IfNoValueTF {#2}{lang=local}{#2}} {localnumeral}
+ }{% unstarred: take number
+ \polyglossia_ii_localnumeral:eeeen {\int_eval:n{#3}}
+ {\mainlanguagename} {\languagename} {\IfNoValueTF {#2}{lang=local}{#2}} {localnumeral}
+ }
+}
+
+% print number usage \Localnumeral[option]{numeral}
+% or \Localnumeral*[option]{counter}
+% \Localnumeral[]{numeral} use main language
+% \localnumeral{numeral} use local language
+\NewExpandableDocumentCommand{\Localnumeral}{som}
+{
+ \IfBooleanTF{#1}%
+ {% starred: take counter
+ \exp_args:Nc \polyglossia_i_localnumeral:nnnnn {c@#3}
+ {\mainlanguagename} {\languagename} {\IfNoValueTF {#2}{lang=local}{#2}} {Localnumeral}
+ }{% unstarred: take number
+ \polyglossia_ii_localnumeral:eeeon {\int_eval:n{#3}}
+ {\mainlanguagename} {\languagename} {\IfNoValueTF {#2}{lang=local}{#2}} {Localnumeral}
+ }
+}
+
+\cs_new_nopar:Nn{\polyglossia@lang@frenchspacing:n}{
+ \prop_get:NxNTF \polyglossia@langsetup {#1/frenchspacing} \l_tmpa_tl
+ {
+ \str_case_e:nnF{\l_tmpa_tl}{
+ {true}{\frenchspacing}
+ {false}{\nonfrenchspacing}
+ }
+ {\xpg@error{frenchspacing~should~be~true~or~false. Is~"\l_tmpa_ttl"~ for~ language~ "#1"}}
+ }
+ {
+ \xpg@error{Could~ not~ retrieve~ key~ frenchspacing~ for~ language~ "#1"}
+ \prop_show:N{\polyglossia@langsetup}
+ }
+}
+
+\cs_new_nopar:Nn{\polyglossia@lang@indentfirst:n}{
+ \prop_get:NxNTF \polyglossia@langsetup {#1/indentfirst} \l_tmpa_tl
+ {
+ \str_case_e:nnF{\l_tmpa_tl}{
+ {true}{\french@indent}
+ {false}{\nofrench@indent}
+ }
+ {\xpg@error{indentfirst~should~be~true~or~false. Is~"\l_tmpa_ttl"~ for~ language~ "#1"}}
+ }
+ {
+ \xpg@error{Could~ not~ retrieve~ key~ indentfirst~ for~ language~ "#1"}
+ \prop_show:N{\polyglossia@langsetup}
+ }
+}
+
+
+\cs_new:Nn{\polyglossia@lang@setpardirection:n}{
+ \prop_get:NxNTF \polyglossia@langsetup {#1/direction} \l_tmpa_tl
+ {
+ \polyglossia@setpardirection:n{\l_tmpa_tl}
+ }
+ {
+ \xpg@error{Could~ not~ retrieve~ key~ direction~ for~ language~ "#1"}
+ \prop_show:N{\polyglossia@langsetup}
+ }
+}
+
+
+\cs_new:Nn{\polyglossia@lang@settextdirection:nn}{
+ \prop_get:NxNTF \polyglossia@langsetup {#1/direction} \l_tmpa_tl
+ {
+ \polyglossia@settextdirection:n{\l_tmpa_tl}{#2}
+ }
+ {
+ \xpg@error{Could~ not~ retrieve~ key~ direction~ for~ language~ "#1"}
+ \prop_show:N{\polyglossia@langsetup}
+ }
+}
+
+\AtEndDocument{\prop_log:N{\polyglossia@langsetup}}
+\def\xpg@lastlanguage{0}%
+
+\providebool{xpg@hyphenation@disabled}%
+\boolfalse{xpg@hyphenation@disabled}
+
+\def\xpg@disablehyphenation{%
+ \ifx\@onlypreamble\@notprerr%
+ \xpg@@disablehyphenation%
+ \else%
+ % if this is used in the preamble, we have to postpone
+ % the execution until the main language has been set (#125).
+ \cs_gset_nopar:Nn \polyglossia@AtBeginDocument@hyphenation: {
+ \xpg@@disablehyphenation%
+ }%
+ \fi%
+}
+
+\def\xpg@@disablehyphenation{%
+ \ifbool{xpg@hyphenation@disabled}{}{%
+ \booltrue{xpg@hyphenation@disabled}%
+ \xdef\xpg@lastlanguage{\the\language}%
+ % We do not call \xpg@set@hyphenation@patterns here to avoid a warning message.
+ % "nohyphenation" is not listed in language.dat.lua.
+ \language=\l@nohyphenation%
+ }%
+}
+
+\def\xpg@enablehyphenation{%
+ \ifbool{xpg@hyphenation@disabled}{%
+ \boolfalse{xpg@hyphenation@disabled}%
+ \language=\csname xpg@lastlanguage\endcsname%
+ }{}%
+}
+
+\let\disablehyphenation\xpg@disablehyphenation
+\let\enablehyphenation\xpg@enablehyphenation
+
+%\def\xpg@fontsetup#1{\xpg@csifdef@warn{xpg@fontsetup@#1}}
+%\def\xpg@fontsetup@none#1{\csgdef{#1@font}{\ifcsdef{#1font}{\csname #1font\endcsname}{}}} %<-- simplistic
+%\def\xpg@fontsetup@custom#1{\csuse{#1@font}}
+
+\cs_new:Nn \polyglossia@lang@autosetupfont:n {
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#1/fontsetup}}{true}
+ {
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#1/lcscript}}{latin}%
+ {\xpg@fontsetup@latin{#1}}
+ {\xpg@fontsetup@nonlatin{#1}}
+ }
+ {
+ \xpg@info{Skipping~ automatic~ font~ setup~ for~ language~ #1}
+ }
+}
+
+
+% add fontfeature Language=#2 to langtag #1
+% do nothing if #1 or #2 is empty
+\cs_new:Nn \polyglossia@addfontfeature@language:nn {
+ \bool_if:nTF{\tl_if_empty_p:n{#1} || \tl_if_empty_p:n{#2}}
+ {
+ % maybe an error ?
+ \xpg@warning{Asking~ to~ add~ empty~ feature~to~ latin~ font~
+ (Language="#2"~ to~ langtag~ "#1")}
+ }
+ {
+ \str_if_eq:nnTF{#2}{Turkish}{
+ \fontspec_if_language:nTF {TRK}%
+ {
+ \addfontfeature{Language=Turkish}
+ }
+ {
+ \fontspec_if_language:nTF {TUR}%
+ {
+ \addfontfeature{Language=Turkish}
+ }{}
+ }
+ }{
+ \fontspec_if_language:nTF{#1}
+ {
+ \addfontfeature{Language=#2}
+ }
+ {}
+ }
+ }
+}
+\cs_generate_variant:Nn \polyglossia@addfontfeature@language:nn { on , no, oo , Vn, nV, VV , xn, nx, xx}
+
+% add fontfeature Script=#2 to scripttag #1
+% do nothing if #1 or #2 is empty
+\cs_new:Nn \polyglossia@addfontfeature@script:nn {
+ \bool_if:nTF{\tl_if_empty_p:n{#1} || \tl_if_empty_p:n{#2}}
+ {
+ % maybe an error ?
+ \xpg@warning{Asking~ to~ add~ empty~ feature~to~ latin~ font
+ (Script="#2"~ to~ scripttag~ "#1")}
+ }
+ {
+ \fontspec_if_script:nTF{#1}
+ {\addfontfeature{Script=#2}}
+ {\xpg@error{
+ The~ current~ latin ~ font~ \l_fontspec_family_tl\space does~ not~ contain~ the~"#2"~ script!\MessageBreak
+ Please~ define~\csname\tl_if_empty:nF{#2}{\str_lowercase:n#2}font\endcsname~
+ with~ \string\newfontfamily\space command
+ }
+ }
+ }
+}
+\cs_generate_variant:Nn \polyglossia@addfontfeature@script:nn { on , no, oo , Vn, nV, VV , xn, nx, xx}
+
+\def\xpg@fontsetup@latin#1{%
+ \begingroup
+ \csgdef{#1@font@rm}{%
+ \cs_if_exist_use:cF{#1font}{
+ \rmfamilylatin
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }
+ }
+ \csgdef{#1@font@sf}{%
+ \cs_if_exist_use:cF{#1fontsf}{
+ \sffamilylatin
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }%
+ }%
+ \csgdef{#1@font@tt}{%
+ \cs_if_exist_use:cF{#1fonttt}{
+ \ttfamilylatin
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }%
+ }%
+ \endgroup
+}
+
+\def\xpg@fontsetup@nonlatin#1{%
+ \begingroup
+ \csgdef{#1@font@rm}{%
+ \cs_if_exist_use:cF{#1font}
+ {
+ \providetoggle{#1@use@script@font}%
+ \str_if_eq:nnTF{\prop_item:Nn{\polyglossia@langsetup}{#1/script}}{\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ {\rmfamilylatin}%
+ {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia@langsetup}{#1/lcscript} font}
+ {
+ \toggletrue{#1@use@script@font}%
+ }
+ {
+ \rmfamilylatin
+ }
+ }
+ \iftoggle{#1@use@script@font}{}{%
+ \polyglossia@addfontfeature@script:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/scripttag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/script}}
+ }%
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }}%
+ \csgdef{#1@font@sf}{%
+ \cs_if_exist_use:cF{#1fontsf}%
+ {
+ \providetoggle{#1@use@script@fontsf}%
+ \str_if_eq:nnTF{\prop_item:Nn{\polyglossia@langsetup}{#1/script}}{\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ {\sffamilylatin}%
+ {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia@langsetup}{#1/lcscript} fontsf}
+ {
+ \toggletrue{#1@use@script@fontsf}%
+ }
+ {
+ \sffamilylatin
+ }
+ }
+ \iftoggle{#1@use@script@fontsf}{}{%
+ \polyglossia@addfontfeature@script:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/scripttag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/script}}
+ }%
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }}%
+ \csgdef{#1@font@tt}{%
+ \cs_if_exist_use:cF{#1fonttt}%
+ {
+ \providetoggle{#1@use@script@fonttt}%
+ \str_if_eq:nnTF{\prop_item:Nn{\polyglossia@langsetup}{#1/script}}{\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ {\ttfamilylatin}%
+ {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia@langsetup}{#1/lcscript} fonttt}
+ {
+ \toggletrue{#1@use@script@fonttt}%
+ }
+ {
+ \ttfamilylatin
+ }
+ }
+ \iftoggle{#1@use@script@fonttt}{}{%
+ \polyglossia@addfontfeature@script:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/scripttag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/script}}
+ }%
+ \polyglossia@addfontfeature@language:xx{\prop_item:Nn{\polyglossia@langsetup}{#1/langtag}}
+ {\prop_item:Nn{\polyglossia@langsetup}{#1/language}}
+ }}%
+ \endgroup
+}
+
+%%% END OF PolyglossiaSetup
+
+%% ensure localization of \markright and \markboth commands
+%%% THIS IS NOW DISABLED BY DEFAULT
+\cs_new_nopar:Nn {\polyglossia@local@marks:n} {}
+\cs_new_nopar:Nn {\polyglossia@enable@local@marks:}
+{
+ \xpg@info{Option:~ localmarks}%
+ \cs_gset_nopar:Nn \polyglossia@local@marks:n
+ {%
+ \def\xpg@tmp@lang{##1}%
+ \DeclareRobustCommand\markboth[2]{%
+ \begingroup
+ \let\label\relax \let\index\relax \let\glossary\relax
+ \unrestored@protected@xdef\@themark
+ {%
+ {\lowercase{\foreignlanguage{\xpg@tmp@lang}}{\protect\@@ensure@maindir{####1}}}%
+ {\lowercase{\foreignlanguage{\xpg@tmp@lang}}{\protect\@@ensure@maindir{####2}}}%
+ }%
+ \@temptokena \expandafter{\@themark}%
+ \mark{\the\@temptokena}%
+ \endgroup
+ \if@nobreak\ifvmode\nobreak\fi\fi%
+ }%
+ \DeclareRobustCommand\markright[1]{%
+ \begingroup
+ \let\label\relax \let\index\relax \let\glossary\relax
+ \expandafter\@markright\@themark
+ {\lowercase{\foreignlanguage{\xpg@tmp@lang}}{\protect\@@ensure@maindir{####1}}}%
+ \@temptokena \expandafter{\@themark}%
+ \mark{\the\@temptokena}%
+ \endgroup
+ \if@nobreak\ifvmode\nobreak\fi\fi%
+ }%
+% This part seems wrong (see #396 for explanation). Remove after a while.
+% \def\@markright####1####2####3{%
+% \@temptokena{\protect\@@ensure@maindir{####1}}%
+% \unrestored@protected@xdef\@themark{%
+% {\the\@temptokena}%
+% {\protect\@@ensure@maindir{####3}}%
+% }%
+% }%
+ }%
+}
+
+
+% Easy way out – Arthur, 2012-08-01
+\ifcsdef{newXeTeXintercharclass}{%
+% to reset the intercharclass of a character to "normal"
+\newXeTeXintercharclass\xpg@normalclass %TODO
+}{}
+
+\ifxetex
+%% when no patterns are available, we use \l@nohyphenation, assigned to 255
+%% (suggestion by Enrico Gregorio)
+ \@ifundefined{l@nohyphenation}{\chardef\l@nohyphenation=255 }{}
+\else\ifluatex
+ \@ifundefined{l@nohyphenation}{\chardef\l@nohyphenation=\directlua{
+ tex.sprint(polyglossia.newloader_loaded_languages.nohyphenation)}\relax
+ }{}
+\fi\fi
+
+%we call this macro when a gloss file is not found for a given language
+\def\xpg@nogloss#1{%
+ \xpg@warning{File~ gloss-#1.ldf~ does~ not~ exist!\MessageBreak
+ I~ will~ nevertheless~ try~ to~ use~ hyphenation~ patterns~ for~ #1.}%
+ \PolyglossiaSetup{#1}{hyphenmins,hyphennames={#1},fontsetup=true}%
+ % the above amounts to:
+ %\ifcsundef{l@#1}%
+ % {\expandafter\adddialect\csname l@#1\endcsname\l@nohyphenation\relax}%
+ % {\setlocalhyphenmins{#1}{2}{3}}%
+ %\csdef{#1@language}{\language=\csname l@#1\endcsname}%
+}
+
+\newcommand{\xpg@input}[1]{%
+ % Store catcode of @ before making at letter
+ \chardef\xpg@saved@at@catcode\catcode`\@
+ \makeatletter
+ \input{#1}%
+ % restore former @ catcode
+ \catcode`\@=\xpg@saved@at@catcode%
+}
+
+% try to load a language file
+\cs_new:Nn \polyglossia_load_lang_definition:nn {
+ \file_if_exist:nTF{gloss-#2.ldf}
+ {
+ % Temporarily force catcode of ~ to 13 since babelsh.def
+ % requires it. This is needed particularly with LaTeX3
+ % packages which force \ExplSyntaxOn (#425)
+ \protected\edef\xpg@restore@tilde@catcode{\catcode 126 = \the\catcode 126\relax}
+ \catcode 126 = 13
+ \xpg@input{gloss-#2.ldf}
+ \setkeys{#2}{#1}
+ % restore former ~ catcode
+ \xpg@restore@tilde@catcode
+ }
+ {
+ \xpg@nogloss{#2}
+ }
+}
+
+% load a master language from an alias file
+\newcommand*\xpg@load@master@language[1] {
+ \xpg@input{gloss-#1.ldf}
+ \ifcsundef{#1@loaded}%
+ {
+ \exp_args:Nx\polyglossia@define@language@cmd:n{#1}%
+ }{}
+ \polyglossia@register@language:nn{}{#1}%
+ \csgdef{#1@loaded}{}%
+}
+
+
+% define environment and command
+\cs_new:Nn \polyglossia@define@language@cmd:n {
+ \ifcsundef{#1@alias@lang}{%
+ \exp_args:Ne
+ \newenvironment {\prop_item:Nn{\polyglossia@langsetup}{#1/envname}} [1] []
+ {
+ \begin{otherlanguage}[##1]{#1}
+ }%
+ {
+ \end{otherlanguage}
+ }%
+ \exp_args:Nc \newcommand {text#1} [2][]
+ {%
+ \xpg@textlanguage[##1]{#1}{##2}%
+ }%
+ }{}
+}
+
+% provide way to define alias environment and command
+% \setlanguagealias[<options>]{<language>}{<alias>}
+\DeclareDocumentCommand \setlanguagealias {s O{} m m}
+{
+ % The starred version does not define commands and environments
+ \IfBooleanF {#1}
+ {
+ \ifcsundef{#4@alias@lang}{%
+ \exp_args:Ne
+ \newenvironment {#4}
+ {
+ \begin{otherlanguage}[#2]{#3}
+ }%
+ {
+ \end{otherlanguage}
+ }%
+ \exp_args:Nc \newcommand {text#4} [2][]
+ {%
+ \xpg@textlanguage[#2,##1]{#3}{##2}%
+ }%
+ }{%
+ \exp_args:Ne
+ \renewenvironment {#4}
+ {
+ \begin{otherlanguage}[#2]{#3}
+ }%
+ {
+ \end{otherlanguage}
+ }%
+ \exp_args:Nc \renewcommand {text#4} [2][]
+ {%
+ \xpg@textlanguage[#2,##1]{#3}{##2}%
+ }%
+ }%
+ }%
+ \csgdef{#4@alias@lang}{#3}%
+ \tl_if_blank:nF {#2} {\csgdef{#4@alias@opts}{#2}}%
+}
+
+\cs_new:Nn \polyglossia@register@language:nn {
+ % register polyglossia language name
+ \ifcsundef{#2@registered}{%
+ \global\edef\xpg@loaded{%
+ \ifx\xpg@loaded\@empty\else\xpg@loaded,\fi #2%
+ }%
+ }{}
+ \csgdef{#2@registered}{}%
+ \tl_if_blank:nF {#1}{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {#2} {#1}%
+ }%
+ % register babelname
+ \def\xpg@tmp@babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ \ifcsundef{\csname xpg@tmp@babelname\endcsname @bbl@registered}{%
+ \global\edef\xpg@bloaded{%
+ \ifx\xpg@bloaded\@empty\else\xpg@bloaded,\fi\xpg@tmp@babelname}%
+ }{}%
+ \csgdef{\csname xpg@tmp@babelname\endcsname @bbl@registered}{}%
+ % register BCP-47 ID
+ \def\xpg@tmp@bcpname{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ \ifcsundef{\csname xpg@tmp@bcpname\endcsname @bcp@registered}{%
+ \global\edef\xpg@bcp@loaded{%
+ \ifx\xpg@bcp@loaded\@empty\else\xpg@bcp@loaded,\fi\xpg@tmp@bcpname}%
+ }{}%
+ \csgdef{\csname xpg@tmp@bcpname\endcsname @bcp@registered}{}%
+}
+
+
+\newcommand{\setdefaultlanguage}[2][]{%
+ \ifcsundef{#2@loaded}%
+ {
+ \polyglossia_load_lang_definition:nn{#1}{#2}
+ % define environment and command (except for internal latex language)
+ \ifstrequal{#2}{latex}{}{%
+ \exp_args:Nx\polyglossia@define@language@cmd:n{#2}
+ }%
+ \csgdef{#2@loaded}{}%
+ }
+ {
+ \relax
+ }
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \polyglossia_load_lang_definition:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ \exp_args:Nxx \polyglossia@set@default@language:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ }{%
+ \polyglossia@set@default@language:nn {#1} {\csuse{#2@alias@lang}}%
+ }%
+ }{%
+ \polyglossia@set@default@language:nn {#1} {#2}%
+ }%
+}
+
+\cs_new:Nn \polyglossia@set@default@language:nn
+{
+ \gdef\xpg@main@language{#2}%
+ \tl_if_blank:nTF {#1}{\gdef\mainlanguagevariant{}}{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {#2} {#1}%
+ }%
+ \csgdef{#2@gvar}{\mainlanguagevariant}%
+ %% The following settings are for the default language and script
+ % this tells bidi.sty or luabidi.sty that the document is RTL
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/direction}}{RL}{%
+ \str_case_e:nnF{\c_sys_engine_str}{%
+ {luatex}{\setRTLmain}
+ {xetex}{\@RTLmaintrue\setnonlatin}
+ }{}%
+ }{}%
+ \cs_gset_nopar:Nn \polyglossia@AtBeginDocument@selectlanguage: {
+ \selectbackgroundlanguage{#2}
+ \selectlanguage[#1]{#2}%
+ }
+ \xpg@info{Default~ language~ is~ #2}%
+ \polyglossia@set@language@name[#1]{#2}%
+ \def\mainlanguagename{#2}
+ % Store babelname of main language (for external packages such as biblatex)
+ \prop_get:NxNT \polyglossia@langsetup {#2/babelname} \l_tmpa_tl
+ { \edef\mainbabelname{\l_tmpa_tl} }
+ % Store babelname of current language (for external packages such as biblatex)
+ \prop_get:NxNT \polyglossia@langsetup {#2/babelname} \l_tmpa_tl
+ { \edef\babelname{\l_tmpa_tl}%
+ \cs_gset_eq:cc{#2@gbabelname}{babelname}%
+ }
+ % Store BCP-47 id of main language
+ \prop_get:NxNT \polyglossia@langsetup {#2/bcp47} \l_tmpa_tl
+ { \csedef{mainbcp47id}{\l_tmpa_tl} }
+ % Store BCP-47 id of current language
+ \prop_get:NxNT \polyglossia@langsetup {#2/bcp47} \l_tmpa_tl
+ { \csedef{bcp47id}{\l_tmpa_tl}%
+ \cs_gset_eq:cc{#2@gbcp47id}{bcp47id}%
+ }
+ \ifluatex %
+ \directlua{polyglossia.set_default_language('\luatexluaescapestring{\string#2}')}%
+ \fi %
+}
+
+\let\setmainlanguage=\setdefaultlanguage
+
+% Returns the language ID of the current language
+% Currently supported: bcp-47
+\DeclareDocumentCommand \languageid {m}
+{
+ \str_case:nnTF {#1}
+ {
+ {bcp-47} { \csuse{bcp47id} }
+ {bcp47} { \csuse{bcp47id} }
+ }
+ {}
+ {
+ \xpg@error{Invalid~ \string\languageid\space argument:~ #1}
+ }
+}
+
+% Returns the language ID of the main language
+% Currently supported: bcp-47
+\DeclareDocumentCommand \mainlanguageid {m}
+{
+ \str_case:nnTF {#1}
+ {
+ {bcp-47} { \csuse{mainbcp47id} }
+ {bcp47} { \csuse{mainbcp47id} }
+ }
+ {}
+ {
+ \xpg@error{Invalid~ \string\mainlanguageid\space argument:~ #1}
+ }
+}
+
+\def\mainbabelname{}%
+\def\mainlanguagevariant{}%
+% Store main language variant for external packages
+\define@key{xpg@main@langvariant}{variant}{%
+ \gdef\mainlanguagevariant{#1}%
+}
+
+\def\babelname{}%
+\def\languagevariant{}%
+% Store current language variant for external packages
+\define@key{xpg@set@langvariant}{variant}{%
+ \def\languagevariant{#1}%
+}
+
+\newcommand*\polyglossia@set@language@name[2][]{
+ \def\languagename{#2}%
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gvar}{\def\languagevariant{}}{\def\languagevariant{\csuse{#2@gvar}}}
+ }{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {#2} {#1}%
+ }%
+}
+
+
+\newcommand*{\resetdefaultlanguage}[2][]{%
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \polyglossia@reset@default@language:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ }{%
+ polyglossia@reset@default@language:nn {#1} {\csuse{#2@alias@lang}}%
+ }%
+ }{%
+ polyglossia@reset@default@language:nn {#1} {#2}%
+ }%
+}
+
+\cs_new:Nn \polyglossia@reset@default@language:nn
+{
+ \polyglossia@error@iflangnotloaded:n{#2}
+ % disable globalnumbers of previously defined default language
+ \csuse{no\xpg@main@language @globalnumbers}
+ \csuse{noextras@\xpg@main@language}%
+ % This is a hook for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{noextras@bbl@\mainbabelname}%
+ \csuse{init@noextras@\xpg@main@language}%
+ \polyglossia@set@language@name[#1]{#2}%
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/direction}}{RL}{\@rlmaintrue\@rl@footnotetrue}{}%
+ \selectlanguage[#1]{#2}%
+ \selectbackgroundlanguage{#2}%
+ % Store babelname of current language (for external packages such as biblatex)
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbabelname}{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }{%
+ \edef\babelname{\csuse{#2@gbabelname}}%
+ }%
+ }{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }%
+ % Store BCP-47 id of current language
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbcp47id}{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }{%
+ \csedef{bcp47id}{\csuse{#2@gbcp47id}}%
+ }%
+ }{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }%
+}
+
+% This saves the normalfont for the latin script since we may change normalfont in other scripts
+\let\normalfontlatin=\normalfont%
+
+% Provide default fonts (as set with \setmainfont, \setsansfont and \setmonofont)
+% for Latin scripts and as a fallback for non-Latin scripts.
+\DeclareRobustCommand\xpg@defaultfont@rm{%
+ \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+ \fontfamily\rmdefault%
+ \selectfont%
+}
+\DeclareRobustCommand\xpg@defaultfont@sf{%
+ \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+ \fontfamily\sfdefault%
+ \selectfont%
+}
+\DeclareRobustCommand\xpg@defaultfont@tt{%
+ \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+ \fontfamily\ttdefault%
+ \selectfont%
+}
+
+\def\xpg@patch@fontfamilies{%
+ % This robustifies the redefinitions of \<xx>family (suggestion by Enrico Gregorio)
+ % e.g. to prevent expansion of the \familytype redefinition in auxiliary files
+ \csgappto{rmfamily~}{\def\familytype{rm}}
+ \csgappto{sffamily~}{\def\familytype{sf}}
+ \csgappto{ttfamily~}{\def\familytype{tt}}
+}
+
+% These switches activate the default fonts
+% Note that a simple \let\rmfamilylatin=\rmfamily
+% does not work reliably (see #24)
+\cs_gset_eq:cc{rmfamilylatin}{xpg@defaultfont@rm}%
+\cs_gset_eq:cc{sffamilylatin}{xpg@defaultfont@sf}%
+\cs_gset_eq:cc{ttfamilylatin}{xpg@defaultfont@tt}%
+
+\def\xpg@set@familydefault{%
+ % We need the \edef route here in order
+ % to detect both \renewcommand and \let
+ % changes.
+ \edef\tempa{\familydefault}%
+ \edef\tempb{\sfdefault}%
+ \ifcsequal{tempa}{tempb}%
+ {\def\familytype{sf}}
+ {\edef\tempb{\ttdefault}%
+ \ifcsequal{tempa}{tempb}%
+ {\def\familytype{tt}}
+ {\def\familytype{rm}}}
+ \xpg@patch@fontfamilies%
+ % This (re-)saves the normalfont for the latin script since we may
+ % change normalfont in other scripts
+ \let\normalfontlatin=\normalfont%
+ % And for all cases, we also reset \<xx>familylatin
+ \cs_gset_eq:cc{rmfamilylatin}{xpg@defaultfont@rm}%
+ \cs_gset_eq:cc{sffamilylatin}{xpg@defaultfont@sf}%
+ \cs_gset_eq:cc{ttfamilylatin}{xpg@defaultfont@tt}%
+}
+
+\def\resetfontlatin{%
+ \DeclareRobustCommand\rmfamily{\xpg@defaultfont@rm}%
+ \DeclareRobustCommand\sffamily{\xpg@defaultfont@sf}%
+ \DeclareRobustCommand\ttfamily{\xpg@defaultfont@tt}%
+ \xpg@patch@fontfamilies%
+ \global\let\normalfont=\normalfontlatin%
+}
+
+\def\selectfontfamilylatin{%
+ \def\tmp@tt{tt}\def\tmp@sf{sf}%
+ \ifx\familytype\tmp@tt%
+ \ttfamilylatin%
+ \else\ifx\familytype\tmp@sf%
+ \sffamilylatin%
+ \else\rmfamilylatin\fi\fi}
+
+\def\xpg@select@fontfamily#1{%
+ \def\tmp@tt{tt}\def\tmp@sf{sf}%
+ \ifx\familytype\tmp@tt
+ \csuse@warn{#1@font@tt}%
+ \else\ifx\familytype\tmp@sf
+ \csuse@warn{#1@font@sf}%
+ \else\csuse@warn{#1@font@rm}\fi\fi}
+
+\def\xpg@set@normalfont#1{%
+ \DeclareRobustCommand\rmfamily{\csuse{#1@font@rm}}%
+ \DeclareRobustCommand\sffamily{\csuse{#1@font@sf}}%
+ \DeclareRobustCommand\ttfamily{\csuse{#1@font@tt}}%
+ \gdef\normalfont{\protect\xpg@select@fontfamily{#1}%
+ \fontseries{\seriesdefault}\selectfont%
+ \fontshape{\shapedefault}\selectfont}%
+ \gdef\reset@font{\protect\normalfont}%
+}
+
+\let\@@fterindentfalse\@afterindentfalse
+\def\french@indent{%
+ \let\@afterindentfalse\@afterindenttrue
+ \@afterindenttrue%
+}
+\def\nofrench@indent{%
+ \let\@afterindentfalse\@@fterindentfalse
+ \@afterindentfalse%
+}
+
+\newcommand*{\selectbackgroundlanguage}[1]{%
+ \ifcsdef{#1@alias@lang}{%
+ \polyglossia@select@background@language:n {\csuse{#1@alias@lang}}%
+ }{%
+ \polyglossia@select@background@language:n {#1}%
+ }%
+}
+
+\cs_new:Nn \polyglossia@select@background@language:n
+{
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#1/lcscript}}{latin}
+ {}
+ {\xpg@set@normalfont{#1}}%
+ \csuse{#1@globalnumbers}%
+}
+
+\newcommand{\setotherlanguage}[2][]{%
+ \ifcsundef{#2@loaded}
+ {
+ \polyglossia_load_lang_definition:nn{#1}{#2}
+ % define environment and command
+ \exp_args:Nx\polyglossia@define@language@cmd:n{#2}
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \polyglossia_load_lang_definition:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ \exp_args:Nxx \polyglossia@set@other@language:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ }{%
+ \polyglossia@set@other@language:nn {#1} {\csuse{#2@alias@lang}}%
+ }%
+ }{%
+ \polyglossia@set@other@language:nn {#1} {#2}%
+ }%
+ \csgdef{#2@loaded}{}%
+ }
+ {}
+}
+
+\cs_new:Nn \polyglossia@set@other@language:nn
+{
+ \polyglossia@register@language:nn{#1}{#2}%
+ % If a variant is set, store it.
+ \gdef\otherlanguagevariant{}
+ \tl_if_blank:nTF {#1}{}{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {#2} {#1}%
+ }%
+ \csgdef{#2@gvar}{\otherlanguagevariant}%
+ \prop_get:NxNT \polyglossia@langsetup {#2/babelname} \l_tmpa_tl
+ { \xdef\otherlanguagebabelname{\l_tmpa_tl} }
+ \cs_gset_eq:cc{#2@gbabelname}{otherlanguagebabelname}%
+}
+
+% Store main language variant for external packages
+\define@key{xpg@other@langvariant}{variant}{%
+ \gdef\otherlanguagevariant{#1}%
+}
+
+\newcommand\setotherlanguages[1]{%
+ \def\do##1{\setotherlanguage{##1}}%
+ \exp_args:Nx\docsvlist{#1}}%
+
+\def\common@language{% FIXME is this really needed???
+ \ifbool{xpg@hyphenation@disabled}{%
+ \xdef\xpg@lastlanguage{\z@}%
+ }{%
+ \language=\z@
+ }%
+ \lefthyphenmin=\tw@
+ \righthyphenmin=\thr@@}
+
+\def\xpg@initial@setup{%
+ \common@language%
+}
+
+
+% Alias to \text<lang>, but more suitable
+% for specific (esp. tag-based) aliases
+% where \text<alias> would cause clashes
+% (e.g., \textit)
+\newcommand\textlang[3][]{%
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \xpg@textlanguage[\csuse{#2@alias@opts},#1]{\csuse{#2@alias@lang}}{#3}%
+ }{%
+ \xpg@textlanguage[#1]{\csuse{#2@alias@lang}}{#3}%
+ }%
+ }{%
+ \xpg@textlanguage[#1]{#2}{#3}%
+ }%
+}%
+
+% Alias to {<lang>}, but more suitable
+% for specific (esp. tag-based) aliases
+% where {<alias>} would cause clashes
+% (e.g., \fi)
+\newenvironment{lang}[2][]{%
+ \begin{otherlanguage}[#1]{#2}%
+}{%
+ \end{otherlanguage}
+}%
+
+\providecommand{\foreignlanguage}{}
+
+% wrapper for foreignlanguage and otherlanguage*
+\newcommand*\polyglossia@setforeignlanguage[2][]{
+ \select@@language[#1]{#2}
+ \polyglossia@register@language:nn{#1}{#2}%
+ % Store babelname of current language (for external packages such as biblatex)
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbabelname}{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }{%
+ \edef\babelname{\csuse{#2@gbabelname}}%
+ }%
+ }{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }%
+ % Store BCP-47 id of current language
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbcp47id}{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }{%
+ \csedef{bcp47id}{\csuse{#2@gbcp47id}}%
+ }%
+ }{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }%
+}
+
+% joint code of \foreignlanguage, otherlanguage*
+% and \text<lang>
+\newcommand{\xpg@otherlanguage}[2][]
+{%
+ \polyglossia@error@iflangnotloaded:n{#2}
+ \exp_args:Nne \setkeys{#2}{#1}%
+ \polyglossia@setforeignlanguage[#1]{#2}
+ % Hook for external packages such as biblatex
+ \polyglossia@language@switched%
+ % buggy restoration heure
+ \csuse{inlineextras@#2}%
+ % This is a hook for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{inlineextras@bbl@\babelname}%
+}
+
+\renewcommand{\foreignlanguage}[3][]
+{%
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \polyglossia@foreignlanguage:nnn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}} {#3}%
+ }{%
+ \polyglossia@foreignlanguage:nnn {#1} {\csuse{#2@alias@lang}} {#3}%
+ }%
+ }{%
+ \polyglossia@foreignlanguage:nnn {#1} {#2} {#3}%
+ }%
+}
+
+\cs_new:Nn \polyglossia@foreignlanguage:nnn
+{
+ \polyglossia@error@iflangnotloaded:n{#2}
+ \bgroup
+ \xpg@otherlanguage[#1]{#2}%
+ \polyglossia@lang@settextdirection:nn{#2}{#3}%
+ \egroup
+}
+
+% otherlanguage* is the environment equivalent of \foreignlanguage
+\expandafter\providecommand\csname otherlanguage*\endcsname{}
+
+\renewenvironment{otherlanguage*}[2][]
+{%
+ \ifcsdef{#2@alias@lang}{%
+ \ifcsdef{#2@alias@opts}{%
+ \exp_args:Nxx \polyglossia@otherlanguage:nn {\csuse{#2@alias@opts},#1} {\csuse{#2@alias@lang}}%
+ }{%
+ \polyglossia@otherlanguage:nn {#1} {\csuse{#2@alias@lang}}%
+ }%
+ }{%
+ \polyglossia@otherlanguage:nn {#1} {#2}%
+ }%
+}
+{\egroup}
+
+\cs_new:Nn \polyglossia@otherlanguage:nn
+{
+ \xpg@otherlanguage[#1]{#2}%
+ \polyglossia@lang@settextdirection:nn{#2}\bgroup%
+}
+
+% use by \text<lang> and \textlang. Equivalent to \foreignlanguage,
+% except that dates are localized.
+\newcommand\xpg@textlanguage[3][]{%
+ \polyglossia@error@iflangnotloaded:n{#2}
+ \bgroup
+ \xpg@otherlanguage[#1]{#2}%
+ \csuse{date#2}%
+ % This is a hook for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{date@bbl@\babelname}%
+ \polyglossia@lang@settextdirection:nn{#2}{#3}%
+ \egroup
+ % Reset the language's/script's font families
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/lcscript}}{latin}{}{\resetfontlatin}%
+}
+
+
+% Define language-specific hyphenation exceptions
+\newcommand\pghyphenation[3][]{
+ \bgroup
+ \polyglossia@error@iflangnotloaded:n{#2}
+ \setkeys{#2}{#1}%
+ \select@@language[#1]{#2}%
+ \hyphenation{#3}%
+ \egroup
+}
+
+
+% Hook that other package authors can use
+% (for instance biblatex):
+\newcommand*{\xpg@hook@setlanguage}{}
+
+\def\xpg@pop@language@i#1#2{%
+ \xpg@set@language@aux[#1]{#2}%
+ \xpg@hook@setlanguage
+ \let\emp@langname\@undefined}
+
+\DeclareDocumentCommand \selectlanguage {s O{} m}
+{%
+ \ifcsdef{#3@alias@lang}{%
+ \ifcsdef{#3@alias@opts}{%
+ \exp_args:Nxx \polyglossia@select@language:nnn {#1} {\csuse{#3@alias@opts},#2} {\csuse{#3@alias@lang}}%
+ }{%
+ \polyglossia@select@language:nnn {#1} {#2} {\csuse{#3@alias@lang}}%
+ }%
+ }{%
+ \polyglossia@error@iflangnotloaded:n{#3}%
+ \polyglossia@select@language:nnn {#1} {#2} {#3}%
+ }
+}
+
+\cs_new:Nn \polyglossia@select@language:nnn
+{
+ \IfBooleanF {#1}
+ {
+ \cs_set_nopar:Npx \xpg@pop@language { \exp_not:N \xpg@pop@language@i {#2} {#3} }
+ \group_insert_after:N \xpg@pop@language
+ }
+ \tl_if_blank:nTF {#2}{}{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {#3} {#2}%
+ }%
+ % The starred variant does not write to the aux
+ \IfBooleanTF#1{%
+ \xpg@set@language@nonaux[#2]{#3}%
+ }{%
+ \xpg@set@language@aux[#2]{#3}%
+ }%
+ \ifluatex%
+ \directlua{polyglossia.select_language('\luatexluaescapestring{\string#3}',
+ \the\csname l@#3\endcsname)}%
+ \fi%
+ \polyglossia@register@language:nn{#2}{#3}%
+}
+
+
+\cs_new:Nn \polyglossia@set@lang@options:nn
+{
+ % If the optional argument sets a value for the key “variant”, copy it to xpg@langvariant
+ \clist_map_inline:nn { #2 } {%
+ \xpg@parsevariantkeyvalue##1=@xpg@langvariant:#1\relax
+ }%
+ \exp_args:Nne \setkeys{#1}{#2}%
+}
+
+% Initialize default language options, so that
+% \iflanguageoption has the info it needs also
+% for default settings
+\newcommand*\xpg@initialize@gloss@options[2]{%
+ \polyglossia@set@lang@options:nn {#1} {#2}%
+}
+
+% Record synonymous keyvals such as variant=us and variant=american
+% Syntax: \xpg@set@alias@values{<lang>}{<key>}{<val>}{<alias vals, comma-separated>}
+\newcommand*\xpg@set@alias@values[4]{%
+ \prop_if_exist:cF { xpg@alias@keyvals@#1@#3 }
+ { \prop_new:c {xpg@alias@keyvals@#1@#3} }
+ \prop_put:cnn { xpg@alias@keyvals@#1@#3 }
+ {#2}{#4}
+ \prop_put:cnn { xpg@alias@keyvals@#1@#4 }
+ {#2}{#3}
+}
+
+% Patch xkeyval to record default values of keys
+\pretocmd{\XKV@define@default}{%
+ \csgdef{xpg@default@opt@\XKV@header #1}{#2}%
+}{}{\xpg@warning{Patching xkeyval failed!}}
+
+% Helper to get and register option keyvals
+\def\xpg@parsevariantkeyvalue#1=#2@#3:#4\relax{%
+ \def\@tmpa{#1}
+ \def\@tmpb{variant}
+ % variant values are stored in specific macros
+ % (\xpg@main@langvariant, \xpg@other@langvariant
+ % and \xpg@set@langvariant)
+ \ifx\@tmpa\@tmpb\setkeys{#3}{#1=#2}\fi
+ \tl_if_empty:nTF{#2}
+ {
+ \ifcsdef{xpg@default@opt@KV@#4@#1}%
+ {\xpg@store@opt@keyval#1:\csuse{xpg@default@opt@KV@#4@#1}=:#4\relax}%
+ {}%
+ }
+ { \xpg@store@opt@keyval#1:#2:#4\relax }
+}%
+
+% Store option keys and values
+% This strips trailing '=' from values.
+\def\xpg@store@opt@keyval#1:#2=:#3\relax{%
+ \prop_if_exist:cF { xpg@current@options@#3 }
+ { \prop_new:c {xpg@current@options@#3} }
+ \prop_put:cnn { xpg@current@options@#3 }
+ {#1}{#2}
+}
+
+
+\prg_set_conditional:Npnn \polyglossia@check@option@value:NNN #1#2#3 { p , T , F , TF }
+{
+ \prop_get:cnNTF {xpg@current@options@#1} {#2} \l_tmpa_tl
+ {
+ \exp_args:Nee \str_if_eq:NNTF{\l_tmpa_tl}{#3}
+ {\prg_return_true:}
+ {
+ \prop_get:cnNTF {xpg@alias@keyvals@#1@#3} {#2} \l_tmpb_tl
+ {
+ \exp_args:Nne \clist_set:Nn{\l_tmpa_clist}{\l_tmpb_tl}
+ \providetoggle{xpgvalfound}
+ \togglefalse{xpgvalfound}
+ \clist_map_inline:Nn \l_tmpa_clist {
+ \exp_args:Nee \str_if_eq:NNT{##1}{\l_tmpa_tl}
+ { \toggletrue{xpgvalfound} }
+ }
+ \iftoggle{xpgvalfound}{\prg_return_true:}{\prg_return_false:}
+ }
+ {
+ \prg_return_false:
+ }
+ }
+ }
+ {
+ \prg_return_false:
+ }
+}
+
+% Test if option value is set
+\newcommand*\iflanguageoption[5]{%
+ \polyglossia@check@option@value:NNNTF{#1}{#2}{#3}{#4}{#5}%
+}
+
+
+% Append any variant to csv list of variants
+\define@key{xpg@langvariant}{variant}{%
+ \edef\xpg@vloaded{#1\ifx\xpg@vloaded\@empty\else,\xpg@vloaded\fi}%
+}
+
+\prg_set_conditional:Npnn \polyglossia@check@if@lang@loaded:N #1 { p , T , F , TF }{
+ \cs_if_exist:cTF{#1}{
+ \prg_return_true:
+ }{
+ \prg_return_false:
+ }
+}
+
+% Test if language is loaded
+\newcommand*\iflanguageloaded[3]{%
+ \polyglossia@check@if@lang@loaded:NTF{#1@loaded}{#2}{#3}%
+}
+
+% Same for babellanguage is loaded
+\newcommand*\ifbabellanguageloaded[3]{%
+ \polyglossia@check@if@lang@loaded:NTF{#1@bbl@loaded}{#2}{#3}%
+}
+
+% Same for languageid
+\DeclareDocumentCommand \iflanguageidloaded {mmmm}
+{
+ \str_case:nnTF {#1}
+ {
+ {bcp-47} { \polyglossia@check@if@lang@loaded:NTF{#2@bcp@loaded}{#3}{#4} }
+ {bcp47} { \polyglossia@check@if@lang@loaded:NTF{#2@bcp@loaded}{#3}{#4} }
+ }
+ {}
+ {
+ \xpg@error{Invalid~ \string\iflanguageidloaded\space argument:~ #1}
+ }
+}
+
+% Check if the current font has a given glyph
+\prg_set_conditional:Npnn \polyglossia@check@if@char@available:N #1 { p , T , F , TF }
+{
+ \str_case_e:nnF{\c_sys_engine_str}{
+ {luatex}{
+ \int_compare:nNnTF { \directlua{polyglossia.check_char(0x#1)} } > { 0 }
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ {xetex}{
+ \int_compare:nNnTF { \the\XeTeXcharglyph"#1 } > { 0 }
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+ }
+ {
+ \xpg@warning{You’re running a TeX engine that is not LuaTeX or XeTeX.\MessageBreak
+ That is almost guaranteed to cause problems.}
+ }
+}
+
+% Test if a char (by char code) is available in the current font
+\newcommand*\xpg@if@char@available[3]{%
+ \polyglossia@check@if@char@available:NTF{#1}{#2}{#3}%
+}
+
+\newcommand*\charifavailable[2]{%
+ \xpg@if@char@available{#1}{\char"#1}{#2}%
+}
+
+
+\newcommand*{\xpg@set@language@nonaux}[2][]{%
+ \@select@language[#1]{#2}%
+}
+
+
+\newcommand*{\xpg@set@language@aux}[2][]{%
+ % Store babelname of current language (for external packages such as biblatex)
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbabelname}{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }{%
+ \edef\babelname{\csuse{#2@gbabelname}}%
+ }%
+ }{%
+ \edef\babelname{\prop_item:Nn{\polyglossia@langsetup}{#2/babelname}}%
+ }%
+ % Store BCP-47 id of current language
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbcp47id}{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }{%
+ \csedef{bcp47id}{\csuse{#2@gbcp47id}}%
+ }%
+ }{%
+ \csedef{bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }%
+ \@select@language[#1]{#2}%
+ % Write to the aux
+ \if@filesw%
+ \ifx#1\\\\%
+ \protected@write\@auxout{}{\protect\selectlanguage*{#2}}%
+ \addtocontents{toc}{\protect\selectlanguage*{#2}}%
+ \addtocontents{lof}{\protect\selectlanguage*{#2}}%
+ \addtocontents{lot}{\protect\selectlanguage*{#2}}%
+ \else
+ \protected@write\@auxout{}{\protect\selectlanguage*[#1]{#2}}%
+ \addtocontents{toc}{\protect\selectlanguage*[#1]{#2}}%
+ \addtocontents{lof}{\protect\selectlanguage*[#1]{#2}}%
+ \addtocontents{lot}{\protect\selectlanguage*[#1]{#2}}%
+ \fi
+ \fi
+}
+
+% The bidi package swaps the output stream within RTL tables
+% (to get the column order right). This also swaps group
+% delimiters inserted to the aux files via otherlanguage (see #354).
+% We therefore patch bidi and insert a bool that tells us
+% whether we are in such a table.
+\newbool{xpg@inbiditable}
+\AtBeginDocument{%
+ \@ifpackageloaded{bidi}{%
+ \patchcmd{\@tabular}%
+ {\if@RTLtab}%
+ {\if@RTLtab\booltrue{xpg@inbiditable}}%
+ {}% success
+ {\xpg@warning{Patching bidi table failed!}}%
+ }{}%
+}
+
+% Open a group in the aux file. This is to keep
+% nested language options local (see #320).
+% In bidi tables, the opening/closing needs to be swapped (see #354)
+\newcommand*{\xpg@set@group@aux}{%
+ \if@filesw%
+ \ifbool{xpg@inbiditable}{%
+ \protected@write\@auxout{}{\egroup}%
+ \addtocontents{toc}{\egroup}%
+ \addtocontents{lof}{\egroup}%
+ \addtocontents{lot}{\egroup}%
+ }{%
+ \protected@write\@auxout{}{\bgroup}%
+ \addtocontents{toc}{\bgroup}%
+ \addtocontents{lof}{\bgroup}%
+ \addtocontents{lot}{\bgroup}%
+ }%
+ \fi
+}
+
+% Close the group in the aux file.
+% In bidi RTL tables, the opening/closing needs
+% to be swapped (see #354).
+\newcommand*{\xpg@unset@group@aux}{%
+ \if@filesw%
+ \ifbool{xpg@inbiditable}{%
+ \protected@write\@auxout{}{\bgroup}%
+ \addtocontents{toc}{\bgroup}%
+ \addtocontents{lof}{\bgroup}%
+ \addtocontents{lot}{\bgroup}%
+ }{%
+ \protected@write\@auxout{}{\egroup}%
+ \addtocontents{toc}{\egroup}%
+ \addtocontents{lof}{\egroup}%
+ \addtocontents{lot}{\egroup}%
+ }%
+ \fi
+}
+
+\prg_set_conditional:Npnn \polyglossia@check@ifdefined:N #1 { p , T , F , TF }{
+ \cs_if_exist:cTF {l@#1}
+ {
+ \cs_if_eq:cNTF {l@#1} \l@nohyphenation
+ {
+ \prg_return_false:
+ }
+ {
+ % it's possible that sometimes \csname l@#1\endcsname becomes \relax
+ \cs_if_eq:cNTF {l@#1} \relax
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+ }
+ {
+ \prg_return_false:
+ }
+}
+
+\def\polyglossia@luatex@load@lang#1{%
+ % if \l@#1 is not properly defined, call lua function newloader(#1),
+ % and assign the returned number to \l@#1
+ \polyglossia@check@ifdefined:NF {#1}
+ {
+ \expandafter\chardef\csname l@#1\endcsname=
+ \directlua{ tex.sprint(polyglossia.newloader'#1') }\relax
+ }
+}
+
+% This check is also used by biblatex, so don't
+% rename silently.
+\newcommand\xpg@ifdefined[3]{%
+ % With luatex, we first need to define \l@#1.
+ \ifluatex
+ \polyglossia@luatex@load@lang{#1}%
+ \fi
+ \polyglossia@check@ifdefined:NTF{#1}{#2}{#3}%
+}%
+
+% Set \bbl@hyphendata@\the\language, which is (lua)babel's
+% hyphenation pattern hook
+% FIXME Clarifiy why/when this is needed.
+\newcommand*\xpg@set@bbl@hyphendata[1]{%
+ \ifluatex%
+ \ifcsdef{bbl@hyphendata@#1}{}{%
+ \global\@namedef{bbl@hyphendata@\the\language}{}%
+ }%
+ \fi%
+}
+
+% Set hyphenation patterns for a given language. This does the right
+% thing both for XeTeX and LuaTeX
+\newcommand*\xpg@set@hyphenation@patterns[1]{%
+ \ifluatex
+ \polyglossia@luatex@load@lang{#1}%
+ \language=\csname l@#1\endcsname
+ \else
+ \ifxetex
+ \language=\csname l@#1\endcsname
+ \else
+ \xpg@warning{You’re~running~a~TeX~engine~that~is~not~LuaTeX~or~XeTeX.\MessageBreak
+ That~is~almost~guaranteed~to~cause~problems.}%
+ \fi
+ \fi
+}
+
+
+\newcommand*\@select@language[2][]{
+ % hook for compatibility with biblatex
+ \select@language{#2}
+ \xpg@set@bbl@hyphendata{\the\language}
+ \xpg@initial@setup%
+ \select@@language[#1]{#2}%
+ % Hook for external packages such as biblatex
+ \polyglossia@language@switched%
+ \polyglossia@lang@setpardirection:n{#2}%
+ \csuse{captions#2}%
+ \csuse{date#2}%
+ % These are hooks for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{captions@bbl@\babelname}%
+ \cs_if_exist_use:c{date@bbl@\babelname}%
+ \polyglossia@local@marks:n{#2}%
+ \csuse{init@extras@#2}%
+ \polyglossia@lang@indentfirst:n{#2}%
+ \csuse{blockextras@#2}%
+ % This is a hook for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{blockextras@bbl@\babelname}%
+ }
+
+% hook for compatibility with biblatex
+% (probably no longer used due to the
+% more general hook that follows, but
+% we keep it for backwards comp.)
+\def\select@language#1{}
+
+% Hook for external packages such as biblatex
+\def\polyglossia@language@switched{}
+
+\def\noextrascurrent#1{%
+ \csuse{noextras@#1}%
+ % This is a hook for external packages which want to access variants
+ % via babelname (such as biblatex)
+ \cs_if_exist_use:c{noextras@bbl@\babelname}
+}
+
+% Common code for `\select@language' and `\foreignlanguage'.
+\newcommand{\select@@language}[2][]{%
+ % disable the extras and number settings of the previous language
+ \ifcsundef{languagename}{}{%
+ \noextrascurrent{\languagename}%
+ \csuse{no\languagename @numbers}%
+ \ifxetex
+ \str_if_eq:eeTF{\exp_args:Nne\prop_item:Nn{\polyglossia@langsetup}{\languagename/direction}}{RL}%
+ {%
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/direction}}{RL}%
+ {}% RTL -> RTL
+ {\setlatin}% RTL -> LTR
+ }{%
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/direction}}{RL}%
+ {\setnonlatin}% LTR -> RTL
+ {}% LTR -> LTR
+ }%
+ \fi
+ }%
+ \polyglossia@set@language@name[#1]{#2}%
+ % Set the language's/script's font families
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#2/lcscript}}{latin}{\resetfontlatin}{\xpg@set@normalfont{#2}}%
+ \xpg@select@fontfamily{#2}%
+ \csuse@warn{#2@language}%
+ \csuse{#2@numbers}%
+ \use@localhyphenmins[#1]{#2}%
+ \polyglossia@lang@frenchspacing:n{#2}
+}
+
+
+\let\xpg@pop@language\relax
+
+\provideenvironment{otherlanguage}{}{}
+
+\newbool{xpg@noset@groups}
+\renewenvironment{otherlanguage}[2][]
+{%
+ % We usually embrace the switch in groups to keep the changes local.
+ % We cannot do this if an LTR environmet starts in an RTL paragraph,
+ % as bidi interferes here badly with its directionality smartness.
+ \ifxetex
+ \str_if_eq:eeT{\exp_args:Nne\prop_item:Nn{\polyglossia@langsetup}{\languagename/direction}}{RL}%
+ {%
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#1/direction}}{RL}%
+ {}% RTL -> RTL
+ {\ifvmode\else\booltrue{xpg@noset@groups}\fi}% RTL -> LTR
+ }%
+ \fi%
+ \ifbool{xpg@noset@groups}{}{\xpg@set@group@aux}%
+ \selectlanguage[#1]{#2}%
+}
+{\ifbool{xpg@noset@groups}{}{\xpg@unset@group@aux}}
+
+\newcommand{\setlocalhyphenmins}[3]{%
+ \xpg@ifdefined{#1}{%
+ \expandafter\ifx\csname l@#1\endcsname\l@nohyphenation%
+ \xpg@warning{\string\setlocalhyphenmin\space~ useless~ for~ unhyphenated~ language~ #1}%
+ \else
+ \providehyphenmins{#1}{#2#3}%
+ \fi
+ }{%
+ \xpg@warning{\string\setlocalhyphenmin\space~ useless~ for~ unknown~ language~ #1}%
+ }%
+}%
+
+% \setlanghyphenmins[options]{lang}{l}{r}
+\newcommand*\setlanghyphenmins[4][]{%
+ % Check for real language name and options
+ \edef\xpg@tmp@lang{#2}%
+ \edef\xpg@tmp@opts{#1}%
+ \ifcsdef{#2@alias@lang}{%
+ \edef\xpg@tmp@lang{\csuse{#2@alias@lang}}%
+ \ifcsdef{#2@alias@opts}{%
+ \edef\xpg@tmp@opts{\csuse{#2@alias@opts},#1}%
+ }{}%
+ }{}%
+ \bgroup
+ \polyglossia@error@iflangnotloaded:n{\xpg@tmp@lang}
+ \exp_args:Nne \setkeys{\xpg@tmp@lang}{\xpg@tmp@opts}%
+ % Store BCP-47 id of language
+ \tl_if_blank:nTF {\xpg@tmp@opts}{%
+ \ifcsundef{\csname xpg@tmp@lang\endcsname @gbcp47id}{%
+ \csedef{tmp@bcp47id}{\exp_args:Nne\prop_item:Nn{\polyglossia@langsetup}{\xpg@tmp@lang /bcp47}}%
+ }{%
+ \csedef{tmp@bcp47id}{\csuse{#2@gbcp47id}}%
+ }%
+ }{%
+ \csedef{tmp@bcp47id}{\exp_args:Nne \prop_item:Nn{\polyglossia@langsetup}{\xpg@tmp@lang /bcp47}}%
+ }%
+ \xpg@warning{id: \csuse{tmp@bcp47id}}%
+ \csgdef{\csname tmp@bcp47id\endcsname @hyphenmins}{{#3}{#4}}%
+ \egroup
+}
+
+% \use@localhypenmins[options]{lang}
+\newcommand*\use@localhyphenmins[2][]{%
+ \bgroup
+ \polyglossia@error@iflangnotloaded:n{#2}
+ \setkeys{#2}{#1}%
+ % Store BCP-47 id of language
+ \tl_if_blank:nTF {#1}{%
+ \ifcsundef{#2@gbcp47id}{%
+ \csxdef{tmp@bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }{%
+ \csxdef{tmp@bcp47id}{\csuse{#2@gbcp47id}}%
+ }%
+ }{%
+ \csxdef{tmp@bcp47id}{\prop_item:Nn{\polyglossia@langsetup}{#2/bcp47}}%
+ }%
+ \egroup
+ \ifcsundef{\csname tmp@bcp47id\endcsname @hyphenmins}{%
+ \ifcsundef{#2hyphenmins}{}%
+ {%
+ \expandafter\expandafter\expandafter\set@hyphenmins\csname #2hyphenmins\endcsname\relax%
+ }
+ }{%
+ \edef\tmpa{\csuse{\csname tmp@bcp47id\endcsname @hyphenmins}}%
+ \expandafter\expandafter\expandafter\set@hyphenmins\tmpa\relax%
+ }
+ \ifluatex
+ % Set \totalhyphenmin if specified
+ \prop_get:NxNTF \polyglossia@langsetup {#2/totalhyphenmin} \l_tmpa_tl
+ {
+ \xpg@warning{totalhyphenmin: '\l_tmpa_tl'}
+ \expandafter\hyphenationmin \l_tmpa_tl%
+ }%
+ {}%
+ \fi
+}
+
+% Babel previously compiled in hyphenrules into the kernel (via hyphen.cfg)
+% but this is no longer the case. In any case, we roll our own one now
+% and possibly overwrite babel's.
+\provideenvironment{hyphenrules}{}{}
+
+% As opposed to the one inherited from switch.def/babel, our environment
+% supports language options and aliases.
+\renewenvironment{hyphenrules}[2][]
+{%
+ % We usually embrace the switch in groups to keep the changes local.
+ % We cannot do this if an LTR environmet starts in an RTL paragraph,
+ % as bidi interferes here badly with its directionality smartness.
+ \ifxetex
+ \str_if_eq:eeT{\exp_args:Nne\prop_item:Nn{\polyglossia@langsetup}{\languagename/direction}}{RL}%
+ {%
+ \str_if_eq:eeTF{\prop_item:Nn{\polyglossia@langsetup}{#1/direction}}{RL}%
+ {}% RTL -> RTL
+ {\ifvmode\else\booltrue{xpg@noset@groups}\fi}% RTL -> LTR
+ }%
+ \fi%
+ \ifbool{xpg@noset@groups}{}{\xpg@set@group@aux}%
+ % Check for real language name and options
+ \edef\xpg@tmp@lang{#2}%
+ \edef\xpg@tmp@opts{#1}%
+ \ifcsdef{#2@alias@lang}{%
+ \edef\xpg@tmp@lang{\csuse{#2@alias@lang}}%
+ \ifcsdef{#2@alias@opts}{%
+ \edef\xpg@tmp@opts{\csuse{#2@alias@opts},#1}%
+ }{}%
+ }{}%
+ \tl_if_blank:nF {\xpg@tmp@opts}{%
+ % Register the language options
+ \polyglossia@set@lang@options:nn {\xpg@tmp@lang} {\xpg@tmp@opts}%
+ }%
+ % Now switch patterns
+ \csuse@warn{\csuse{xpg@tmp@lang}@language}%
+ % And activate hyphenmins
+ \use@localhyphenmins[\xpg@tmp@opts]{\xpg@tmp@lang}%
+}
+{\ifbool{xpg@noset@groups}{}{\xpg@unset@group@aux}}
+
+\AtEndPreamble{%
+ \@ifpackageloaded{bidi}{%
+ \providecommand*{\aemph}[1]{$\overline{\hboxR{#1}}$}%
+ }{}%
+ \@ifpackageloaded{luabidi}{%
+ \providecommand*{\aemph}[1]{$\overline{\hbox{\RL{#1}}}$}%
+ }{}%
+}
+
+
+% keys for main package
+\keys_define:nn { polyglossia } {
+ verbose
+ .bool_set:N = \l_polyglossia_verbose_bool,
+ verbose
+ .default:n = true,
+ % compatibility
+ quiet
+ .meta:n = { verbose = false },
+
+ localmarks
+ .bool_set:N = \l_polyglossia_localmarks_bool,
+ localmarks
+ .default:n = true,
+ % compatibility
+ nolocalmarks
+ .meta:n = { localmarks = false },
+
+ babelshorthands
+ .bool_set:N = \l_polyglossia_babelshorthands_bool,
+ babelshorthands
+ .default:n = true,
+
+ luatexrenderer
+ .cs_set:Np = \l_polyglossia_luatex_renderer,
+ luatexrenderer
+ .value_required:n = true,
+}
+
+\keys_set:nn { polyglossia } {
+ localmarks = false,
+ verbose = true,
+ babelshorthands = false,
+ luatexrenderer = Harfbuzz
+}
+
+% load by default latex
+\setmainlanguage{latex}
+% then process key in order to overwrite
+\ProcessKeysOptions{polyglossia}
+
+% Set the LuaTeX renderer. As opposed to fontspec, we use Harfbuzz by default.
+% This can be changed via the luatexrenderer package option.
+\ifluatex
+ \exp_args:Nee \str_if_eq:nnF{\l_polyglossia_luatex_renderer}{none}
+ {
+ \xpg@info{Setting~ LuaTeX~ font~ renderer~ to~ \l_polyglossia_luatex_renderer}
+ \exp_args:Nee \defaultfontfeatures{Renderer=\l_polyglossia_luatex_renderer}
+ }
+\fi
+
+\bool_if:nTF \l_polyglossia_verbose_bool {} {
+ \gdef\@latex@info#1{\relax}% no latex info
+ \gdef\@font@info#1{\relax}% no latex font info
+ \gdef\@font@warning#1{\relax}% no latex font warnings
+ \gdef\zf@PackageInfo#1{\relax}% no fontspec info
+ \gdef\xpg@info#1{\relax}% no polyglossia info
+}
+
+\bool_if:nTF \l_polyglossia_localmarks_bool {
+ \polyglossia@enable@local@marks:
+}{}
+
+% compatibility
+\newif\ifsystem@babelshorthands
+\bool_if:nTF \l_polyglossia_babelshorthands_bool {
+ \system@babelshorthandstrue
+}{
+ \system@babelshorthandsfalse
+}
+
+%
+% FIXME these should also be loaded \AtEndOfPackage !!!
+\def\xpg@option#1#2{%
+ \ifcsundef{xpg@main@language}{\setdefaultlanguage}{\setotherlanguage}%
+ [#1]{#2}}
+\ExplSyntaxOff
+
+% \end{macrocode}
+% \iffalse
+%</polyglossia.sty>
+%<*farsical.sty>
+% \fi
+% \clearpage
+%
+% \subsection{farsical.sty}
+% \begin{macrocode}
+\ProvidesPackage{farsical}
+ [2019/12/12 v0.2 %
+ Farsi (jalali) calendar]
+\ifluatex\RequirePackage{luabidi}\else\RequirePackage{bidi}\fi
+\RequirePackage{calc,arabicnumbers}
+
+%TODO - rewrite completely using calc
+%% - use Reingold & Dershowitz ME
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Modified from Arabiftoday.sty which is part of the Arabi package:
+%%% Copyright (C) 2006 Youssef Jabri
+%%% itself a modification of the code in the FarsiTeX system:
+%%% Copyright (C) 1996 Hassan Abolhassani
+%%% Copyright (C) 1996-2001 Roozbeh Pournader <roozbeh@sharif.edu>
+%%% Copyright (C) 2000-2001 Behdad Esfahbod <behdad@bamdad.org>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\ifJALALI@leap \newif\ifJALALI@kabiseh
+\newcount\JALALI@i \newcount\JALALI@y \newcount\JALALI@m \newcount\JALALI@d
+\newcount\JALALI@latini \newcount\JALALI@farsii
+\newcount\JALALI@latinii \newcount\JALALI@farsiii
+\newcount\JALALI@latiniii \newcount\JALALI@farsiiii
+\newcount\JALALI@latiniv \newcount\JALALI@farsiiv
+\newcount\JALALI@latinv \newcount\JALALI@farsiv
+\newcount\JALALI@latinvi \newcount\JALALI@farsivi
+\newcount\JALALI@latinvii \newcount\JALALI@farsivii
+\newcount\JALALI@latinviii \newcount\JALALI@farsiviii
+\newcount\JALALI@latinix \newcount\JALALI@farsiix
+\newcount\JALALI@latinx \newcount\JALALI@farsix
+\newcount\JALALI@latinxi \newcount\JALALI@farsixi
+\newcount\JALALI@latinxii \newcount\JALALI@farsixii
+ \newcount\JALALI@farsixiii
+
+\newcount\JALALI@temp
+\newcount\JALALI@temptwo
+\newcount\JALALI@tempthree
+\newcount\JALALI@yModHundred
+\newcount\JALALI@thirtytwo
+\newcount\JALALI@dn
+\newcount\JALALI@sn
+\newcount\JALALI@mminusone
+
+% \ftoday renamed to \Jalalitoday - FC
+\def\Jalalitoday{%
+\JALALI@y=\year \JALALI@m=\month \JALALI@d=\day
+%
+\JALALI@temp=\JALALI@y
+\divide\JALALI@temp by 100\relax
+\multiply\JALALI@temp by 100\relax
+\JALALI@yModHundred=\JALALI@y
+\advance\JALALI@yModHundred by -\JALALI@temp\relax
+%
+\ifodd\JALALI@yModHundred
+ \JALALI@leapfalse
+\else
+ \JALALI@temp=\JALALI@yModHundred
+ \divide\JALALI@temp by 2\relax
+ \ifodd\JALALI@temp\JALALI@leapfalse
+ \else
+ \ifnum\JALALI@yModHundred=0%
+ \JALALI@temp=\JALALI@y
+ \divide\JALALI@temp by 400\relax
+ \multiply\JALALI@temp by 400\relax
+ \ifnum\JALALI@y=\JALALI@temp\JALALI@leaptrue\else\JALALI@leapfalse\fi
+ \else\JALALI@leaptrue
+ \fi
+ \fi
+\fi
+%
+\JALALI@latini=31\relax
+\ifJALALI@leap
+ \JALALI@latinii = 29\relax
+\else
+ \JALALI@latinii = 28\relax
+\fi
+\JALALI@latiniii = 31\relax
+\JALALI@latiniv = 30\relax
+\JALALI@latinv = 31\relax
+\JALALI@latinvi = 30\relax
+\JALALI@latinvii = 31\relax
+\JALALI@latinviii = 31\relax
+\JALALI@latinix = 30\relax
+\JALALI@latinx = 31\relax
+\JALALI@latinxi = 30\relax
+\JALALI@latinxii = 31\relax
+%
+\JALALI@thirtytwo=32\relax
+%
+\JALALI@temp=\JALALI@y
+\advance\JALALI@temp by -17\relax
+\JALALI@temptwo=\JALALI@temp
+\divide\JALALI@temptwo by 33\relax
+\multiply\JALALI@temptwo by 33\relax
+\advance\JALALI@temp by -\JALALI@temptwo
+\ifnum\JALALI@temp=\JALALI@thirtytwo\JALALI@kabisehfalse
+\else
+ \JALALI@temptwo=\JALALI@temp
+ \divide\JALALI@temptwo by 4\relax
+ \multiply\JALALI@temptwo by 4\relax
+ \advance\JALALI@temp by -\JALALI@temptwo
+ \ifnum\JALALI@temp=\z@\JALALI@kabisehtrue\else\JALALI@kabisehfalse\fi
+\fi
+%
+% --BE
+% In fact farsii is equal to the Leap years from a fixed year to the last
+% year minus the Kabise years from a fixed year to the last year plus a const.
+%
+\JALALI@tempthree=\JALALI@y % Number of Leap years
+\advance\JALALI@tempthree by -1
+\JALALI@temp=\JALALI@tempthree % T := (MY-1) div 4
+\divide\JALALI@temp by 4\relax
+\JALALI@temptwo=\JALALI@tempthree % T := T - ((MY-1) div 100)
+\divide\JALALI@temptwo by 100\relax
+\advance\JALALI@temp by -\JALALI@temptwo
+\JALALI@temptwo=\JALALI@tempthree % T := T + ((MY-1) div 400)
+\divide\JALALI@temptwo by 400\relax
+\advance\JALALI@temp by \JALALI@temptwo
+\advance\JALALI@tempthree by -611 % Number of Kabise years
+\JALALI@temptwo=\JALALI@tempthree % T := T - ((SY+10) div 33) * 8
+\divide\JALALI@temptwo by 33\relax
+\multiply\JALALI@temptwo by 8\relax
+\advance\JALALI@temp by -\JALALI@temptwo
+\JALALI@temptwo=\JALALI@tempthree %
+\divide\JALALI@temptwo by 33\relax
+\multiply\JALALI@temptwo by 33\relax
+\advance\JALALI@tempthree by -\JALALI@temptwo
+\ifnum\JALALI@tempthree=32\advance\JALALI@temp by 1\fi % if (SY+10) mod 33=32 then Inc(T);
+\divide\JALALI@tempthree by 4\relax % T := T - ((SY+10) mod 33) div 4
+\advance\JALALI@temp by -\JALALI@tempthree
+\advance\JALALI@temp by -137 % T := T - 137 Adjust the value
+\JALALI@farsii=31
+\advance\JALALI@farsii by -\JALALI@temp % now 31 - T is the farsii
+%
+\JALALI@farsiii = 30\relax
+\ifJALALI@kabiseh
+ \JALALI@farsiiii = 30\relax
+\else
+ \JALALI@farsiiii = 29\relax
+\fi
+\JALALI@farsiiv = 31\relax
+\JALALI@farsiv = 31\relax
+\JALALI@farsivi = 31\relax
+\JALALI@farsivii = 31\relax
+\JALALI@farsiviii= 31\relax
+\JALALI@farsiix = 31\relax
+\JALALI@farsix = 30\relax
+\JALALI@farsixi = 30\relax
+\JALALI@farsixii = 30\relax
+\JALALI@farsixiii= 30\relax
+%
+\JALALI@dn= 0\relax
+\JALALI@sn= 0\relax
+\JALALI@mminusone=\JALALI@m
+\advance\JALALI@mminusone by -1\relax
+%
+\JALALI@i=0\relax
+\ifnum\JALALI@i < \JALALI@mminusone
+\loop
+\advance \JALALI@i by 1\relax
+\advance\JALALI@dn by \csname JALALI@latin\romannumeral\the\JALALI@i\endcsname
+\ifnum\JALALI@i<\JALALI@mminusone \repeat
+\fi
+\advance \JALALI@dn by \JALALI@d
+%
+\JALALI@i=1\relax
+\JALALI@sn = \JALALI@farsii
+\ifnum \JALALI@sn<\JALALI@dn
+\loop
+\advance \JALALI@i by 1\relax
+\advance\JALALI@sn by \csname JALALI@farsi\romannumeral\the\JALALI@i\endcsname
+\ifnum \JALALI@sn<\JALALI@dn \repeat
+\fi
+\ifnum \JALALI@i < 4
+ \JALALI@m = 9 \advance\JALALI@m by \JALALI@i
+ \advance \JALALI@y by -622\relax
+\else
+ \JALALI@m = \JALALI@i \advance \JALALI@m by -3\relax
+ \advance \JALALI@y by -621\relax
+\fi
+\advance\JALALI@sn by -\csname JALALI@farsi\romannumeral\the\JALALI@i%
+\endcsname
+\ifnum\JALALI@i = 1
+ \JALALI@d = \JALALI@dn \advance \JALALI@d by 30 \advance\JALALI@d by -\JALALI@farsii
+\else
+ \JALALI@d = \JALALI@dn \advance \JALALI@d by -\JALALI@sn
+\fi
+%% DATE FORMATTING
+\if@RTL{\farsidigits{\number\JALALI@d}\space%
+\Jalalimonth{\JALALI@m}\space\farsidigits{\number\JALALI@y}}%
+\else
+\number\JALALI@d\space\JalalimonthEnglish{\JALALI@m}%
+\space\number\JALALI@y%
+\fi}
+%%%
+\def\Jalalimonth#1{\ifcase#1\or فروردین\or
+اردیبهشت\or خرداد\or تیر\or مرداد\or شهریور%
+\or مهر\or آبان\or آذر\or دی\or بهمن\or اسفند%
+\fi}
+\def\JalalimonthEnglish#1{\ifcase#1%
+\or Farvardīn\or Ordībehesht\or Khordād\or Tīr%
+\or Mordād\or Shahrīvar\or Mihr\or Ābān\or Āzar%
+\or Dai\or Bahman\or Esfand\fi}
+% \end{macrocode}
+% \iffalse
+%</farsical.sty>
+%<*hebrewcal.sty>
+% \fi
+% \clearpage
+%
+% \subsection{hebrewcal.sty}
+% \begin{macrocode}
+\ProvidesPackage{hebrewcal}
+ [2019/12/03 v2.7 %
+ Hebrew calendar for polyglossia (adapted from hebcal.sty in Babel)]
+\RequirePackage{xkeyval}
+\ifluatex\RequirePackage{luabidi}\else\RequirePackage{bidi}\fi
+
+\newif\if@xpg@hebrewcal@marcheshvan
+\@xpg@hebrewcal@marcheshvanfalse
+
+\DeclareOption{marcheshvan}{\@xpg@hebrewcal@marcheshvantrue}
+
+\@ifundefined{if@xpg@hebrew@marcheshvan}{}{%
+ \if@xpg@hebrew@marcheshvan
+ \@xpg@hebrewcal@marcheshvantrue
+ \fi
+}
+
+%% TODO rewrite this on the basis of Reingold & Dershowitz
+%% on the model of hijrical (using calc)
+
+\@ifundefined{@Remainder}{\input{cal-util.def}}{}
+
+\define@boolkey{hebrew}[@hebrew@]{fullyear}[true]{}
+\setkeys{hebrew}{fullyear=false}
+
+\newcount\hebrewday \newcount\hebrewmonth \newcount\hebrewyear
+\def\hebrewdate#1#2#3{%
+ \HebrewFromGregorian{#1}{#2}{#3}%
+ {\hebrewday}{\hebrewmonth}{\hebrewyear}%
+ \if@RTL%
+ \@FormatForHebrew{\hebrewday}{\hebrewmonth}{\hebrewyear}%
+ \else%
+ \@FormatForEnglish{\hebrewday}{\hebrewmonth}{\hebrewyear}%
+ \fi}
+\def\hebrewtoday{\hebrewdate{\day}{\month}{\year}}
+% The command name is capitalised in the doc, and this is consistent
+% with other names such as \Hijritoday and \Jalalitoday.
+\let\Hebrewtoday=\hebrewtoday
+\def\hebrewsetreg{%
+ \HebrewFromGregorian{\day}{\month}{\year}%
+ {\hebrewday}{\hebrewmonth}{\hebrewyear}}
+\def\HebrewYearName#1{{%
+ \@tempcnta=#1\divide\@tempcnta by 1000\multiply\@tempcnta by 1000
+ \ifnum#1=\@tempcnta\relax % divisible by 1000: disambiguate
+ \Hebrewnumeral{#1}\ (לפ"ג)%
+ \else % not divisible by 1000
+ \ifnum#1<1000\relax % first millennium: disambiguate
+ \Hebrewnumeral{#1}\ (לפ"ג)%
+ \else
+ \ifnum#1<5000
+ \Hebrewnumeral{#1}%
+ \else
+ \ifnum#1<6000 % current millenium, print without thousands
+ \@tempcnta=#1\relax
+ \if@hebrew@fullyear\else\advance\@tempcnta by -5000\fi
+ \Hebrewnumeral{\@tempcnta}%
+ \else % #1>6000
+ \Hebrewnumeral{#1}%
+ \fi
+ \fi
+ \fi
+ \fi}}
+\def\HebrewMonthName#1#2{%
+ \ifnum #1 = 7 %
+ \@CheckLeapHebrewYear{#2}%
+ \if@HebrewLeap אדר\ ב'%
+ \else אדר%
+ \fi%
+ \else%
+ \ifcase#1%
+ % nothing for 0
+ \or תשרי%
+ \or\if@xpg@hebrewcal@marcheshvan מרחשון\else חשון\fi%
+ \or כסלו%
+ \or טבת%
+ \or שבט%
+ \or אדר\ א'%
+ \or אדר\ ב'%
+ \or ניסן%
+ \or אייר%
+ \or סיון%
+ \or תמוז%
+ \or אב%
+ \or אלול%
+ \fi%
+ \fi}
+\def\@FormatForHebrew#1#2#3{%
+ \Hebrewnumeral{#1}~ב\HebrewMonthName{#2}{#3}~%
+ \HebrewYearName{#3}}
+\def\HebrewMonthNameInEnglish#1#2{%
+ \ifnum #1 = 7%
+ \@CheckLeapHebrewYear{#2}%
+ \if@HebrewLeap Adar II\else Adar\fi%
+ \else%
+ \ifcase #1%
+ % nothing for 0
+ \or Tishrei%
+ \or\if@xpg@hebrewcal@marcheshvan Marcheshvan\else Heshvan\fi%
+ \or Kislev%
+ \or Tebeth%
+ \or Shebat%
+ \or Adar I%
+ \or Adar II%
+ \or Nisan%
+ \or Iyar%
+ \or Sivan%
+ \or Tammuz%
+ \or Av%
+ \or Elul%
+ \fi
+ \fi}
+\def\@FormatForEnglish#1#2#3{%
+ \HebrewMonthNameInEnglish{#2}{#3} \number#1,\ \number#3}
+\newcount\@common
+\newif\if@HebrewLeap
+\def\@CheckLeapHebrewYear#1{%
+ {%
+ \countdef\tmpa = 0% % \tmpa==\count0
+ \countdef\tmpb = 1% % \tmpb==\count1
+ \tmpa = #1%
+ \multiply \tmpa by 7%
+ \advance \tmpa by 1%
+ \@Remainder{\tmpa}{19}{\tmpb}%
+ \ifnum \tmpb < 7% % \tmpb = (7*year+1)%19
+ \global\@HebrewLeaptrue%
+ \else%
+ \global\@HebrewLeapfalse%
+ \fi}}
+\def\@HebrewElapsedMonths#1#2{%
+ {%
+ \countdef\tmpa = 0% % \tmpa==\count0
+ \countdef\tmpb = 1% % \tmpb==\count1
+ \countdef\tmpc = 2% % \tmpc==\count2
+ \tmpa = #1% %
+ \advance \tmpa by -1% %
+ #2 = \tmpa% % #2 = \tmpa = year-1
+ \divide #2 by 19% % Number of complete Meton cycles
+ \multiply #2 by 235% % #2 = 235*((year-1)/19)
+ \@Remainder{\tmpa}{19}{\tmpb}% \tmpa = years%19-years this cycle
+ \tmpc = \tmpb% %
+ \multiply \tmpb by 12% %
+ \advance #2 by \tmpb% % add regular months this cycle
+ \multiply \tmpc by 7% %
+ \advance \tmpc by 1% %
+ \divide \tmpc by 19% % \tmpc = (1+7*((year-1)%19))/19 -
+ \advance #2 by \tmpc% % add leap months
+ \global\@common = #2}%
+ #2 = \@common}
+\def\@HebrewElapsedDays#1#2{%
+ {%
+ \countdef\tmpa = 0% % \tmpa==\count0
+ \countdef\tmpb = 1% % \tmpb==\count1
+ \countdef\tmpc = 2% % \tmpc==\count2
+ \@HebrewElapsedMonths{#1}{#2}%
+ \tmpa = #2% %
+ \multiply \tmpa by 13753% %
+ \advance \tmpa by 5604% % \tmpa=MonthsElapsed*13758 + 5604
+ \@Remainder{\tmpa}{25920}{\tmpc}% \tmpc == ConjunctionParts
+ \divide \tmpa by 25920%
+ \multiply #2 by 29%
+ \advance #2 by 1%
+ \advance #2 by \tmpa% % #2 = 1 + MonthsElapsed*29 +
+ \@Remainder{#2}{7}{\tmpa}% % \tmpa == DayOfWeek
+ \ifnum \tmpc < 19440%
+ \ifnum \tmpc < 9924%
+ \else% % New moon at 9 h. 204 p. or later
+ \ifnum \tmpa = 2% % on Tuesday ...
+ \@CheckLeapHebrewYear{#1}% of a common year
+ \if@HebrewLeap%
+ \else%
+ \advance #2 by 1%
+ \fi%
+ \fi%
+ \fi%
+ \ifnum \tmpc < 16789%
+ \else% % New moon at 15 h. 589 p. or later
+ \ifnum \tmpa = 1% % on Monday ...
+ \advance #1 by -1%
+ \@CheckLeapHebrewYear{#1}% at the end of leap year
+ \if@HebrewLeap%
+ \advance #2 by 1%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+ \advance #2 by 1% % new moon at or after midday
+ \fi%
+ \@Remainder{#2}{7}{\tmpa}% % \tmpa == DayOfWeek
+ \ifnum \tmpa = 0% % if Sunday ...
+ \advance #2 by 1%
+ \else% %
+ \ifnum \tmpa = 3% % Wednesday ...
+ \advance #2 by 1%
+ \else%
+ \ifnum \tmpa = 5% % or Friday
+ \advance #2 by 1%
+ \fi%
+ \fi%
+ \fi%
+ \global\@common = #2}%
+ #2 = \@common}
+\def\@DaysInHebrewYear#1#2{%
+ {%
+ \countdef\tmpe = 12% % \tmpe==\count12
+ \@HebrewElapsedDays{#1}{\tmpe}%
+ \advance #1 by 1%
+ \@HebrewElapsedDays{#1}{#2}%
+ \advance #2 by -\tmpe%
+ \global\@common = #2}%
+ #2 = \@common}
+\def\@HebrewDaysInPriorMonths#1#2#3{%
+ {%
+ \countdef\tmpf= 14% % \tmpf==\count14
+ #3 = \ifcase #1% % Days in prior month of regular year
+ 0 \or% % no month number 0
+ 0 \or% % Tishri
+ 30 \or% % Heshvan
+ 59 \or% % Kislev
+ 89 \or% % Tebeth
+ 118 \or% % Shebat
+ 148 \or% % Adar I
+ 148 \or% % Adar II
+ 177 \or% % Nisan
+ 207 \or% % Iyar
+ 236 \or% % Sivan
+ 266 \or% % Tammuz
+ 295 \or% % Av
+ 325 \or% % Elul
+ 400% % Dummy
+ \fi%
+ \@CheckLeapHebrewYear{#2}%
+ \if@HebrewLeap% % in leap year
+ \ifnum #1 > 6% % if month after Adar I
+ \advance #3 by 30% % add 30 days
+ \fi%
+ \fi%
+ \@DaysInHebrewYear{#2}{\tmpf}%
+ \ifnum #1 > 3%
+ \ifnum \tmpf = 353% %
+ \advance #3 by -1% %
+ \fi% % Short Kislev
+ \ifnum \tmpf = 383% %
+ \advance #3 by -1% %
+ \fi% %
+ \fi%
+ \ifnum #1 > 2%
+ \ifnum \tmpf = 355% %
+ \advance #3 by 1% %
+ \fi% % Long Heshvan
+ \ifnum \tmpf = 385% %
+ \advance #3 by 1% %
+ \fi% %
+ \fi%
+ \global\@common = #3}%
+ #3 = \@common}
+\def\@FixedFromHebrew#1#2#3#4{%
+ {%
+ #4 = #1%
+ \@HebrewDaysInPriorMonths{#2}{#3}{#1}%
+ \advance #4 by #1% % Add days in prior months this year
+ \@HebrewElapsedDays{#3}{#1}%
+ \advance #4 by #1% % Add days in prior years
+ \advance #4 by -1373429% % Subtract days before Gregorian
+ \global\@common = #4}% % 01.01.0001
+ #4 = \@common}
+\def\@GregorianDaysInPriorMonths#1#2#3{%
+ {%
+ #3 = \ifcase #1%
+ 0 \or% % no month number 0
+ 0 \or%
+ 31 \or%
+ 59 \or%
+ 90 \or%
+ 120 \or%
+ 151 \or%
+ 181 \or%
+ 212 \or%
+ 243 \or%
+ 273 \or%
+ 304 \or%
+ 334%
+ \fi%
+ \@CheckIfGregorianLeap{#2}%
+ \if@GregorianLeap%
+ \ifnum #1 > 2% % if month after February
+ \advance #3 by 1% % add leap day
+ \fi%
+ \fi%
+ \global\@common = #3}%
+ #3 = \@common}
+\def\@GregorianDaysInPriorYears#1#2{%
+ {%
+ \countdef\tmpc = 4% % \tmpc==\count4
+ \countdef\tmpb = 2% % \tmpb==\count2
+ \tmpb = #1% %
+ \advance \tmpb by -1% %
+ \tmpc = \tmpb% % \tmpc = \tmpb = year-1
+ \multiply \tmpc by 365% % Days in prior years =
+ #2 = \tmpc% % = 365*(year-1) ...
+ \tmpc = \tmpb% %
+ \divide \tmpc by 4% % \tmpc = (year-1)/4
+ \advance #2 by \tmpc% % ... plus Julian leap days ...
+ \tmpc = \tmpb% %
+ \divide \tmpc by 100% % \tmpc = (year-1)/100
+ \advance #2 by -\tmpc% % ... minus century years ...
+ \tmpc = \tmpb% %
+ \divide \tmpc by 400% % \tmpc = (year-1)/400
+ \advance #2 by \tmpc% % ... plus 4-century years.
+ \global\@common = #2}%
+ #2 = \@common}
+\def\@AbsoluteFromGregorian#1#2#3#4{%
+ {%
+ \countdef\tmpd = 0% % \tmpd==\count0
+ #4 = #1% % days so far this month
+ \@GregorianDaysInPriorMonths{#2}{#3}{\tmpd}%
+ \advance #4 by \tmpd% % add days in prior months
+ \@GregorianDaysInPriorYears{#3}{\tmpd}%
+ \advance #4 by \tmpd% % add days in prior years
+ \global\@common = #4}%
+ #4 = \@common}
+\def\HebrewFromGregorian#1#2#3#4#5#6{%
+ {%
+ \countdef\tmpx= 17% % \tmpx==\count17
+ \countdef\tmpy= 18% % \tmpy==\count18
+ \countdef\tmpz= 19% % \tmpz==\count19
+ #6 = #3% %
+ \global\advance #6 by 3761% approximation from above
+ \@AbsoluteFromGregorian{#1}{#2}{#3}{#4}%
+ \tmpz = 1 \tmpy = 1%
+ \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
+ \ifnum \tmpx > #4% %
+ \global\advance #6 by -1% Hyear = Gyear + 3760
+ \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
+ \fi% %
+ \advance #4 by -\tmpx% % Days in this year
+ \advance #4 by 1% %
+ #5 = #4% %
+ \divide #5 by 30% % Approximation for month from below
+ \loop% % Search for month
+ \@HebrewDaysInPriorMonths{#5}{#6}{\tmpx}%
+ \ifnum \tmpx < #4%
+ \advance #5 by 1%
+ \tmpy = \tmpx%
+ \repeat%
+ \global\advance #5 by -1%
+ \global\advance #4 by -\tmpy}}
+\ProcessOptions*
+% \end{macrocode}
+% \iffalse
+%</hebrewcal.sty>
+%<*hijrical.sty>
+% \fi
+% \clearpage
+%
+% \subsection{hijrical.sty}
+% \begin{macrocode}
+\ProvidesPackage{hijrical}
+ [2010/07/12 v0.2 %
+ Islamic calendar]
+\RequirePackage{calc}
+\RequirePackage{arabicnumbers}
+\@ifpackageloaded{bidi}{}{\newif\if@RTL\@RTLfalse}
+\@ifpackageloaded{l3calc}{\PackageError{hijrical}{\MessageBreak
+Package l3calc is loaded, which replaces the functionality of
+calc. Computation of Hijri dates will not work properly with
+% FIXME by Arthur: François couldn’t possibly mean ‘l3calc’ on the
+% following line :-) Find out if he meant ‘calc’.
+l3calc! The latest version of expl3 on CTAN no longer loads
+l3calc. Please update expl3!
+}{}}{}
+
+\@ifundefined{@Remainder}{\input{cal-util.def}}{}
+
+%% The following functions are straightforward implementation
+%% of Reingold & Dershowitz, Calendrical Calculations, The Millenium Edition
+%%
+
+\def\@FixedFromHijri#1#2#3#4{% year,month,day,counter
+\@ifundefined{c@#4}{\newcounter{#4}}{}%
+\setcounter{tmpA}{#2/2}% see errata of Reingold+Dershowitz
+%\message{tmpA is \thetmpA}%
+\setcounter{tmpB}{(3+11*#1)/30}%
+%\message{tmpB is \thetmpB}%
+\setcounter{#4}{227014+(#1-1)*354+\value{tmpB}+(29*(#2-1))+\value{tmpA}+#3}%
+}
+
+\newcounter{Hijriday}\newcounter{Hijrimonth}\newcounter{Hijriyear}
+
+\def\HijriFromGregorian#1#2#3{% year,month,day
+\@FixedFromGregorian{#1}{#2}{#3}{RDdate}%
+\setcounter{Hijriyear}{(30*(\value{RDdate}-227015)+10646)/10631}%
+\@FixedFromHijri{\value{Hijriyear}}{1}{1}{tmpx}%
+%\message{tmpx is \thetmpx}%
+\setcounter{tmpB}{\value{RDdate}-\value{tmpx}}%
+%\message{tmpB is \thetmpB}%
+\setcounter{Hijrimonth}{((11*\value{tmpB})+330)/325}%
+\@FixedFromHijri{\value{Hijriyear}}{\value{Hijrimonth}}{1}{tmpy}%
+%\message{tmpy is \thetmpy}%
+\setcounter{Hijriday}{1+\value{RDdate}-\value{tmpy}}%
+}
+
+%\HijriFromGregorian{\year}{\month}{\day}%
+
+%\def\PlainHijritoday{%
+%\theHijriday.\theHijrimonth.\theHijriyear}
+
+\def\Hijridate#1#2#3{%
+ \HijriFromGregorian{#1}{#2}{#3}%
+ \FormatHijriDate}
+
+% added option \Hijritoday[n] (default 0) for adjusting the date + n days
+\@ifundefined{@hijri@correction}{\gdef\@hijri@correction{0}}{}
+\newcommand\Hijritoday[1][\@hijri@correction]{%
+ \@ifundefined{c@adj@day}{\global\newcounter{adj@day}}{}%
+ \setcounter{adj@day}{\the\day+#1}%
+ \Hijridate{\year}{\month}{\value{adj@day}}}
+%\def\Hijritoday{\Hijridate{\year}{\month}{\day}}
+\let\hijritoday=\Hijritoday
+%FIXME necessary?
+%\def\Hijrisetreg{%
+% \HijriFromGregorian{\year}{\month}{\day}}
+
+\def\HijriMonthTranslit#1{\ifcase#1\or Muḥarram\or Ṣafar\or Rabīʿ I\or Rabīʿ II\or%
+Jumādā I\or Jumādā II\or Rajab\or Shaʿbān\or Ramaḍān\or%
+Shawwāl\or Dhū ’l-Qaʿda\or Dhū ’l-Ḥijja\fi}
+
+\def\HijriMonthArabic#1{\ifcase#1\or محرم\or صفر\or ربيع الأول\or ربيع الآخر\or%
+جمادى الأولى\or جمادى الآخرة\or رجب\or شعبان\or رمضان\or%
+شوال\or ذو القعدة\or ذو الحجة\fi}
+
+%% This macro is now locale-aware!
+\def\FormatHijriDate{%
+ \@ifundefined{FormatHijriDate@\languagename}%
+ {\if@RTL\FormatHijriDate@defaultRTL\else\FormatHijriDate@defaultLTR\fi}%
+ {\csname FormatHijriDate@\languagename\endcsname}}
+
+\newcommand\DefineFormatHijriDate[2]{%
+ \@namedef{FormatHijriDate@#1}{#2}}
+
+% we provide this as a reasonable default.
+% Further definitions are in polyglossia’s language definition files.
+\DefineFormatHijriDate{defaultRTL}{\@ensure@RTL{%
+\arabicdigits{\value{Hijriday}}\space\HijriMonthArabic{\value{Hijrimonth}}\space\arabicdigits{\value{Hijriyear}}}}
+
+\DefineFormatHijriDate{defaultLTR}{%
+\number\value{Hijriday}\space\HijriMonthTranslit{\value{Hijrimonth}}\space\number\value{Hijriyear}}
+% \end{macrocode}
+% \iffalse
+%</hijrical.sty>
+%<*polyglossia-french.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-french.lua}
+% \begin{macrocode}
+require('polyglossia-punct')
+
+local function set_left_space(lang, char, kern, rubber)
+ polyglossia.add_left_spaced_character(lang, char, kern, "space", rubber)
+end
+
+local function set_right_space(lang, char, kern, rubber)
+ polyglossia.add_right_spaced_character(lang, char, kern, "space", rubber)
+end
+
+local function activate_french_punct(thincolonspace, autospaceguillemets)
+ -- We need different language tags here to make switching of options possible
+ -- within a paragraph.
+ local lang = "french"
+ if thincolonspace then
+ lang = lang.."-thincolon"
+ end
+ if autospaceguillemets then
+ lang = lang.."-autospace"
+ end
+
+ polyglossia.activate_punct(lang)
+ polyglossia.clear_spaced_characters(lang)
+
+ if thincolonspace then
+ set_left_space(lang, ':', 0.5)
+ else
+ set_left_space(lang, ':', 1, true) -- stretchable and shrinkable space
+ end
+
+ set_left_space(lang, '!', 0.5)
+ set_left_space(lang, '?', 0.5)
+ set_left_space(lang, ';', 0.5)
+ set_left_space(lang, '‼', 0.5)
+ set_left_space(lang, '⁇', 0.5)
+ set_left_space(lang, '⁈', 0.5)
+ set_left_space(lang, '⁉', 0.5)
+ set_left_space(lang, '‽', 0.5) -- U+203D (interrobang)
+
+ if autospaceguillemets then
+ set_left_space(lang, '»', 0.5)
+ set_left_space(lang, '›', 0.5)
+ set_right_space(lang, '«', 0.5)
+ set_right_space(lang, '‹', 0.5)
+ end
+end
+
+local function deactivate_french_punct()
+ polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_french_punct = activate_french_punct
+polyglossia.deactivate_french_punct = deactivate_french_punct
+% \end{macrocode}
+% \iffalse
+%</polyglossia-french.lua>
+%<*polyglossia-korean.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-korean.lua}
+% \begin{macrocode}
+--
+-- polyglossia-korean.lua
+--
+
+local glyph_id = node.id"glyph"
+local hbox_id = node.id"hlist"
+local vbox_id = node.id"vlist"
+local glue_id = node.id"glue"
+local penalty_id = node.id"penalty"
+local disc_id = node.id"disc"
+
+--
+-- attr_korean: variant = plain (0), classic (1), modern (2)
+--
+local attr_korean = luatexbase.attributes["xpg@attr@korean"]
+local attr_josa = luatexbase.attributes["xpg@attr@autojosa"]
+
+--
+-- characters after which linebreak is not allowed
+--
+local nobr_after = {
+ [0x28] = 1, -- ( LEFT PARENTHESIS
+ [0x3C] = 1, -- < LESS-THAN SIGN
+ [0x5B] = 1, -- [ LEFT SQUARE BRACKET
+ [0x60] = 1, -- ` GRAVE ACCENT
+ [0x7B] = 1, -- { LEFT CURLY BRACKET
+ [0xAB] = 1, -- « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ [0x2018] = 1, -- ‘ LEFT SINGLE QUOTATION MARK
+ [0x201C] = 1, -- “ LEFT DOUBLE QUOTATION MARK
+ [0x2329] = 1, -- 〈 LEFT-POINTING ANGLE BRACKET
+ [0x3008] = 1, -- 〈 LEFT ANGLE BRACKET
+ [0x300A] = 1, -- 《 LEFT DOUBLE ANGLE BRACKET
+ [0x300C] = 1, -- 「 LEFT CORNER BRACKET
+ [0x300E] = 1, -- 『 LEFT WHITE CORNER BRACKET
+ [0x3010] = 1, -- 【 LEFT BLACK LENTICULAR BRACKET
+ [0x3014] = 1, -- 〔 LEFT TORTOISE SHELL BRACKET
+ [0x3016] = 1, -- 〖 LEFT WHITE LENTICULAR BRACKET
+ [0x3018] = 1, -- 〘 LEFT WHITE TORTOISE SHELL BRACKET
+ [0x301A] = 1, -- 〚 LEFT WHITE SQUARE BRACKET
+ [0x301D] = 1, -- 〝 REVERSED DOUBLE PRIME QUOTATION MARK
+ [0xFE17] = 1, -- ︗ PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+ [0xFE35] = 1, -- ︵ PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+ [0xFE37] = 1, -- ︷ PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+ [0xFE39] = 1, -- ︹ PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+ [0xFE3B] = 1, -- ︻ PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+ [0xFE3D] = 1, -- ︽ PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+ [0xFE3F] = 1, -- ︿ PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+ [0xFE41] = 1, -- ﹁ PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+ [0xFE43] = 1, -- ﹃ PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+ [0xFE47] = 1, -- ﹇ PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+ [0xFE59] = 1, -- ﹙ SMALL LEFT PARENTHESIS
+ [0xFE5B] = 1, -- ﹛ SMALL LEFT CURLY BRACKET
+ [0xFE5D] = 1, -- ﹝ SMALL LEFT TORTOISE SHELL BRACKET
+ [0xFF08] = 1, -- ( FULLWIDTH LEFT PARENTHESIS
+ [0xFF3B] = 1, -- [ FULLWIDTH LEFT SQUARE BRACKET
+ [0xFF5B] = 1, -- { FULLWIDTH LEFT CURLY BRACKET
+ [0xFF5F] = 1, -- ⦅ FULLWIDTH LEFT WHITE PARENTHESIS
+ [0xFF62] = 1, -- 「 HALFWIDTH LEFT CORNER BRACKET
+}
+
+--
+-- characters before which linebreak is not allowed
+-- (currently, not much differences among the followings)
+-- 1: normal chars
+-- 2: hangul jamo vowels and trailing consonants
+-- 3: kana small letters
+-- 0: dashes (supress visible spacing)
+--
+local nobr_before = setmetatable({
+ [0x21] = 1, -- ! EXCLAMATION MARK
+ [0x22] = 1, -- " QUOTATION MARK
+ [0x27] = 1, -- ' APOSTROPHE
+ [0x29] = 1, -- ) RIGHT PARENTHESIS
+ [0x2C] = 1, -- , COMMA
+ [0x2D] = 0, -- - HYPHEN-MINUS
+ [0x2E] = 1, -- . FULL STOP
+ [0x2F] = 0, -- / SOLIDUS
+ [0x3A] = 0, -- : COLON
+ [0x3B] = 1, -- ; SEMICOLON
+ [0x3E] = 1, -- > GREATER-THAN SIGN
+ [0x3F] = 1, -- ? QUESTION MARK
+ [0x5C] = 0, -- \ REVERSE SOLIDUS
+ [0x5D] = 1, -- ] RIGHT SQUARE BRACKET
+ [0x7D] = 1, -- } RIGHT CURLY BRACKET
+ [0x7E] = 0, -- ~ TILDE
+ [0xB7] = 1, -- · MIDDLE DOT
+ [0xBB] = 1, -- » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ [0x2013] = 0, -- – EN DASH
+ [0x2014] = 0, -- — EM DASH
+ [0x2015] = 1, -- ― HORIZONTAL BAR
+ [0x2019] = 1, -- ’ RIGHT SINGLE QUOTATION MARK
+ [0x201D] = 1, -- ” RIGHT DOUBLE QUOTATION MARK
+ [0x2025] = 1, -- ‥ TWO DOT LEADER
+ [0x2026] = 1, -- … HORIZONTAL ELLIPSIS
+ [0x232A] = 1, -- 〉 RIGHT-POINTING ANGLE BRACKET
+ [0x3001] = 1, -- 、 IDEOGRAPHIC COMMA
+ [0x3002] = 1, -- 。 IDEOGRAPHIC FULL STOP
+ [0x3005] = 1, -- 々 IDEOGRAPHIC ITERATION MARK
+ [0x3009] = 1, -- 〉 RIGHT ANGLE BRACKET
+ [0x300B] = 1, -- 》 RIGHT DOUBLE ANGLE BRACKET
+ [0x300D] = 1, -- 」 RIGHT CORNER BRACKET
+ [0x300F] = 1, -- 』 RIGHT WHITE CORNER BRACKET
+ [0x3011] = 1, -- 】 RIGHT BLACK LENTICULAR BRACKET
+ [0x3015] = 1, -- 〕 RIGHT TORTOISE SHELL BRACKET
+ [0x3017] = 1, -- 〗 RIGHT WHITE LENTICULAR BRACKET
+ [0x3019] = 1, -- 〙 RIGHT WHITE TORTOISE SHELL BRACKET
+ [0x301B] = 1, -- 〛 RIGHT WHITE SQUARE BRACKET
+ [0x301C] = 1, -- 〜 WAVE DASH
+ [0x301E] = 1, -- 〞 DOUBLE PRIME QUOTATION MARK
+ [0x301F] = 1, -- 〟 LOW DOUBLE PRIME QUOTATION MARK
+ [0x3035] = 1, -- 〵 VERTICAL KANA REPEAT MARK LOWER HALF
+ [0x303B] = 1, -- 〻 VERTICAL IDEOGRAPHIC ITERATION MARK
+ [0x303C] = 1, -- 〼 MASU MARK
+ [0x3041] = 3, -- ぁ HIRAGANA LETTER SMALL A
+ [0x3043] = 3, -- ぃ HIRAGANA LETTER SMALL I
+ [0x3045] = 3, -- ぅ HIRAGANA LETTER SMALL U
+ [0x3047] = 3, -- ぇ HIRAGANA LETTER SMALL E
+ [0x3049] = 3, -- ぉ HIRAGANA LETTER SMALL O
+ [0x3063] = 3, -- っ HIRAGANA LETTER SMALL TU
+ [0x3083] = 3, -- ゃ HIRAGANA LETTER SMALL YA
+ [0x3085] = 3, -- ゅ HIRAGANA LETTER SMALL YU
+ [0x3087] = 3, -- ょ HIRAGANA LETTER SMALL YO
+ [0x308E] = 3, -- ゎ HIRAGANA LETTER SMALL WA
+ [0x3095] = 3, -- ゕ HIRAGANA LETTER SMALL KA
+ [0x3096] = 3, -- ゖ HIRAGANA LETTER SMALL KE
+ [0x3099] = 1, -- COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
+ [0x309A] = 1, -- COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ [0x309B] = 1, -- ゛ KATAKANA-HIRAGANA VOICED SOUND MARK
+ [0x309C] = 1, -- ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ [0x309D] = 1, -- ゝ HIRAGANA ITERATION MARK
+ [0x309E] = 1, -- ゞ HIRAGANA VOICED ITERATION MARK
+ [0x30A0] = 1, -- ゠ KATAKANA-HIRAGANA DOUBLE HYPHEN
+ [0x30A1] = 3, -- ァ KATAKANA LETTER SMALL A
+ [0x30A3] = 3, -- ィ KATAKANA LETTER SMALL I
+ [0x30A5] = 3, -- ゥ KATAKANA LETTER SMALL U
+ [0x30A7] = 3, -- ェ KATAKANA LETTER SMALL E
+ [0x30A9] = 3, -- ォ KATAKANA LETTER SMALL O
+ [0x30C3] = 3, -- ッ KATAKANA LETTER SMALL TU
+ [0x30E3] = 3, -- ャ KATAKANA LETTER SMALL YA
+ [0x30E5] = 3, -- ュ KATAKANA LETTER SMALL YU
+ [0x30E7] = 3, -- ョ KATAKANA LETTER SMALL YO
+ [0x30EE] = 3, -- ヮ KATAKANA LETTER SMALL WA
+ [0x30F5] = 3, -- ヵ KATAKANA LETTER SMALL KA
+ [0x30F6] = 3, -- ヶ KATAKANA LETTER SMALL KE
+ [0x30FB] = 1, -- ・ KATAKANA MIDDLE DOT
+ [0x30FC] = 1, -- ー KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ [0x30FD] = 1, -- ヽ KATAKANA ITERATION MARK
+ [0x30FE] = 1, -- ヾ KATAKANA VOICED ITERATION MARK
+ [0xFE30] = 1, -- ︰ PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ [0xFE31] = 1, -- ︱ PRESENTATION FORM FOR VERTICAL EM DASH
+ [0xFE32] = 1, -- ︲ PRESENTATION FORM FOR VERTICAL EN DASH
+ [0xFE36] = 1, -- ︶ PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+ [0xFE38] = 1, -- ︸ PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+ [0xFE3A] = 1, -- ︺ PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+ [0xFE3C] = 1, -- ︼ PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+ [0xFE3E] = 1, -- ︾ PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+ [0xFE40] = 1, -- ﹀ PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+ [0xFE42] = 1, -- ﹂ PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+ [0xFE44] = 1, -- ﹄ PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+ [0xFE48] = 1, -- ﹈ PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+ [0xFE5A] = 1, -- ﹚ SMALL RIGHT PARENTHESIS
+ [0xFE5C] = 1, -- ﹜ SMALL RIGHT CURLY BRACKET
+ [0xFE5E] = 1, -- ﹞ SMALL RIGHT TORTOISE SHELL BRACKET
+ [0xFF01] = 1, -- ! FULLWIDTH EXCLAMATION MARK
+ [0xFF09] = 1, -- ) FULLWIDTH RIGHT PARENTHESIS
+ [0xFF0C] = 1, -- , FULLWIDTH COMMA
+ [0xFF0E] = 1, -- . FULLWIDTH FULL STOP
+ [0xFF1A] = 1, -- : FULLWIDTH COLON
+ [0xFF1B] = 1, -- ; FULLWIDTH SEMICOLON
+ [0xFF1F] = 1, -- ? FULLWIDTH QUESTION MARK
+ [0xFF3D] = 1, -- ] FULLWIDTH RIGHT SQUARE BRACKET
+ [0xFF5D] = 1, -- } FULLWIDTH RIGHT CURLY BRACKET
+ [0xFF60] = 1, -- ⦆ FULLWIDTH RIGHT WHITE PARENTHESIS
+ [0xFF61] = 1, -- 。 HALFWIDTH IDEOGRAPHIC FULL STOP
+ [0xFF63] = 1, -- 」 HALFWIDTH RIGHT CORNER BRACKET
+ [0xFF64] = 1, -- 、 HALFWIDTH IDEOGRAPHIC COMMA
+ [0xFF65] = 1, -- ・ HALFWIDTH KATAKANA MIDDLE DOT
+ [0xFF9E] = 1, -- ゙ HALFWIDTH KATAKANA VOICED SOUND MARK
+ [0xFF9F] = 1, -- ゚ HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+}, { __index = function(_,c)
+ if c >= 0x1160 and c <= 0x11FF then return 2 end
+ if c >= 0xD7B0 and c <= 0xD7FF then return 2 end
+ if c >= 0x302A and c <= 0x302F then return 1 end
+ if c >= 0x31F0 and c <= 0x31FF then return 3 end
+ if c >= 0xFF67 and c <= 0xFF70 then return 3 end
+ if c >= 0xFE00 and c <= 0xFE0F then return 1 end
+ if c >= 0xFE10 and c <= 0xFE19 and not (c == 0xFE17) then return 1 end
+ if c >= 0xFE50 and c <= 0xFE58 then return 1 end
+ if c >= 0xE0100 and c <= 0xE01EF then return 1 end
+ end
+})
+
+--
+-- whether 'c' is a cjk character
+--
+local function is_cjk (c)
+ return c >= 0xAC00 and c <= 0xD7FF
+ or c >= 0x1100 and c <= 0x11FF
+ or c >= 0xA960 and c <= 0xA97F
+ or c >= 0x2E80 and c <= 0x9FFF
+ or c >= 0xF900 and c <= 0xFAFF
+ or c >= 0xFE10 and c <= 0xFE1F
+ or c >= 0xFE30 and c <= 0xFE6F
+ or c >= 0xFF00 and c <= 0xFFEF
+ or c >= 0x1F100 and c <= 0x1F2FF
+ or c >= 0x20000 and c <= 0x2FA1F
+ or nobr_after[c] and c > 0x2014
+ or nobr_before[c] and c > 0x2014
+end
+
+--
+-- classify cjk characters
+-- 1: openings
+-- 2: closings
+-- 3: centered chars
+-- 4: full stops
+-- 5: ellipses
+-- 6: exclamation and question marks
+-- 0: all others
+--
+local charclass = setmetatable({
+ [0x2018] = 1, [0x201C] = 1, [0x2329] = 1, [0x3008] = 1,
+ [0x300A] = 1, [0x300C] = 1, [0x300E] = 1, [0x3010] = 1,
+ [0x3014] = 1, [0x3016] = 1, [0x3018] = 1, [0x301A] = 1,
+ [0x301D] = 1, [0xFE17] = 1, [0xFE35] = 1, [0xFE37] = 1,
+ [0xFE39] = 1, [0xFE3B] = 1, [0xFE3D] = 1, [0xFE3F] = 1,
+ [0xFE41] = 1, [0xFE43] = 1, [0xFE47] = 1, [0xFF08] = 1,
+ [0xFF3B] = 1, [0xFF5B] = 1, [0xFF5F] = 1, [0xFF62] = 1,
+ [0x2019] = 2, [0x201D] = 2, [0x232A] = 2, [0x3001] = 2,
+ [0x3009] = 2, [0x300B] = 2, [0x300D] = 2, [0x300F] = 2,
+ [0x3011] = 2, [0x3015] = 2, [0x3017] = 2, [0x3019] = 2,
+ [0x301B] = 2, [0x301E] = 2, [0x301F] = 2, [0xFE10] = 2,
+ [0xFE11] = 2, [0xFE18] = 2, [0xFE36] = 2, [0xFE38] = 2,
+ [0xFE3A] = 2, [0xFE3C] = 2, [0xFE3E] = 2, [0xFE40] = 2,
+ [0xFE42] = 2, [0xFE44] = 2, [0xFE48] = 2, [0xFF09] = 2,
+ [0xFF0C] = 2, [0xFF3D] = 2, [0xFF5D] = 2, [0xFF60] = 2,
+ [0xFF63] = 2, [0xFF64] = 2, [0x00B7] = 3, [0x30FB] = 3,
+ [0xFF1A] = 3, [0xFF1B] = 3, [0xFF65] = 3, [0x3002] = 4,
+ [0xFE12] = 4, [0xFF0E] = 4, [0xFF61] = 4, [0x2015] = 5,
+ [0x2025] = 5, [0x2026] = 5, [0xFE19] = 5, [0xFE30] = 5,
+ [0xFE31] = 5, [0xFE15] = 6, [0xFE16] = 6, [0xFF01] = 6,
+ [0xFF1F] = 6,
+}, { __index = function() return 0 end })
+
+--
+-- table for spacing between char classes
+-- 1 stands for 0.5*fontsize when variant=classic
+--
+local intercharclass = { [0] =
+ { [0] = nil, {1,1}, nil, {.5,.5} },
+ { [0] = nil, nil, nil, {.5,.5} },
+ { [0] = {1,1}, {1,1}, nil, {.5,.5}, nil, {1,1}, {1,1} },
+ { [0] = {.5,.5},{.5,.5},{.5,.5},{1,.5}, {.5,.5},{.5,.5},{.5,.5} },
+ { [0] = {1,0}, {1,0}, nil, {1.5,.5},nil, {1,0}, {1,0} },
+ { [0] = nil, {1,1}, nil, {.5,.5} },
+ { [0] = {1,1}, {1,1}, nil, {.5,.5} },
+}
+
+--
+-- get a new penalty node
+--
+local function get_new_penalty (p)
+ local penalty = node.new("penalty")
+ penalty.penalty = p
+ return penalty
+end
+
+--
+-- get a new glue node
+--
+local function get_new_glue (...)
+ local glue = node.new("glue")
+ node.setglue(glue, ...)
+ return glue
+end
+
+--
+-- return 0.5*fontsize of given fontid
+-- space: true if variant=modern; then 0.5*interword_space
+--
+local function get_font_size (fid, space)
+ local size = font.getparameters(fid)
+ if space then
+ size = size and size.space or 196608
+ else
+ size = size and size.quad or 655360
+ end
+ return size/2
+end
+
+--
+-- charclass 1 thru 4 will be packed in \hbox to 0.5em{\hss? curr \hss?}
+-- when variant=classic/modern
+--
+local function glyph_to_box (head, curr, class)
+ local g, h = curr
+ local size = get_font_size(g.font)
+ head, curr = node.remove(head, curr)
+ g.next, g.prev = nil, nil
+ local hss = get_new_glue(0, 65536, 65536, 2, 2)
+ if class == 1 then
+ h, hss.next, g.prev = hss, g, hss
+ elseif class == 2 or class == 4 then
+ h, g.next, hss.prev = g, hss, g
+ else
+ local hss2 = node.copy(hss)
+ h, hss.next, g.prev, g.next, hss2.prev = hss, g, hss, hss2, g
+ end
+ h = nodes.simple_font_handler(h)
+ local box = node.hpack(h, size, "exactly")
+ if curr then
+ head, curr = node.insert_before(head, curr, box)
+ else
+ head, curr = node.insert_after(head, node.tail(head), box)
+ end
+ return head, curr
+end
+
+--
+-- insert spacing defined as charclass[a][b] between a and b
+-- f: fontid
+-- var: variant = plain, classic, modern
+-- cc: charclass of current char
+-- nc: charclass of next char
+-- nobr: linebreak is not allowed
+--
+local function insert_cjk_penalty_glue (head, curr, f, var, cc, nc, nobr)
+ if nobr or cc == 1 or nc > 1 then
+ local penalty = get_new_penalty(10000)
+ head, curr = node.insert_after(head, curr, penalty)
+ end
+ local factor = get_font_size(f, var == 2)
+ local t = intercharclass[cc][nc]
+ local glue = get_new_glue(t[1]*factor, nil, t[2]*factor)
+ head, curr = node.insert_after(head, curr, glue)
+ return head, curr
+end
+
+--
+-- insert inter-character spacing in other normal cases
+-- f: fontid
+-- var: variant = plain, classic, modern
+-- x: true between cjk and non-cjk (a little more spacing)
+--
+local function insert_penalty_glue (head, curr, f, var, x)
+ if var ~= 1 then
+ local penalty = get_new_penalty(50)
+ head, curr = node.insert_after(head, curr, penalty)
+ end
+ local size, glue = get_font_size(f, x and var == 2)
+ if x then
+ glue = get_new_glue(size/2, size/4, size/8)
+ else
+ glue = get_new_glue(0, size/10, size/50)
+ end
+ head, curr = node.insert_after(head, curr, glue)
+ return head, curr
+end
+
+--
+-- main process for linebreak and inter-character spacing
+-- lb: true if pre_linebreak_filter
+--
+local function korean_break (head, lb)
+ local curr = head
+ while curr do
+ if curr.id == glyph_id then
+ local var = node.has_attribute(curr, attr_korean)
+ if var then
+ local c, f = curr.char or 0, curr.font or 0
+ local cc, cjkc = charclass[c], is_cjk(c)
+
+ -- compress cjk punctuations when charclass is 1 thru 4
+ if var > 0 and cc > 0 and cc < 5 then
+ head, curr = glyph_to_box(head, curr, cc)
+ end
+
+ local next = curr.next
+ if next and next.id == glyph_id then
+ local n = next.char or 0
+ local nc = charclass[n]
+ local nobr = nobr_before[n] or nobr_after[c]
+
+ -- insert spacing as of intercharclass
+ if var > 0 and intercharclass[cc][nc] then
+ head, curr = insert_cjk_penalty_glue(head, curr, f, var, cc, nc, nobr)
+
+ -- or insert spacing when linebreak is allowed
+ elseif not nobr then
+ local cjkn = is_cjk(n)
+
+ -- if curr or next is cjk char
+ if cjkc or cjkn then
+
+ -- if between cjk and non-cjk
+ if var > 0 and not (cjkc and cjkn) and nobr_before[c] ~= 0 then
+ head, curr = insert_penalty_glue(head, curr, f, var, true)
+
+ -- or under pre_linebreak_filter
+ elseif lb then
+ head, curr = insert_penalty_glue(head, curr, f, var)
+ end
+ end
+ end
+ end
+ end
+ end
+ curr = curr.next
+ end
+ return head
+end
+
+--
+-- process for reordering hangul tone marks (U+302E, U+302F)
+-- some hangul fonts (eg. Noto CJK) are so designed that hangul tone marks
+-- should be moved to the first position of a syllable.
+-- Currently, this functionality is not provided by luaotfload.
+--
+local function reorder_tm (head)
+ local curr, tone = node.slide(head)
+ while curr do
+ if curr.id == glyph_id and node.has_attribute(curr, attr_korean) then
+ local f = font.getfont(curr.font) or font.fonts[curr.font]
+ if f and f.hb then -- harfbuzz do the right thing
+ tone = nil
+ else
+ local c, wd = curr.char or 0, curr.width or 0
+ if (c == 0x302E or c == 0x302F) and wd > 0 then
+ tone = curr
+ elseif tone and not nobr_before[c] then
+ head = node.remove(head, tone)
+ tone.next, tone.prev = nil, nil
+ head, curr = node.insert_before(head, curr, tone)
+ tone = nil
+ end
+ end
+ end
+ curr = curr.prev
+ end
+ return head
+end
+
+--
+-- automatic josa selection
+--
+local josa_table = {
+ -- consonant ㄹ, vowel, other consonants
+ [0xAC00] = {0xC774, 0xAC00, 0xC774}, -- 가 => 이, 가, 이
+ [0xC740] = {0xC740, 0xB294, 0xC740}, -- 은 => 은, 는, 은
+ [0xC744] = {0xC744, 0xB97C, 0xC744}, -- 을 => 을, 를, 을
+ [0xC640] = {0xACFC, 0xC640, 0xACFC}, -- 와 => 과, 와, 과
+ [0xC73C] = {nil, nil, 0xC73C}, -- 으(로) => , , 으
+ [0xC774] = {0xC774, nil, 0xC774}, -- 이(라) => 이, , 이
+}
+
+--
+-- helper function for number-like characters
+--
+local function josa_char_num (t, c)
+ c = c % 10 + 0x30
+ return t[c] or 2
+end
+
+--
+-- decide josa selection
+--
+local josa_code = setmetatable({
+ [0x30] = 3, [0x31] = 1, [0x33] = 3, [0x36] = 3, [0x37] = 1,
+ [0x38] = 1, [0x4C] = 1, [0x4D] = 3, [0x4E] = 3, [0x6C] = 1,
+ [0x6D] = 3, [0x6E] = 3, [0xFB02] = 1, [0xFB04] = 1,
+},{ __index = function(t,c)
+ if c >= 0xAC00 and c <= 0xD7A3 then
+ c = (c - 0xAC00) % 28 + 0x11A7
+ end
+ if c >= 0x11A8 and c <= 0x11FF then
+ if c == 0x11AF then return 1 end
+ return 3
+ end
+ if c >= 0xD7CB and c <= 0xD7FB then return 3 end
+ if c >= 0x2170 and c <= 0x217F then c = c - 0x10 end
+ if c >= 0x2160 and c <= 0x216F then
+ if c >= 0x216C then return 3 end
+ return josa_char_num(t, c - 0x215F)
+ end
+ if c >= 0x2460 and c <= 0x2473 then return josa_char_num(t, c - 0x245F) end
+ if c >= 0x2474 and c <= 0x2487 then return josa_char_num(t, c - 0x2473) end
+ if c >= 0x2488 and c <= 0x249B then return josa_char_num(t, c - 0x2487) end
+ if c >= 0x249C and c <= 0x24B5 then return t[c - 0x249C + 0x61] or 2 end
+ if c >= 0x24B6 and c <= 0x24CF then return t[c - 0x24B6 + 0x61] or 2 end
+ if c >= 0x24D0 and c <= 0x24E9 then return t[c - 0x24D0 + 0x61] or 2 end
+ if c >= 0x3131 and c <= 0x318E then
+ if c == 0x3139 then return 1 end
+ if c >= 0x314F and c <= 0x3163 or c >= 0x3187 then return 2 end
+ return 3
+ end
+ if c >= 0x3260 and c <= 0x327E then c = c - 0x60 end
+ if c >= 0x3200 and c <= 0x321E then
+ if c == 0x3203 then return 1 end
+ if c >= 0x320E then return 2 end
+ return 3
+ end
+ if c >= 0xFF10 and c <= 0xFF19 then return josa_char_num(t, c - 0xFF10) end
+ if c >= 0xFF21 and c <= 0xFF3A then return t[c - 0xFF21 + 0x61] or 2 end
+ if c >= 0xFF41 and c <= 0xFF5A then return t[c - 0xFF41 + 0x61] or 2 end
+ return 2
+ end
+})
+
+--
+-- obtain char that comes just before the josa
+--
+local function get_prev_char (p)
+ while p do
+ if p.id == glyph_id then
+ local pc = p.char or 0
+ if not nobr_after[pc] then
+ if not nobr_before[pc] or nobr_before[pc] >= 2 then
+ return pc
+ end
+ end
+ elseif p.id == hbox_id or p.id == vbox_id then
+ local pc = get_prev_char(node.slide(p.head))
+ if pc then return pc end
+ end
+ p = p.prev
+ end
+end
+
+--
+-- main process of josa selection
+--
+local function auto_josa (head)
+ local curr, tofree = head, {}
+ while curr do
+ if curr.id == glyph_id then
+ local josa = node.has_attribute(curr, attr_josa)
+ if josa then
+ local cc = curr.char or 0
+ if josa == 0 then
+ josa = josa_code[get_prev_char(curr.prev) or 0x30]
+ end
+ if cc == 0xC774 then
+ local n = curr.next
+ if n and n.char and n.char >= 0xAC00 and n.char <= 0xD7A3 then
+ else
+ cc = 0xAC00
+ end
+ end
+ local new = josa_table[cc]
+ if new then
+ cc = new[josa]
+ if cc then
+ curr.char = cc
+ else
+ head = node.remove(head, curr)
+ table.insert(tofree, curr)
+ end
+ end
+ node.unset_attribute(curr, attr_josa)
+ end
+ end
+ curr = curr.next
+ end
+ for _,v in ipairs(tofree) do node.free(v) end
+ return head
+end
+
+--
+-- now register to luatex callbacks
+-- As char value of glyphs can be changed by opentype GSUB process,
+-- we have to occupy the first position among callback functions.
+--
+local prepend_to_callback
+if luatexbase.base_add_to_callback then
+ prepend_to_callback = function(name, func, desc)
+ luatexbase.add_to_callback(name, func, desc, 1)
+ end
+else
+ prepend_to_callback = function(name, func, desc)
+ local t = { {func, desc} }
+ for _,v in ipairs(luatexbase.callback_descriptions(name)) do
+ table.insert(t, {luatexbase.remove_from_callback(name, v)})
+ end
+ for _,v in ipairs(t) do
+ luatexbase.add_to_callback(name, v[1], v[2])
+ end
+ end
+end
+
+prepend_to_callback ("pre_linebreak_filter",
+ function(head)
+ head = auto_josa(head)
+ head = korean_break(head, true)
+ head = reorder_tm(head)
+ return head
+ end,
+ "polyglossia.lang_korean")
+
+prepend_to_callback ("hpack_filter",
+ function(head)
+ head = auto_josa(head)
+ head = korean_break(head)
+ head = reorder_tm(head)
+ return head
+ end,
+ "polyglossia.lang_korean")
+
+-- vim:ft=lua:tw=0:sw=4:ts=4:expandtab
+% \end{macrocode}
+% \iffalse
+%</polyglossia-korean.lua>
+%<*polyglossia-latin.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-latin.lua}
+% \begin{macrocode}
+require('polyglossia-punct')
+
+-- For ecclesiastic Latin (and sometimes for Italian) a very small space is
+-- used for the punctuation. The ecclesiastic package uses a space of
+-- 0.3\fontdimen2, where \fontdimen2 is a interword space, which is typically
+-- between 1/4 and 1/3 of a quad. We choose a half of a \thinspace here.
+local hairspace = 0.08333 -- 1/12
+
+local function space_left(char)
+ polyglossia.add_left_spaced_character('latin', char, hairspace, 'quad')
+end
+
+local function space_right(char)
+ polyglossia.add_right_spaced_character('latin', char, hairspace, 'quad')
+end
+
+polyglossia.clear_spaced_characters('latin')
+space_left('!')
+space_left('?')
+space_left('‼')
+space_left('⁇')
+space_left('⁈')
+space_left('⁉')
+space_left('‽') -- U+203D (interrobang)
+space_left(':')
+space_left(';')
+space_left('»')
+space_left('›')
+space_right('«')
+space_right('‹')
+
+local function activate_latin_punct()
+ polyglossia.activate_punct('latin')
+end
+
+local function deactivate_latin_punct()
+ polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_latin_punct = activate_latin_punct
+polyglossia.deactivate_latin_punct = deactivate_latin_punct
+% \end{macrocode}
+% \iffalse
+%</polyglossia-latin.lua>
+%<*polyglossia-punct.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-punct.lua}
+% \begin{macrocode}
+require('polyglossia') -- just in case...
+
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+local priority_in_callback = luatexbase.priority_in_callback
+local new_attribute = luatexbase.new_attribute
+
+local node = node
+
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = node.remove
+local has_attribute = node.has_attribute
+local node_copy = node.copy
+local new_node = node.new
+local end_of_math = node.end_of_math
+local getnext = node.getnext
+local getprev = node.getprev
+
+-- node types according to node.types()
+local glue_code = node.id"glue"
+local glyph_code = node.id"glyph"
+local penalty_code = node.id"penalty"
+local kern_code = node.id"kern"
+local math_code = node.id"math"
+
+-- we need some node subtypes
+local userkern = 1
+local userskip = 0
+local removable_skip = {
+ [0] = true, -- userskip
+ [13] = true, -- spaceskip
+ [14] = true, -- xspaceskip
+}
+
+-- we make a new node, so that we can copy it later on
+local kern_node = new_node(kern_code)
+kern_node.subtype = userkern -- this kern can be removed later on
+
+local function get_kern_node(dim)
+ local n = node_copy(kern_node)
+ n.kern = dim
+ return n
+end
+
+local glue_node = new_node(glue_code)
+glue_node.subtype = userskip
+
+local function get_glue_node(dim, stretch, shrink)
+ local n = node_copy(glue_node)
+ n.width = dim
+ n.stretch = stretch
+ n.shrink = shrink
+ return n
+end
+
+local penalty_node = new_node(penalty_code)
+penalty_node.penalty = 10000
+
+local function get_penalty_node()
+ return node_copy(penalty_node)
+end
+
+-- all possible space characters according to section 6.2 of the Unicode Standard
+-- https://www.unicode.org/versions/Unicode12.0.0/ch06.pdf
+local space_chars = {
+ [0x20] = true, -- space
+ [0xA0] = true, -- no-break space
+ [0x1680] = true, -- ogham space mark
+ [0x2000] = true, -- en quad
+ [0x2001] = true, -- em quad
+ [0x2002] = true, -- en space
+ [0x2003] = true, -- em space
+ [0x2004] = true, -- three-per-em-space
+ [0x2005] = true, -- four-per-em space
+ [0x2006] = true, -- six-per-em space
+ [0x2007] = true, -- figure space
+ [0x2008] = true, -- punctuation space
+ [0x2009] = true, -- thin space
+ [0x200A] = true, -- hair space
+ [0x202F] = true, -- narrow no-break space
+ [0x205F] = true, -- medium mathematical space
+ [0x3000] = true -- ideographic space
+}
+
+-- all left bracket characters, referenced by their Unicode slot
+local left_bracket_chars = {
+ [0x28] = true, -- left parenthesis
+ [0x5B] = true, -- left square bracket
+ [0x7B] = true, -- left curly bracket
+ [0x27E8] = true -- mathematical left angle bracket
+}
+
+-- all right bracket characters, referenced by their Unicode slot
+local right_bracket_chars = {
+ [0x29] = true, -- right parenthesis
+ [0x5D] = true, -- right square bracket
+ [0x7D] = true, -- right curly bracket
+ [0x27E9] = true -- mathematical right angle bracket
+}
+
+-- question and exclamation marks, referenced by their Unicode slot
+local question_exclamation_chars = {
+ [0x21] = true, -- exclamation mark !
+ [0x3F] = true, -- question mark ?
+ [0x203C] = true, -- double exclamation mark ‼
+ [0x203D] = true, -- interrobang ‽
+ [0x2047] = true, -- double question mark ⁇
+ [0x2048] = true, -- question exclamation mark ⁈
+ [0x2049] = true -- exclamation question mark ⁉
+}
+
+-- from nodes-tst.lua, adapted
+local function somespace(n)
+ if n then
+ local id, subtype = n.id, n.subtype
+ if id == glue_code then
+ -- it is dangerous to remove all the type of glue
+ return removable_skip[subtype]
+ elseif id == kern_code then
+ -- remove only user's kern
+ return subtype == userkern
+ elseif id == glyph_code then
+ return space_chars[n.char]
+ end
+ end
+end
+
+local function someleftbracket(n)
+ if n then
+ local id = n.id
+ if id == glyph_code then
+ return left_bracket_chars[n.char]
+ end
+ end
+end
+
+local function somerightbracket(n)
+ if n then
+ local id = n.id
+ if id == glyph_code then
+ return right_bracket_chars[n.char]
+ end
+ end
+end
+
+local function question_exclamation_sequence(n1, n2)
+ if n1 and n2 then
+ local id1 = n1.id
+ local id2 = n2.id
+ if id1 == glyph_code and id2 == glyph_code then
+ return question_exclamation_chars[n1.char] and question_exclamation_chars[n2.char]
+ end
+ end
+end
+
+-- idem
+local function somepenalty(n, value)
+ if n then
+ local id = n.id
+ if id == penalty_code then
+ if value then
+ return n.penalty == value
+ else
+ return true
+ end
+ end
+ end
+end
+
+local punct_attr = new_attribute("polyglossia_punct")
+
+local lang_id = {}
+local lang_counter = 0
+local left_space = {}
+local right_space = {}
+
+local function ensure_lang_id(lang)
+ if not lang_id[lang] then
+ lang_counter = lang_counter + 1
+ lang_id[lang] = lang_counter
+ end
+ return lang_id[lang]
+end
+
+local function clear_spaced_characters(lang)
+ local id = ensure_lang_id(lang)
+ left_space[id] = {}
+ right_space[id] = {}
+end
+
+local function illegal_unit(unit)
+ if unit then
+ texio.write_nl('Illegal spacing unit "'..unit..'".')
+ else
+ texio.write_nl('Spacing unit is a nil value.')
+ end
+end
+
+local function add_left_spaced_character(lang, char, kern, unit, rubber)
+-- The parameter kern is a number meant as a fraction of the unit.
+-- The unit can be "quad" (1em) or "space" (interword space).
+-- The parameter rubber is a Boolean value indicating if the inserted space is
+-- stretchable and shrinkable (only relevant if the unit is "space").
+ local id = ensure_lang_id(lang)
+ if unit == "quad" or unit == "space" then
+ left_space[id][char] = {}
+ left_space[id][char]["kern"] = kern
+ left_space[id][char]["unit"] = unit
+ left_space[id][char]["rubber"] = rubber
+ else
+ illegal_unit(unit)
+ end
+end
+
+local function add_right_spaced_character(lang, char, kern, unit, rubber)
+ local id = ensure_lang_id(lang)
+ if unit == "quad" or unit == "space" then
+ right_space[id][char] = {}
+ right_space[id][char]["kern"] = kern
+ right_space[id][char]["unit"] = unit
+ right_space[id][char]["rubber"] = rubber
+ else
+ illegal_unit(unit)
+ end
+end
+
+-- from typo-spa.lua, adapted
+local function process(head)
+ local current = head
+ while current do
+ local id = current.id
+ if id == glyph_code then
+ local attr = has_attribute(current, punct_attr)
+ if attr then
+ local char, leftspace, rightspace
+ if current.char <= 0x10FFFF then -- greater values may cause problems with utf8.char
+ char = utf8.char(current.char)
+ leftspace = left_space[attr][char]
+ rightspace = right_space[attr][char]
+ end
+ if leftspace or rightspace then
+ local fontparameters = fonts.hashes.parameters[current.font]
+ local unit, stretch, shrink, spacing_node
+ if leftspace and fontparameters then
+ local prev = getprev(current)
+ local space_exception = false
+ if prev then
+ -- do not add space after left (opening) bracket and between question/exclamation marks
+ space_exception = someleftbracket(prev) or question_exclamation_sequence(prev, current)
+ -- TODO: there is a question here: do we override a preceding space or not?...
+ while somespace(prev) do
+ head = remove_node(head, prev)
+ prev = getprev(current)
+ end
+ if somepenalty(prev, 10000) then
+ head = remove_node(head, prev)
+ end
+ end
+ if leftspace.unit == "quad" then
+ unit = fontparameters.quad
+ spacing_node = get_kern_node(leftspace.kern*unit)
+ elseif leftspace.unit == "space" then
+ unit = fontparameters.space
+ if leftspace.rubber then
+ stretch = leftspace.kern*fontparameters.space_stretch
+ shrink = leftspace.kern*fontparameters.space_shrink
+ spacing_node = get_glue_node(leftspace.kern*unit, stretch, shrink)
+ head = insert_node_before(head, current, get_penalty_node())
+ else
+ spacing_node = get_kern_node(leftspace.kern*unit)
+ end
+ end
+ if not space_exception then
+ head = insert_node_before(head, current, spacing_node)
+ end
+ end
+ if rightspace and fontparameters then
+ local next = getnext(current)
+ local space_exception = false
+ if next then
+ -- do not add space before right (closing) bracket
+ space_exception = somerightbracket(next)
+ local nextnext = getnext(next)
+ if somepenalty(next, 10000) and somespace(nextnext) then
+ head, next = remove_node(head, next)
+ end
+ while somespace(next) do
+ head, next = remove_node(head, next)
+ end
+ end
+ if rightspace.unit == "quad" then
+ unit = fontparameters.quad
+ spacing_node = get_kern_node(rightspace.kern*unit)
+ elseif rightspace.unit == "space" then
+ unit = fontparameters.space
+ if rightspace.rubber then
+ stretch = rightspace.kern*fontparameters.space_stretch
+ shrink = rightspace.kern*fontparameters.space_shrink
+ spacing_node = get_glue_node(rightspace.kern*unit, stretch, shrink)
+ if not space_exception then
+ head, current = insert_node_after(head, current, get_penalty_node())
+ end
+ else
+ spacing_node = get_kern_node(rightspace.kern*unit)
+ end
+ end
+ if not space_exception then
+ head, current = insert_node_after(head, current, spacing_node)
+ end
+ end
+ end
+ end
+ elseif id == math_code then
+ -- warning: this is a feature of luatex > 0.76
+ current = end_of_math(current) -- weird, can return nil .. no math end?
+ end
+ current = getnext(current) -- no error even if current is nil
+ end
+ return head
+end
+
+local function activate(lang)
+ local id = ensure_lang_id(lang)
+ -- We set the punctuation attribute to a language id here. This is
+ -- important to be able to intermix languages with different spacings
+ -- in one paragraph.
+ tex.setattribute(punct_attr, id)
+ for _, callback_name in ipairs{ "pre_linebreak_filter", "hpack_filter" } do
+ if not priority_in_callback(callback_name, "polyglossia-punct.process") then
+ add_to_callback(callback_name, process, "polyglossia-punct.process", 1)
+ end
+ end
+end
+
+local function deactivate()
+ tex.setattribute(punct_attr, -0x7FFFFFFF) -- this value means "unset"
+ -- Though it would make compilation slightly faster, it is not possible to
+ -- safely uncomment the following lines. Imagine the following case: you
+ -- start a paragraph by some spaced punctuation text, then, in the same
+ -- paragraph, you change the language to something else, and thus call the
+ -- following lines. This means that, at the end of the paragraph, the
+ -- function won't be in the callback, so the beginning of the paragraph
+ -- won't be processed by it.
+ -- if priority_in_callback(callback_name, "polyglossia-punct.process") then
+ -- remove_from_callback(callback_name, "polyglossia-punct.process")
+ -- end
+end
+
+polyglossia.activate_punct = activate
+polyglossia.deactivate_punct = deactivate
+polyglossia.add_left_spaced_character = add_left_spaced_character
+polyglossia.add_right_spaced_character = add_right_spaced_character
+polyglossia.clear_spaced_characters = clear_spaced_characters
+% \end{macrocode}
+% \iffalse
+%</polyglossia-punct.lua>
+%<*polyglossia-sanskrit.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-sanskrit.lua}
+% \begin{macrocode}
+require('polyglossia-punct')
+
+-- How do we now, in Lua, what a \thinspace is? In the LaTeX source (latex.ltx)
+-- it is defined as:
+-- \def\thinspace{\leavevmode@ifvmode\kern .16667em }
+-- I see no way of seeing if it has been overriden or not. So we stick to this
+-- value.
+local thinspace = 0.16667 -- 1/6
+
+local function space_left(char)
+ polyglossia.add_left_spaced_character('sanskrit', char, thinspace, 'quad')
+end
+
+polyglossia.clear_spaced_characters('sanskrit')
+space_left('!')
+space_left('?')
+space_left('‼')
+space_left('⁇')
+space_left('⁈')
+space_left('⁉')
+space_left('‽') -- U+203D (interrobang)
+space_left(':')
+space_left(';')
+space_left('।') -- danda, U+0964
+space_left('॥') -- double danda, U+0965
+
+local function activate_sanskrit_punct()
+ polyglossia.activate_punct('sanskrit')
+end
+
+local function deactivate_sanskrit_punct()
+ polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_sanskrit_punct = activate_sanskrit_punct
+polyglossia.deactivate_sanskrit_punct = deactivate_sanskrit_punct
+% \end{macrocode}
+% \iffalse
+%</polyglossia-sanskrit.lua>
+%<*polyglossia-tibt.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia-tibt.lua}
+% \begin{macrocode}
+require('polyglossia') -- just in case...
+
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+local priority_in_callback = luatexbase.priority_in_callback
+
+local next, type = next, type
+
+local nodes, fonts, node = nodes, fonts, node
+
+local nodecodes = nodes.nodecodes --- <= preloaded node.types()
+
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove
+local copy_node = node.copy
+local has_attribute = node.has_attribute
+
+local end_of_math = node.end_of_math
+if not end_of_math then -- luatex < .76
+ local traverse_nodes = node.traverse_id
+ local math_code = nodecodes.math
+ local end_of_math = function (n)
+ for n in traverse_nodes(math_code, n.next) do
+ return n
+ end
+ end
+end
+
+-- node types as of April 2013
+local glyph_code = nodecodes.glyph
+local penalty_code = nodecodes.penalty
+local kern_code = nodecodes.kern
+
+-- we make a new node, so that we can copy it later on
+local penalty_node = node.new(penalty_code)
+penalty_node.penalty = 50 -- corresponds to the penalty LaTeX sets at explicit hyphens
+
+local function get_penalty_node()
+ return copy_node(penalty_node)
+end
+
+local xpgtibtattr = luatexbase.attributes['xpg@tibteol']
+
+local tsheg = unicode.utf8.byte('་')
+
+-- from typo-spa.lua
+local function process(head)
+ local start = head
+ -- head is always begin of par (whatsit), so we have at least two prev nodes
+ -- penalty followed by glue
+ while start do
+ local id = start.id
+ if id == glyph_code then
+ local attr = has_attribute(start, xpgtibtattr)
+ if attr and attr > 0 then
+ if start.char == tsheg then
+ if start.next then
+ insert_node_after(head,start,get_penalty_node())
+ end
+ end
+ end
+ elseif id == math_code then
+ -- warning: this is a feature of luatex > 0.76
+ start = end_of_math(start) -- weird, can return nil .. no math end?
+ end
+ if start then
+ start = start.next
+ end
+ end
+ return head
+end
+
+local callback_name = "pre_linebreak_filter"
+
+local function activate()
+ if not priority_in_callback (callback_name, "polyglossia-tibt.process") then
+ add_to_callback(callback_name, process, "polyglossia-tibt.process", 1)
+ end
+end
+
+local function desactivate()
+ if priority_in_callback (callback_name, "polyglossia-tibt.process") then
+ remove_from_callback(callback_name, "polyglossia-tibt.process")
+ end
+end
+
+polyglossia.activate_tibt_eol = activate
+polyglossia.desactivate_tibt_eol = desactivate
+% \end{macrocode}
+% \iffalse
+%</polyglossia-tibt.lua>
+%<*polyglossia.lua>
+% \fi
+% \clearpage
+%
+% \subsection{polyglossia.lua}
+% \begin{macrocode}
+
+local module_name = "polyglossia"
+local polyglossia_module = {
+ name = module_name,
+ version = 1.3,
+ date = "2013/05/11",
+ description = "Polyglossia",
+ author = "Elie Roux",
+ copyright = "Elie Roux",
+ license = "CC0"
+}
+
+luatexbase.provides_module(polyglossia_module)
+
+local log_info = function(message, ...)
+ luatexbase.module_info(module_name, message:format(...))
+end
+local log_warn = function(message, ...)
+ luatexbase.module_warning(module_name, message:format(...))
+end
+
+polyglossia = polyglossia or {}
+local polyglossia = polyglossia
+
+local function select_language(lang, id)
+ polyglossia.current_language = lang
+end
+
+local function set_default_language(lang, id)
+ polyglossia.default_language = lang
+end
+
+local byte = utf8.codepoint -- use standard module of lua 5.3
+
+local check_char
+
+if luaotfload and luaotfload.aux and luaotfload.aux.font_has_glyph then
+ local font_has_glyph = luaotfload.aux.font_has_glyph
+ function check_char(chr)
+ local codepoint = tonumber(chr) or byte(chr)
+ if font_has_glyph(font.current(), codepoint) then
+ tex.sprint('1')
+ else
+ tex.sprint('0')
+ end
+ end
+else
+ function check_char(chr) -- always in current font
+ local fontid = font.current()
+ local fontdata = font.getfont(fontid) or font.fonts[fontid]
+ local chardata = fontdata.characters
+ local codepoint = tonumber(chr) or byte(chr)
+ if chardata and chardata[codepoint] then
+ tex.sprint('1')
+ else
+ tex.sprint('0')
+ end
+ end
+end
+
+local function load_tibt_eol()
+ require('polyglossia-tibt')
+end
+
+-- predefined l@nohyphenation or LuaTeX's maximum value for \language
+local nohyphid = luatexbase.registernumber'l@nohyphenation' or 16383
+
+-- key `nohyphenation` is for .sty file when possibly undefined l@nohyphenation
+local newloader_loaded_languages = { nohyphenation = nohyphid }
+
+local newloader_available_languages = require'language.dat.lua'
+-- Suggestion by Dohyun Kim on #129
+local t = { }
+for k, v in pairs(newloader_available_languages) do
+ t[k] = v
+ for _, vv in pairs(v.synonyms) do
+ t[vv] = v
+ end
+end
+newloader_available_languages = t
+
+-- LaTeX's language register is \count19
+local lang_register = 19
+
+-- New hyphenation pattern loader: use language.dat.lua directly and the language identifiers
+local function newloader(langentry)
+ local loaded_language = newloader_loaded_languages[langentry]
+ if loaded_language then
+ local langid = lang.id(loaded_language)
+ log_info('Language %s already loaded; id is %i', langentry, langid)
+ return langid
+ else
+ local langdata = newloader_available_languages[langentry]
+ if langdata then
+
+ local special = langdata.special
+ if special then
+ -- language0 (USenglish) is already included in the format
+ if special == 'language0' then
+ return 0
+
+ -- disabled language should not be used for utf-8 text
+ elseif special:find'^disabled:' then
+ log_warn('Hyphenation of language %s %s', langentry, special)
+ return nohyphid
+ end
+ end
+
+ -- language info will be written into the .log file
+ local s = { "Language data for " .. langentry }
+ for k, v in pairs(langdata) do
+ if type(v) == 'table' then -- for 'synonyms'
+ s[#s+1] = k .. "\t" .. table.concat(v,',')
+ else
+ s[#s+1] = k .. "\t" .. tostring(v)
+ end
+ end
+ log_info(table.concat(s,"\n"))
+
+ --
+ -- LaTeX's \newlanguage increases language register (count19),
+ -- whereas LuaTeX's lang.new() increases its own language id.
+ -- So when a user has declared, say, \newlanguage\lang@xyz, then
+ -- these two numbers do not match each other. If we do not consider
+ -- this possible situation, our newloader() function will
+ -- unfortunately overwrite the language \lang@xyz.
+ --
+ -- Threfore here we will compare LaTeX's \newlanguage number with
+ -- LuaTeX's lang.new() id and select the bigger one for our new
+ -- language object. Also we will update LaTeX's language register
+ -- by this new id, so that another possible \newlanguage should not
+ -- overwrite our language object.
+ --
+ -- get next \newlanguage allocation number
+ local langcnt = tex.count[lang_register] + 1
+ -- get new lang object
+ local langobject = lang.new()
+ local langid = lang.id(langobject)
+ -- get bigger one between \newlanguage and new lang obj id
+ local newlangid = math.max(langcnt, langid)
+ -- set language register for possible \newlanguage
+ tex.setcount('global', lang_register, newlangid)
+ -- get new lang object if needeed
+ if langid ~= newlangid then
+ langobject = lang.new(newlangid)
+ end
+
+ -- load hyphenation patterns and exceptions
+ for _,v in ipairs{ 'patterns', 'hyphenation' } do
+ local data = langdata[v]
+ if data and data ~= '' then
+ -- cope with comma separated list, such as serbian
+ for _,vv in ipairs(data:explode',+') do
+ local filepath = kpse.find_file(vv)
+ if filepath then
+ local fh = io.open(filepath)
+ lang[v](langobject, fh:read'a')
+ fh:close()
+ else
+ log_warn('Hyphenation file %s not found', vv)
+ end
+ end
+ end
+ end
+
+ newloader_loaded_languages[langentry] = langobject
+
+ log_info('Language %s was not yet loaded; created with id %i',
+ langentry, newlangid)
+ return newlangid
+ else
+ log_warn('Language %s not found in language.dat.lua', langentry)
+ return nohyphid
+ end
+ end
+end
+
+polyglossia.select_language = select_language
+polyglossia.set_default_language = set_default_language
+polyglossia.check_char = check_char
+polyglossia.load_tibt_eol = load_tibt_eol
+polyglossia.newloader = newloader
+polyglossia.newloader_loaded_languages = newloader_loaded_languages
+-- global variables:
+-- polyglossia.default_language
+-- polyglossia.current_language
+% \end{macrocode}
+% \iffalse
+%</polyglossia.lua>
+%<*babel-hebrewalph.def>
+% \fi
+% \clearpage
+%
+% \subsection{babel-hebrewalph.def}
+% \begin{macrocode}
+\ProvidesFile{babel-hebrewalph.def}
+ [2010/03/02 %
+ Babel definitions for Hebrew numerals^^J
+ Adapted from hebrew.ldf (2005/03/30 v2.3h)]
+\newif\if@gim@apost % whether we print apostrophes (gereshayim)
+\newif\if@gim@final % whether we use final or initial letters
+\newcommand*\hebrewnumeral[1]{%
+ \expandafter\@hebrew@numeral\expandafter{\the\numexpr#1}%
+}
+\newcommand*\Hebrewnumeral[1]{%
+ \expandafter\@Hebrew@numeral\expandafter{\the\numexpr#1}%
+}
+\newcommand*\Hebrewnumeralfinal[1]{%
+ \expandafter\@Hebrew@numeralfinal\expandafter{\the\numexpr#1}%
+}
+\newrobustcmd*{\@hebrew@numeral}[1] % no apostrophe, no final letters
+ {{\@gim@finalfalse\@gim@apostfalse\@hebrew@@numeral{#1}}}
+\newrobustcmd*{\@Hebrew@numeral}[1] % apostrophe, no final letters
+ {{\@gim@finalfalse\@gim@aposttrue\@hebrew@@numeral{#1}}}
+\newrobustcmd*{\@Hebrew@numeralfinal}[1] % apostrophe, final letters
+ {{\@gim@finaltrue\@gim@aposttrue\@hebrew@@numeral{#1}}}
+\newcommand*{\@hebrew@@numeral}[1]{%
+ \ifnum#1<\z@\space\xpg@warning{Illegal value (#1) for Hebrew numeral}%
+ \else
+ \@tempcnta=#1\@tempcntb=#1\relax
+ \divide\@tempcntb by 1000
+ \ifnum\@tempcntb=0\gim@nomil\@tempcnta\relax
+ \else{\@gim@apostfalse\@gim@finalfalse\@hebrew@numeral\@tempcntb}׳%
+ \multiply\@tempcntb by 1000\relax
+ \advance\@tempcnta by -\@tempcntb\relax
+ \gim@nomil\@tempcnta\relax
+ \fi
+ \fi
+}
+\def\hebrew@alph@zero{}
+\newcommand*{\gim@nomil}[1]{\@tempcnta=#1\@gim@prevfalse
+ \@tempcntb=\@tempcnta\divide\@tempcntb by 100\relax % hundreds digit
+ \ifcase\@tempcntb % print nothing if no hundreds
+ \or\gim@print{100}{ק}%
+ \or\gim@print{200}{ר}%
+ \or\gim@print{300}{ש}%
+ \or\gim@print{400}{ת}%
+ \or ת\@gim@prevtrue\gim@print{500}{ק}%
+ \or ת\@gim@prevtrue\gim@print{600}{ר}%
+ \or ת\@gim@prevtrue\gim@print{700}{ש}%
+ \or ת\@gim@prevtrue\gim@print{800}{ת}%
+ \or ת\@gim@prevtrue ת\gim@print{900}{ק}%
+ \fi
+ \@tempcntb=\@tempcnta\divide\@tempcntb by 10\relax % tens digit
+ \ifcase\@tempcntb % print nothing if no tens
+ \or % number between 10 and 19
+ \ifnum\@tempcnta = 16 \gim@print {9}{ט}% tet-zayin
+ \else\ifnum\@tempcnta = 15 \gim@print {9}{ט}% tet-vav
+ \else \gim@print{10}{י}%
+ \fi % \@tempcnta = 15
+ \fi % \@tempcnta = 16
+ \or\gim@print{20}{\if@gim@final ך\else כ\fi}%
+ \or\gim@print{30}{ל}%
+ \or\gim@print{40}{\if@gim@final ם\else מ\fi}%
+ \or\gim@print{50}{\if@gim@final ן\else נ\fi}%
+ \or\gim@print{60}{ס}%
+ \or\gim@print{70}{ע}%
+ \or\gim@print{80}{\if@gim@final ף\else פ\fi}%
+ \or\gim@print{90}{\if@gim@final ץ\else צ\fi}%
+ \fi
+ \ifcase\@tempcnta
+ \hebrew@alph@zero% empty but can be defined if desired
+ \or\gim@print{1}{א}%
+ \or\gim@print{2}{ב}%
+ \or\gim@print{3}{ג}%
+ \or\gim@print{4}{ד}%
+ \or\gim@print{5}{ה}%
+ \or\gim@print{6}{ו}%
+ \or\gim@print{7}{ז}%
+ \or\gim@print{8}{ח}%
+ \or\gim@print{9}{ט}%
+ \fi
+}
+\newif\if@gim@prev % flag if a previous letter has been typeset
+\newcommand*{\gim@print}[2]{% #2 is a letter, #1 is its value.
+ \advance\@tempcnta by -#1\relax% deduct the value from the remainder
+ \ifnum\@tempcnta=0% if this is the last letter
+ \if@gim@prev\if@gim@apost ״\fi#2%
+ \else#2\if@gim@apost ׳\fi\fi%
+ \else{\@gim@finalfalse#2}\@gim@prevtrue\fi}
+\def\Alphfinal#1{\expandafter\@Alphfinal\csname c@#1\endcsname}%
+\providecommand*{\@Alphfinal}[1]{\Hebrewnumeralfinal{#1}}
+% \end{macrocode}
+% \iffalse
+%</babel-hebrewalph.def>
+%<*babelsh.def>
+% \fi
+% \clearpage
+%
+% \subsection{babelsh.def}
+% \begin{macrocode}
+\ifx\initiate@active@char\@undefined
+\else
+ \bbl@afterfi\endinput
+\fi
+\ProvidesFile{babelsh.def}
+ [2019/09/30 %
+ Babel common definitions for shorthands^^J
+ Taken verbatim from babel files (2019/09/27 v3.34)]
+%
+% ------------------------------------------------------------------------------
+%
+% lines 52 to 56 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@stripslash{\expandafter\@gobble\string}
+\def\bbl@add#1#2{%
+ \bbl@ifunset{\bbl@stripslash#1}%
+ {\def#1{#2}}%
+ {\expandafter\def\expandafter#1\expandafter{#1#2}}}
+%
+% ------------------------------------------------------------------------------
+%
+% line 73 to 74 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\long\def\bbl@afterelse#1\else#2\fi{\fi#1}
+\long\def\bbl@afterfi#1\fi{\fi#1}
+%
+% ------------------------------------------------------------------------------
+%
+% line 399 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\let\bbl@opt@shorthands\@nnil
+%
+% ------------------------------------------------------------------------------
+%
+% lines 432 to 445 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\bbl@opt@shorthands\@nnil
+ \def\bbl@ifshorthand#1#2#3{#2}%
+\else\ifx\bbl@opt@shorthands\@empty
+ \def\bbl@ifshorthand#1#2#3{#3}%
+\else
+ \def\bbl@ifshorthand#1{%
+ \bbl@xin@{\string#1}{\bbl@opt@shorthands}%
+ \ifin@
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+ \edef\bbl@opt@shorthands{%
+ \expandafter\bbl@sh@string\bbl@opt@shorthands\@empty}%
+%
+% ------------------------------------------------------------------------------
+%
+% line 450 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\fi\fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 389 to 424 from switch.def
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\PackageError\@undefined
+ \def\bbl@error#1#2{%
+ \begingroup
+ \newlinechar=`\^^J
+ \def\\{^^J(babel) }%
+ \errhelp{#2}\errmessage{\\#1}%
+ \endgroup}
+ \def\bbl@warning#1{%
+ \begingroup
+ \newlinechar=`\^^J
+ \def\\{^^J(polyglossia) }%
+ \message{\\#1}%
+ \endgroup}
+ \def\bbl@info#1{%
+ \begingroup
+ \newlinechar=`\^^J
+ \def\\{^^J}%
+ \wlog{#1}%
+ \endgroup}
+\else
+ \def\bbl@error#1#2{%
+ \begingroup
+ \def\\{\MessageBreak}%
+ \PackageError{polyglossia}{#1}{#2}%
+ \endgroup}
+ \def\bbl@warning#1{%
+ \begingroup
+ \def\\{\MessageBreak}%
+ \PackageWarning{polyglossia}{#1}%
+ \endgroup}
+ \def\bbl@info#1{%
+ \begingroup
+ \def\\{\MessageBreak}%
+ \PackageInfo{polyglossia}{#1}%
+ \endgroup}
+\fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 48 to 69 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\bbl@ifshorthand\@undefined
+ \let\bbl@opt@shorthands\@nnil
+ \def\bbl@ifshorthand#1#2#3{#2}%
+ \let\bbl@language@opts\@empty
+ \ifx\babeloptionstrings\@undefined
+ \let\bbl@opt@strings\@nnil
+ \else
+ \let\bbl@opt@strings\babeloptionstrings
+ \fi
+ \def\BabelStringsDefault{generic}
+ \def\bbl@tempa{normal}
+ \ifx\babeloptionmath\bbl@tempa
+ \def\bbl@mathnormal{\noexpand\textormath}
+ \fi
+ \def\AfterBabelLanguage#1#2{}
+ \ifx\BabelModifiers\@undefined\let\BabelModifiers\relax\fi
+ \let\bbl@afterlang\relax
+ \def\bbl@opt@safe{BR}
+ \ifx\@uclclist\@undefined\let\@uclclist\@empty\fi
+ \ifx\bbl@trace\@undefined\def\bbl@trace#1{}\fi
+ \expandafter\newif\csname ifbbl@single\endcsname
+\fi
+%
+% ------------------------------------------------------------------------------
+%
+% line 108 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@csarg#1#2{\expandafter#1\csname bbl@#2\endcsname}%
+
+% ------------------------------------------------------------------------------
+%
+% lines 110 to 116 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+
+\def\bbl@loop#1#2#3{\bbl@@loop#1{#3}#2,\@nnil,}
+\def\bbl@loopx#1#2{\expandafter\bbl@loop\expandafter#1\expandafter{#2}}
+\def\bbl@@loop#1#2#3,{%
+ \ifx\@nnil#3\relax\else
+ \def#1{#3}#2\bbl@afterfi\bbl@@loop#1{#2}%
+ \fi}
+\def\bbl@for#1#2#3{\bbl@loopx#1{#2}{\ifx#1\@empty\else#3\fi}}
+
+% ------------------------------------------------------------------------------
+%
+% lines 125 to 130 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@exp#1{%
+ \begingroup
+ \let\\\noexpand
+ \def\<##1>{\expandafter\noexpand\csname##1\endcsname}%
+ \edef\bbl@exp@aux{\endgroup#1}%
+ \bbl@exp@aux}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 144 to 149 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@ifunset#1{%
+ \expandafter\ifx\csname#1\endcsname\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 234 to 243 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\chardef\bbl@engine=%
+ \ifx\directlua\@undefined
+ \ifx\XeTeXinputencoding\@undefined
+ \z@
+ \else
+ \tw@
+ \fi
+ \else
+ \@ne
+ \fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 255 to 258 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@withactive#1#2{%
+ \begingroup
+ \lccode`~=`#2\relax
+ \lowercase{\endgroup#1~}}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 293 to 301 from babel.def
+%
+% NOTE: In order to avoid importing more unneeded definitions, this macro
+% does nothing for us.
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@usehooks#1#2{}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 443 to 558 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@add@special#1{% 1:a macro like \", \?, etc.
+ \bbl@add\dospecials{\do#1}% test @sanitize = \relax, for back. compat.
+ \bbl@ifunset{@sanitize}{}{\bbl@add\@sanitize{\@makeother#1}}%
+ \ifx\nfss@catcodes\@undefined\else % TODO - same for above
+ \begingroup
+ \catcode`#1\active
+ \nfss@catcodes
+ \ifnum\catcode`#1=\active
+ \endgroup
+ \bbl@add\nfss@catcodes{\@makeother#1}%
+ \else
+ \endgroup
+ \fi
+ \fi}
+\def\bbl@remove@special#1{%
+ \begingroup
+ \def\x##1##2{\ifnum`#1=`##2\noexpand\@empty
+ \else\noexpand##1\noexpand##2\fi}%
+ \def\do{\x\do}%
+ \def\@makeother{\x\@makeother}%
+ \edef\x{\endgroup
+ \def\noexpand\dospecials{\dospecials}%
+ \expandafter\ifx\csname @sanitize\endcsname\relax\else
+ \def\noexpand\@sanitize{\@sanitize}%
+ \fi}%
+ \x}
+\def\bbl@active@def#1#2#3#4{%
+ \@namedef{#3#1}{%
+ \expandafter\ifx\csname#2@sh@#1@\endcsname\relax
+ \bbl@afterelse\bbl@sh@select#2#1{#3@arg#1}{#4#1}%
+ \else
+ \bbl@afterfi\csname#2@sh@#1@\endcsname
+ \fi}%
+ \long\@namedef{#3@arg#1}##1{%
+ \expandafter\ifx\csname#2@sh@#1@\string##1@\endcsname\relax
+ \bbl@afterelse\csname#4#1\endcsname##1%
+ \else
+ \bbl@afterfi\csname#2@sh@#1@\string##1@\endcsname
+ \fi}}%
+\def\initiate@active@char#1{%
+ \bbl@ifunset{active@char\string#1}%
+ {\bbl@withactive
+ {\expandafter\@initiate@active@char\expandafter}#1\string#1#1}%
+ {}}
+\def\@initiate@active@char#1#2#3{%
+ \bbl@csarg\edef{oricat@#2}{\catcode`#2=\the\catcode`#2\relax}%
+ \ifx#1\@undefined
+ \bbl@csarg\edef{oridef@#2}{\let\noexpand#1\noexpand\@undefined}%
+ \else
+ \bbl@csarg\let{oridef@@#2}#1%
+ \bbl@csarg\edef{oridef@#2}{%
+ \let\noexpand#1%
+ \expandafter\noexpand\csname bbl@oridef@@#2\endcsname}%
+ \fi
+ \ifx#1#3\relax
+ \expandafter\let\csname normal@char#2\endcsname#3%
+ \else
+ \bbl@info{Making #2 an active character}%
+ \ifnum\mathcode`#2=\ifodd\bbl@engine"1000000 \else"8000 \fi
+ \@namedef{normal@char#2}{%
+ \textormath{#3}{\csname bbl@oridef@@#2\endcsname}}%
+ \else
+ \@namedef{normal@char#2}{#3}%
+ \fi
+ \bbl@restoreactive{#2}%
+ \AtBeginDocument{%
+ \catcode`#2\active
+ \if@filesw
+ \immediate\write\@mainaux{\catcode`\string#2\active}%
+ \fi}%
+ \expandafter\bbl@add@special\csname#2\endcsname
+ \catcode`#2\active
+ \fi
+ \let\bbl@tempa\@firstoftwo
+ \if\string^#2%
+ \def\bbl@tempa{\noexpand\textormath}%
+ \else
+ \ifx\bbl@mathnormal\@undefined\else
+ \let\bbl@tempa\bbl@mathnormal
+ \fi
+ \fi
+ \expandafter\edef\csname active@char#2\endcsname{%
+ \bbl@tempa
+ {\noexpand\if@safe@actives
+ \noexpand\expandafter
+ \expandafter\noexpand\csname normal@char#2\endcsname
+ \noexpand\else
+ \noexpand\expandafter
+ \expandafter\noexpand\csname bbl@doactive#2\endcsname
+ \noexpand\fi}%
+ {\expandafter\noexpand\csname normal@char#2\endcsname}}%
+ \bbl@csarg\edef{doactive#2}{%
+ \expandafter\noexpand\csname user@active#2\endcsname}%
+ \bbl@csarg\edef{active@#2}{%
+ \noexpand\active@prefix\noexpand#1%
+ \expandafter\noexpand\csname active@char#2\endcsname}%
+ \bbl@csarg\edef{normal@#2}{%
+ \noexpand\active@prefix\noexpand#1%
+ \expandafter\noexpand\csname normal@char#2\endcsname}%
+ \expandafter\let\expandafter#1\csname bbl@normal@#2\endcsname
+ \bbl@active@def#2\user@group{user@active}{language@active}%
+ \bbl@active@def#2\language@group{language@active}{system@active}%
+ \bbl@active@def#2\system@group{system@active}{normal@char}%
+ \expandafter\edef\csname\user@group @sh@#2@@\endcsname
+ {\expandafter\noexpand\csname normal@char#2\endcsname}%
+ \expandafter\edef\csname\user@group @sh@#2@\string\protect@\endcsname
+ {\expandafter\noexpand\csname user@active#2\endcsname}%
+ \if\string'#2%
+ \let\prim@s\bbl@prim@s
+ \let\active@math@prime#1%
+ \fi
+ \bbl@usehooks{initiateactive}{{#1}{#2}{#3}}}
+\@ifpackagewith{babel}{KeepShorthandsActive}%
+ {\let\bbl@restoreactive\@gobble}%
+ {\def\bbl@restoreactive#1{%
+ \bbl@exp{%
+%
+% ------------------------------------------------------------------------------
+%
+% lines 561 to 755 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+ \\\AtEndOfPackage
+ {\catcode`#1=\the\catcode`#1\relax}}}%
+ \AtEndOfPackage{\let\bbl@restoreactive\@gobble}}
+\def\bbl@sh@select#1#2{%
+ \expandafter\ifx\csname#1@sh@#2@sel\endcsname\relax
+ \bbl@afterelse\bbl@scndcs
+ \else
+ \bbl@afterfi\csname#1@sh@#2@sel\endcsname
+ \fi}
+\def\active@prefix#1{%
+ \ifx\protect\@typeset@protect
+ \else
+ \ifx\protect\@unexpandable@protect
+ \noexpand#1%
+ \else
+ \protect#1%
+ \fi
+ \expandafter\@gobble
+ \fi}
+\newif\if@safe@actives
+\@safe@activesfalse
+\def\bbl@restore@actives{\if@safe@actives\@safe@activesfalse\fi}
+\def\bbl@activate#1{%
+ \bbl@withactive{\expandafter\let\expandafter}#1%
+ \csname bbl@active@\string#1\endcsname}
+\def\bbl@deactivate#1{%
+ \bbl@withactive{\expandafter\let\expandafter}#1%
+ \csname bbl@normal@\string#1\endcsname}
+\def\bbl@firstcs#1#2{\csname#1\endcsname}
+\def\bbl@scndcs#1#2{\csname#2\endcsname}
+\def\declare@shorthand#1#2{\@decl@short{#1}#2\@nil}
+\def\@decl@short#1#2#3\@nil#4{%
+ \def\bbl@tempa{#3}%
+ \ifx\bbl@tempa\@empty
+ \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@scndcs
+ \bbl@ifunset{#1@sh@\string#2@}{}%
+ {\def\bbl@tempa{#4}%
+ \expandafter\ifx\csname#1@sh@\string#2@\endcsname\bbl@tempa
+ \else
+ \bbl@info
+ {Redefining #1 shorthand \string#2\\%
+ in language \CurrentOption}%
+ \fi}%
+ \@namedef{#1@sh@\string#2@}{#4}%
+ \else
+ \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@firstcs
+ \bbl@ifunset{#1@sh@\string#2@\string#3@}{}%
+ {\def\bbl@tempa{#4}%
+ \expandafter\ifx\csname#1@sh@\string#2@\string#3@\endcsname\bbl@tempa
+ \else
+ \bbl@info
+ {Redefining #1 shorthand \string#2\string#3\\%
+ in language \CurrentOption}%
+ \fi}%
+ \@namedef{#1@sh@\string#2@\string#3@}{#4}%
+ \fi}
+\def\textormath{%
+ \ifmmode
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+\def\user@group{user}
+\def\language@group{english}
+\def\system@group{system}
+\def\useshorthands{%
+ \@ifstar\bbl@usesh@s{\bbl@usesh@x{}}}
+\def\bbl@usesh@s#1{%
+ \bbl@usesh@x
+ {\AddBabelHook{babel-sh-\string#1}{afterextras}{\bbl@activate{#1}}}%
+ {#1}}
+\def\bbl@usesh@x#1#2{%
+ \bbl@ifshorthand{#2}%
+ {\def\user@group{user}%
+ \initiate@active@char{#2}%
+ #1%
+ \bbl@activate{#2}}%
+ {\bbl@error
+ {Cannot declare a shorthand turned off (\string#2)}
+ {Sorry, but you cannot use shorthands which have been\\%
+ turned off in the package options}}}
+\def\user@language@group{user@\language@group}
+\def\bbl@set@user@generic#1#2{%
+ \bbl@ifunset{user@generic@active#1}%
+ {\bbl@active@def#1\user@language@group{user@active}{user@generic@active}%
+ \bbl@active@def#1\user@group{user@generic@active}{language@active}%
+ \expandafter\edef\csname#2@sh@#1@@\endcsname{%
+ \expandafter\noexpand\csname normal@char#1\endcsname}%
+ \expandafter\edef\csname#2@sh@#1@\string\protect@\endcsname{%
+ \expandafter\noexpand\csname user@active#1\endcsname}}%
+ \@empty}
+\newcommand\defineshorthand[3][user]{%
+ \edef\bbl@tempa{\zap@space#1 \@empty}%
+ \bbl@for\bbl@tempb\bbl@tempa{%
+ \if*\expandafter\@car\bbl@tempb\@nil
+ \edef\bbl@tempb{user@\expandafter\@gobble\bbl@tempb}%
+ \@expandtwoargs
+ \bbl@set@user@generic{\expandafter\string\@car#2\@nil}\bbl@tempb
+ \fi
+ \declare@shorthand{\bbl@tempb}{#2}{#3}}}
+\def\languageshorthands#1{\def\language@group{#1}}
+\def\aliasshorthand#1#2{%
+ \bbl@ifshorthand{#2}%
+ {\expandafter\ifx\csname active@char\string#2\endcsname\relax
+ \ifx\document\@notprerr
+ \@notshorthand{#2}%
+ \else
+ \initiate@active@char{#2}%
+ \expandafter\let\csname active@char\string#2\expandafter\endcsname
+ \csname active@char\string#1\endcsname
+ \expandafter\let\csname normal@char\string#2\expandafter\endcsname
+ \csname normal@char\string#1\endcsname
+ \bbl@activate{#2}%
+ \fi
+ \fi}%
+ {\bbl@error
+ {Cannot declare a shorthand turned off (\string#2)}
+ {Sorry, but you cannot use shorthands which have been\\%
+ turned off in the package options}}}
+\def\@notshorthand#1{%
+ \bbl@error{%
+ The character `\string #1' should be made a shorthand character;\\%
+ add the command \string\useshorthands\string{#1\string} to
+ the preamble.\\%
+ I will ignore your instruction}%
+ {You may proceed, but expect unexpected results}}
+\newcommand*\shorthandon[1]{\bbl@switch@sh\@ne#1\@nnil}
+\DeclareRobustCommand*\shorthandoff{%
+ \@ifstar{\bbl@shorthandoff\tw@}{\bbl@shorthandoff\z@}}
+\def\bbl@shorthandoff#1#2{\bbl@switch@sh#1#2\@nnil}
+\def\bbl@switch@sh#1#2{%
+ \ifx#2\@nnil\else
+ \bbl@ifunset{bbl@active@\string#2}%
+ {\bbl@error
+ {I cannot switch `\string#2' on or off--not a shorthand}%
+ {This character is not a shorthand. Maybe you made\\%
+ a typing mistake? I will ignore your instruction}}%
+ {\ifcase#1%
+ \catcode`#212\relax
+ \or
+ \catcode`#2\active
+ \or
+ \csname bbl@oricat@\string#2\endcsname
+ \csname bbl@oridef@\string#2\endcsname
+ \fi}%
+ \bbl@afterfi\bbl@switch@sh#1%
+ \fi}
+\def\babelshorthand{\active@prefix\babelshorthand\bbl@putsh}
+\def\bbl@putsh#1{%
+ \bbl@ifunset{bbl@active@\string#1}%
+ {\bbl@putsh@i#1\@empty\@nnil}%
+ {\csname bbl@active@\string#1\endcsname}}
+\def\bbl@putsh@i#1#2\@nnil{%
+ \csname\languagename @sh@\string#1@%
+ \ifx\@empty#2\else\string#2@\fi\endcsname}
+\ifx\bbl@opt@shorthands\@nnil\else
+ \let\bbl@s@initiate@active@char\initiate@active@char
+ \def\initiate@active@char#1{%
+ \bbl@ifshorthand{#1}{\bbl@s@initiate@active@char{#1}}{}}
+ \let\bbl@s@switch@sh\bbl@switch@sh
+ \def\bbl@switch@sh#1#2{%
+ \ifx#2\@nnil\else
+ \bbl@afterfi
+ \bbl@ifshorthand{#2}{\bbl@s@switch@sh#1{#2}}{\bbl@switch@sh#1}%
+ \fi}
+ \let\bbl@s@activate\bbl@activate
+ \def\bbl@activate#1{%
+ \bbl@ifshorthand{#1}{\bbl@s@activate{#1}}{}}
+ \let\bbl@s@deactivate\bbl@deactivate
+ \def\bbl@deactivate#1{%
+ \bbl@ifshorthand{#1}{\bbl@s@deactivate{#1}}{}}
+\fi
+\newcommand\ifbabelshorthand[3]{\bbl@ifunset{bbl@active@\string#1}{#3}{#2}}
+\def\bbl@prim@s{%
+ \prime\futurelet\@let@token\bbl@pr@m@s}
+\def\bbl@if@primes#1#2{%
+ \ifx#1\@let@token
+ \expandafter\@firstoftwo
+ \else\ifx#2\@let@token
+ \bbl@afterelse\expandafter\@firstoftwo
+ \else
+ \bbl@afterfi\expandafter\@secondoftwo
+ \fi\fi}
+\begingroup
+ \catcode`\^=7 \catcode`\*=\active \lccode`\*=`\^
+ \catcode`\'=12 \catcode`\"=\active \lccode`\"=`\'
+ \lowercase{%
+ \gdef\bbl@pr@m@s{%
+ \bbl@if@primes"'%
+ \pr@@@s
+ {\bbl@if@primes*^\pr@@@t\egroup}}}
+\endgroup
+\initiate@active@char{~}
+\declare@shorthand{system}{~}{\leavevmode\nobreak\ }
+\bbl@activate{~}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 890 to 927 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@allowhyphens{\ifvmode\else\nobreak\hskip\z@skip\fi}
+\def\bbl@t@one{T1}
+\def\allowhyphens{\ifx\cf@encoding\bbl@t@one\else\bbl@allowhyphens\fi}
+\newcommand\babelnullhyphen{\char\hyphenchar\font}
+\def\babelhyphen{\active@prefix\babelhyphen\bbl@hyphen}
+\def\bbl@hyphen{%
+ \@ifstar{\bbl@hyphen@i @}{\bbl@hyphen@i\@empty}}
+\def\bbl@hyphen@i#1#2{%
+ \bbl@ifunset{bbl@hy@#1#2\@empty}%
+ {\csname bbl@#1usehyphen\endcsname{\discretionary{#2}{}{#2}}}%
+ {\csname bbl@hy@#1#2\@empty\endcsname}}
+\def\bbl@usehyphen#1{%
+ \leavevmode
+ \ifdim\lastskip>\z@\mbox{#1}\else\nobreak#1\fi
+ \nobreak\hskip\z@skip}
+\def\bbl@@usehyphen#1{%
+ \leavevmode\ifdim\lastskip>\z@\mbox{#1}\else#1\fi}
+\def\bbl@hyphenchar{%
+ \ifnum\hyphenchar\font=\m@ne
+ \babelnullhyphen
+ \else
+ \char\hyphenchar\font
+ \fi}
+\def\bbl@hy@soft{\bbl@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}}
+\def\bbl@hy@@soft{\bbl@@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}}
+\def\bbl@hy@hard{\bbl@usehyphen\bbl@hyphenchar}
+\def\bbl@hy@@hard{\bbl@@usehyphen\bbl@hyphenchar}
+\def\bbl@hy@nobreak{\bbl@usehyphen{\mbox{\bbl@hyphenchar}}}
+\def\bbl@hy@@nobreak{\mbox{\bbl@hyphenchar}}
+\def\bbl@hy@repeat{%
+ \bbl@usehyphen{%
+ \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}}
+\def\bbl@hy@@repeat{%
+ \bbl@@usehyphen{%
+ \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}}
+\def\bbl@hy@empty{\hskip\z@skip}
+\def\bbl@hy@@empty{\discretionary{}{}{}}
+\def\bbl@disc#1#2{\nobreak\discretionary{#2-}{}{#1}\bbl@allowhyphens}
+%
+% ------------------------------------------------------------------------------
+%
+% end of the code copied from babel files
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl@disc@german#1#2{%
+ \nobreak\discretionary{#2-}{}{#1}}
+% \end{macrocode}
+% \iffalse
+%</babelsh.def>
+%<*cal-util.def>
+% \fi
+% \clearpage
+%
+% \subsection{cal-util.def}
+% \begin{macrocode}
+%%%%%%%%%%%%% cal-util.def %%%%%%%%%%%%%%%%
+% Macros shared by hijrical and hebrewcal %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% the following is adapted from hebcal.sty in babel
+\def\@Remainder#1#2#3{%
+ #3 = #1% % c = a
+ \divide #3 by #2% % c = a/b
+ \multiply #3 by -#2% % c = -b(a/b)
+ \advance #3 by #1}% % c = a - b(a/b)
+\newif\if@Divisible
+\def\@CheckIfDivisible#1#2{%
+ {%
+ \countdef\tmpx=0% % temporary variable
+ \@Remainder{#1}{#2}{\tmpx}%
+ \ifnum\tmpx=0%
+ \global\@Divisibletrue%
+ \else%
+ \global\@Divisiblefalse%
+ \fi}}
+\newif\if@GregorianLeap
+\def\@CheckIfGregorianLeap#1{%
+ {%
+ \@CheckIfDivisible{#1}{4}%
+ \if@Divisible%
+ \@CheckIfDivisible{#1}{100}%
+ \if@Divisible%
+ \@CheckIfDivisible{#1}{400}%
+ \if@Divisible%
+ \global\@GregorianLeaptrue%
+ \else%
+ \global\@GregorianLeapfalse%
+ \fi%
+ \else%
+ \global\@GregorianLeaptrue%
+ \fi%
+ \else%
+ \global\@GregorianLeapfalse%
+ \fi%
+ }}
+%%
+
+\newcounter{tmpA}\newcounter{tmpB}
+\newcounter{tmpC}\newcounter{tmpD}
+\newcounter{tmpE}\newcounter{tmpF}
+
+
+%% This is an algorithm from Reingold & Dershowitz,
+%% Calendrical Calculations, The Millenium Edition
+%%
+\def\@FixedFromGregorian#1#2#3#4{%
+ \setcounter{tmpA}{(#1-1)*365}%
+ \setcounter{tmpB}{(#1-1)/4}%
+ \setcounter{tmpC}{(#1-1)/100}%
+ \setcounter{tmpD}{(#1-1)/400}%
+ \setcounter{tmpE}{(367*#2-362)/12}%
+ \ifnum#2<3%
+ \setcounter{tmpF}{0}%
+ \else%
+ \@CheckIfGregorianLeap{#1}%
+ \if@GregorianLeap%
+ \setcounter{tmpF}{-1}%
+ \else%
+ \setcounter{tmpF}{-2}%
+ \fi%
+ \fi%
+ \@ifundefined{c@#4}{\global\newcounter{#4}}{}%
+ \setcounter{#4}{\value{tmpA}+\value{tmpB}-\value{tmpC}+\value{tmpD}+\value{tmpE}+\value{tmpF}+#3}%
+}
+% \end{macrocode}
+% \iffalse
+%</cal-util.def>
+%<*xgreek-fixes.def>
+% \fi
+% \clearpage
+%
+% \subsection{xgreek-fixes.def}
+% \begin{macrocode}
+% the following fixes are taken verbatim from xgreek.sty:
+% \message{Package `xgreek' version 3.0.1 by Apostolos Syropoulos}
+\global\lccode"0370="0371 \global\uccode"0370="0370
+\global\lccode"0371="0371 \global\uccode"0371="0370
+\global\lccode"0372="0373 \global\uccode"0372="0372
+\global\lccode"0373="0373 \global\uccode"0373="0372
+\global\lccode"0376="0377 \global\uccode"0376="0376
+\global\lccode"0377="0377 \global\uccode"0377="0376
+\global\lccode"03FD="037B \global\uccode"03FD="03FD
+\global\lccode"037B="037B \global\uccode"037B="03FD
+\global\lccode"03FE="037C \global\uccode"03FE="03FE
+\global\lccode"037C="037C \global\uccode"037C="03FE
+\global\lccode"03FF="037D \global\uccode"03FF="03FF
+\global\lccode"037D="037D \global\uccode"037D="03FF
+\global\lccode"0386="03AC \global\uccode"0386="0391
+\global\lccode"0388="03AD \global\uccode"0388="0395
+\global\lccode"0389="03AC \global\uccode"0389="0397
+\global\lccode"038A="03AF \global\uccode"038A="0399
+\global\lccode"038C="03CC \global\uccode"038C="039F
+\global\lccode"038E="03CD \global\uccode"038E="03A5
+\global\lccode"038F="03CE \global\uccode"038F="03A9
+\global\lccode"0390="0390 \global\uccode"0390="03AA
+\global\lccode"0391="03B1 \global\uccode"0391="0391
+\global\lccode"0392="03B2 \global\uccode"0392="0392
+\global\lccode"0393="03B3 \global\uccode"0393="0393
+\global\lccode"0394="03B4 \global\uccode"0394="0394
+\global\lccode"0395="03B5 \global\uccode"0395="0395
+\global\lccode"0396="03B6 \global\uccode"0396="0396
+\global\lccode"0397="03B7 \global\uccode"0397="0397
+\global\lccode"0398="03B8 \global\uccode"0398="0398
+\global\lccode"0399="03B9 \global\uccode"0399="0399
+\global\lccode"039A="03BA \global\uccode"039A="039A
+\global\lccode"039B="03BB \global\uccode"039B="039B
+\global\lccode"039C="03BC \global\uccode"039C="039C
+\global\lccode"039D="03BD \global\uccode"039D="039D
+\global\lccode"039E="03BE \global\uccode"039E="039E
+\global\lccode"039F="03BF \global\uccode"039F="039F
+\global\lccode"03A0="03C0 \global\uccode"03A0="03A0
+\global\lccode"03A1="03C1 \global\uccode"03A1="03A1
+\global\lccode"03A3="03C3 \global\uccode"03A3="03A3
+\global\lccode"03A4="03C4 \global\uccode"03A4="03A4
+\global\lccode"03A5="03C5 \global\uccode"03A5="03A5
+\global\lccode"03A6="03C6 \global\uccode"03A6="03A6
+\global\lccode"03A7="03C7 \global\uccode"03A7="03A7
+\global\lccode"03A8="03C8 \global\uccode"03A8="03A8
+\global\lccode"03A9="03C9 \global\uccode"03A9="03A9
+\global\lccode"03AA="03CA \global\uccode"03AA="03AA
+\global\lccode"03AB="03CB \global\uccode"03AB="03AB
+\global\lccode"03AC="03AC \global\uccode"03AC="0391
+\global\lccode"03AD="03AD \global\uccode"03AD="0395
+\global\lccode"03AE="03AE \global\uccode"03AE="0397
+\global\lccode"03AF="03AF \global\uccode"03AF="0399
+\global\lccode"03B0="03B0 \global\uccode"03B0="03AB
+\global\lccode"03B1="03B1 \global\uccode"03B1="0391
+\global\lccode"03B2="03B2 \global\uccode"03B2="0392
+\global\lccode"03B3="03B3 \global\uccode"03B3="0393
+\global\lccode"03B4="03B4 \global\uccode"03B4="0394
+\global\lccode"03B5="03B5 \global\uccode"03B5="0395
+\global\lccode"03B6="03B6 \global\uccode"03B6="0396
+\global\lccode"03B7="03B7 \global\uccode"03B7="0397
+\global\lccode"03B8="03B8 \global\uccode"03B8="0398
+\global\lccode"03B9="03B9 \global\uccode"03B9="0399
+\global\lccode"03BA="03BA \global\uccode"03BA="039A
+\global\lccode"03BB="03BB \global\uccode"03BB="039B
+\global\lccode"03BC="03BC \global\uccode"03BC="039C
+\global\lccode"03BD="03BD \global\uccode"03BD="039D
+\global\lccode"03BE="03BE \global\uccode"03BE="039E
+\global\lccode"03BF="03BF \global\uccode"03BF="039F
+\global\lccode"03C0="03C0 \global\uccode"03C0="03A0
+\global\lccode"03C1="03C1 \global\uccode"03C1="03A1
+\global\lccode"03C2="03C2 \global\uccode"03C2="03A3
+\global\lccode"03C3="03C3 \global\uccode"03C3="03A3
+\global\lccode"03C4="03C4 \global\uccode"03C4="03A4
+\global\lccode"03C5="03C5 \global\uccode"03C5="03A5
+\global\lccode"03C6="03C6 \global\uccode"03C6="03A6
+\global\lccode"03C7="03C7 \global\uccode"03C7="03A7
+\global\lccode"03C8="03C8 \global\uccode"03C8="03A8
+\global\lccode"03C9="03C9 \global\uccode"03C9="03A9
+\global\lccode"03CA="03CA \global\uccode"03CA="03AA
+\global\lccode"03CB="03CB \global\uccode"03CB="03AB
+\global\lccode"03CC="03CC \global\uccode"03CC="039F
+\global\lccode"03CD="03CD \global\uccode"03CD="03A5
+\global\lccode"03CE="03CE \global\uccode"03CE="03A9
+\global\lccode"03D0="03D0 \global\uccode"03D0="0392
+\global\lccode"03D1="03D1 \global\uccode"03D1="0398
+\global\lccode"03D2="03C5 \global\uccode"03D2="03A5
+\global\lccode"03D3="03CD \global\uccode"03D3="03A5
+\global\lccode"03D4="03CB \global\uccode"03D4="03AB
+\global\lccode"03D5="03C6 \global\uccode"03D5="03A6
+\global\lccode"03D6="03C0 \global\uccode"03D6="03A0
+\global\lccode"03DA="03DB \global\uccode"03DA="03DA
+\global\lccode"03DB="03DB \global\uccode"03DB="03DA
+\global\lccode"03DC="03DD \global\uccode"03DC="03DC
+\global\lccode"03DD="03DD \global\uccode"03DD="03DC
+\global\lccode"03DE="03DF \global\uccode"03DE="03DE
+\global\lccode"03DF="03DF \global\uccode"03DF="03DE
+\global\lccode"03E0="03E1 \global\uccode"03E0="03E0
+\global\lccode"03E1="03E1 \global\uccode"03E1="03E0
+\global\lccode"03F0="03BA \global\uccode"03F0="039A
+\global\lccode"03F1="03C1 \global\uccode"03F1="03A1
+\global\lccode"03F2="03F2 \global\uccode"03F2="03F9
+\global\lccode"03F9="03F2 \global\uccode"03F9="03F9
+\global\lccode"1F00="1F00 \global\uccode"1F00="0391
+\global\lccode"1F01="1F01 \global\uccode"1F01="0391
+\global\lccode"1F02="1F02 \global\uccode"1F02="0391
+\global\lccode"1F03="1F03 \global\uccode"1F03="0391
+\global\lccode"1F04="1F04 \global\uccode"1F04="0391
+\global\lccode"1F05="1F05 \global\uccode"1F05="0391
+\global\lccode"1F06="1F06 \global\uccode"1F06="0391
+\global\lccode"1F07="1F07 \global\uccode"1F07="0391
+\global\lccode"1F08="1F00 \global\uccode"1F08="0391
+\global\lccode"1F09="1F01 \global\uccode"1F09="0391
+\global\lccode"1F0A="1F02 \global\uccode"1F0A="0391
+\global\lccode"1F0B="1F03 \global\uccode"1F0B="0391
+\global\lccode"1F0C="1F04 \global\uccode"1F0C="0391
+\global\lccode"1F0D="1F05 \global\uccode"1F0D="0391
+\global\lccode"1F0E="1F06 \global\uccode"1F0E="0391
+\global\lccode"1F0F="1F07 \global\uccode"1F0F="0391
+\global\lccode"1F10="1F10 \global\uccode"1F10="0395
+\global\lccode"1F11="1F11 \global\uccode"1F11="0395
+\global\lccode"1F12="1F12 \global\uccode"1F12="0395
+\global\lccode"1F13="1F13 \global\uccode"1F13="0395
+\global\lccode"1F14="1F14 \global\uccode"1F14="0395
+\global\lccode"1F15="1F15 \global\uccode"1F15="0395
+\global\lccode"1F18="1F10 \global\uccode"1F18="0395
+\global\lccode"1F19="1F11 \global\uccode"1F19="0395
+\global\lccode"1F1A="1F12 \global\uccode"1F1A="0395
+\global\lccode"1F1B="1F13 \global\uccode"1F1B="0395
+\global\lccode"1F1C="1F14 \global\uccode"1F1C="0395
+\global\lccode"1F1D="1F15 \global\uccode"1F1D="0395
+\global\lccode"1F20="1F20 \global\uccode"1F20="0397
+\global\lccode"1F21="1F21 \global\uccode"1F21="0397
+\global\lccode"1F22="1F22 \global\uccode"1F22="0397
+\global\lccode"1F23="1F23 \global\uccode"1F23="0397
+\global\lccode"1F24="1F24 \global\uccode"1F24="0397
+\global\lccode"1F25="1F25 \global\uccode"1F25="0397
+\global\lccode"1F26="1F26 \global\uccode"1F26="0397
+\global\lccode"1F27="1F27 \global\uccode"1F27="0397
+\global\lccode"1F28="1F20 \global\uccode"1F28="0397
+\global\lccode"1F29="1F21 \global\uccode"1F29="0397
+\global\lccode"1F2A="1F22 \global\uccode"1F2A="0397
+\global\lccode"1F2B="1F23 \global\uccode"1F2B="0397
+\global\lccode"1F2C="1F24 \global\uccode"1F2C="0397
+\global\lccode"1F2D="1F25 \global\uccode"1F2D="0397
+\global\lccode"1F2E="1F26 \global\uccode"1F2E="0397
+\global\lccode"1F2F="1F27 \global\uccode"1F2F="0397
+\global\lccode"1F30="1F30 \global\uccode"1F30="0399
+\global\lccode"1F31="1F31 \global\uccode"1F31="0399
+\global\lccode"1F32="1F32 \global\uccode"1F32="0399
+\global\lccode"1F33="1F33 \global\uccode"1F33="0399
+\global\lccode"1F34="1F34 \global\uccode"1F34="0399
+\global\lccode"1F35="1F35 \global\uccode"1F35="0399
+\global\lccode"1F36="1F36 \global\uccode"1F36="0399
+\global\lccode"1F37="1F37 \global\uccode"1F37="0399
+\global\lccode"1F38="1F30 \global\uccode"1F38="0399
+\global\lccode"1F39="1F31 \global\uccode"1F39="0399
+\global\lccode"1F3A="1F32 \global\uccode"1F3A="0399
+\global\lccode"1F3B="1F33 \global\uccode"1F3B="0399
+\global\lccode"1F3C="1F34 \global\uccode"1F3C="0399
+\global\lccode"1F3D="1F35 \global\uccode"1F3D="0399
+\global\lccode"1F3E="1F36 \global\uccode"1F3E="0399
+\global\lccode"1F3F="1F37 \global\uccode"1F3F="0399
+\global\lccode"1F40="1F40 \global\uccode"1F40="039F
+\global\lccode"1F41="1F41 \global\uccode"1F41="039F
+\global\lccode"1F42="1F42 \global\uccode"1F42="039F
+\global\lccode"1F43="1F43 \global\uccode"1F43="039F
+\global\lccode"1F44="1F44 \global\uccode"1F44="039F
+\global\lccode"1F45="1F45 \global\uccode"1F45="039F
+\global\lccode"1F48="1F40 \global\uccode"1F48="039F
+\global\lccode"1F49="1F41 \global\uccode"1F49="039F
+\global\lccode"1F4A="1F42 \global\uccode"1F4A="039F
+\global\lccode"1F4B="1F43 \global\uccode"1F4B="039F
+\global\lccode"1F4C="1F44 \global\uccode"1F4C="039F
+\global\lccode"1F4D="1F45 \global\uccode"1F4D="039F
+\global\lccode"1F50="1F50 \global\uccode"1F50="03A5
+\global\lccode"1F51="1F51 \global\uccode"1F51="03A5
+\global\lccode"1F52="1F52 \global\uccode"1F52="03A5
+\global\lccode"1F53="1F53 \global\uccode"1F53="03A5
+\global\lccode"1F54="1F54 \global\uccode"1F54="03A5
+\global\lccode"1F55="1F55 \global\uccode"1F55="03A5
+\global\lccode"1F56="1F56 \global\uccode"1F56="03A5
+\global\lccode"1F57="1F57 \global\uccode"1F57="03A5
+\global\lccode"1F59="1F51 \global\uccode"1F59="03A5
+\global\lccode"1F5B="1F53 \global\uccode"1F5B="03A5
+\global\lccode"1F5D="1F55 \global\uccode"1F5D="03A5
+\global\lccode"1F5F="1F57 \global\uccode"1F5F="03A5
+\global\lccode"1F60="1F60 \global\uccode"1F60="03A9
+\global\lccode"1F61="1F61 \global\uccode"1F61="03A9
+\global\lccode"1F62="1F62 \global\uccode"1F62="03A9
+\global\lccode"1F63="1F63 \global\uccode"1F63="03A9
+\global\lccode"1F64="1F64 \global\uccode"1F64="03A9
+\global\lccode"1F65="1F65 \global\uccode"1F65="03A9
+\global\lccode"1F66="1F66 \global\uccode"1F66="03A9
+\global\lccode"1F67="1F67 \global\uccode"1F67="03A9
+\global\lccode"1F68="1F60 \global\uccode"1F68="03A9
+\global\lccode"1F69="1F61 \global\uccode"1F69="03A9
+\global\lccode"1F6A="1F62 \global\uccode"1F6A="03A9
+\global\lccode"1F6B="1F63 \global\uccode"1F6B="03A9
+\global\lccode"1F6C="1F64 \global\uccode"1F6C="03A9
+\global\lccode"1F6D="1F65 \global\uccode"1F6D="03A9
+\global\lccode"1F6E="1F66 \global\uccode"1F6E="03A9
+\global\lccode"1F6F="1F67 \global\uccode"1F6F="03A9
+\global\lccode"1F70="1F70 \global\uccode"1F70="0391
+\global\lccode"1F71="1F71 \global\uccode"1F71="0391
+\global\lccode"1F72="1F72 \global\uccode"1F72="0395
+\global\lccode"1F73="1F73 \global\uccode"1F73="0395
+\global\lccode"1F74="1F74 \global\uccode"1F74="0397
+\global\lccode"1F75="1F75 \global\uccode"1F75="0397
+\global\lccode"1F76="1F76 \global\uccode"1F76="0399
+\global\lccode"1F77="1F77 \global\uccode"1F77="0399
+\global\lccode"1F78="1F78 \global\uccode"1F78="039F
+\global\lccode"1F79="1F79 \global\uccode"1F79="039F
+\global\lccode"1F7A="1F7A \global\uccode"1F7A="03A5
+\global\lccode"1F7B="1F7B \global\uccode"1F7B="03A5
+\global\lccode"1F7C="1F7C \global\uccode"1F7C="03A9
+\global\lccode"1F7D="1F7D \global\uccode"1F7D="03A9
+\global\lccode"1F80="1F80 \global\uccode"1F80="1FBC
+\global\lccode"1F81="1F81 \global\uccode"1F81="1FBC
+\global\lccode"1F82="1F82 \global\uccode"1F82="1FBC
+\global\lccode"1F83="1F83 \global\uccode"1F83="1FBC
+\global\lccode"1F84="1F84 \global\uccode"1F84="1FBC
+\global\lccode"1F85="1F85 \global\uccode"1F85="1FBC
+\global\lccode"1F86="1F86 \global\uccode"1F86="1FBC
+\global\lccode"1F87="1F87 \global\uccode"1F87="1FBC
+\global\lccode"1F88="1F80 \global\uccode"1F88="1FBC
+\global\lccode"1F89="1F81 \global\uccode"1F89="1FBC
+\global\lccode"1F8A="1F82 \global\uccode"1F8A="1FBC
+\global\lccode"1F8B="1F83 \global\uccode"1F8B="1FBC
+\global\lccode"1F8C="1F84 \global\uccode"1F8C="1FBC
+\global\lccode"1F8D="1F85 \global\uccode"1F8D="1FBC
+\global\lccode"1F8E="1F86 \global\uccode"1F8E="1FBC
+\global\lccode"1F8F="1F87 \global\uccode"1F8F="1FBC
+\global\lccode"1F90="1F90 \global\uccode"1F90="1FCC
+\global\lccode"1F91="1F91 \global\uccode"1F91="1FCC
+\global\lccode"1F92="1F92 \global\uccode"1F92="1FCC
+\global\lccode"1F93="1F93 \global\uccode"1F93="1FCC
+\global\lccode"1F94="1F94 \global\uccode"1F94="1FCC
+\global\lccode"1F95="1F95 \global\uccode"1F95="1FCC
+\global\lccode"1F96="1F96 \global\uccode"1F96="1FCC
+\global\lccode"1F97="1F97 \global\uccode"1F97="1FCC
+\global\lccode"1F98="1F90 \global\uccode"1F98="1FCC
+\global\lccode"1F99="1F91 \global\uccode"1F99="1FCC
+\global\lccode"1F9A="1F92 \global\uccode"1F9A="1FCC
+\global\lccode"1F9B="1F93 \global\uccode"1F9B="1FCC
+\global\lccode"1F9C="1F94 \global\uccode"1F9C="1FCC
+\global\lccode"1F9D="1F95 \global\uccode"1F9D="1FCC
+\global\lccode"1F9E="1F96 \global\uccode"1F9E="1FCC
+\global\lccode"1F9F="1F97 \global\uccode"1F9F="1FCC
+\global\lccode"1FA0="1FA0 \global\uccode"1FA0="1FFC
+\global\lccode"1FA1="1FA1 \global\uccode"1FA1="1FFC
+\global\lccode"1FA2="1FA2 \global\uccode"1FA2="1FFC
+\global\lccode"1FA3="1FA3 \global\uccode"1FA3="1FFC
+\global\lccode"1FA4="1FA4 \global\uccode"1FA4="1FFC
+\global\lccode"1FA5="1FA5 \global\uccode"1FA5="1FFC
+\global\lccode"1FA6="1FA6 \global\uccode"1FA6="1FFC
+\global\lccode"1FA7="1FA7 \global\uccode"1FA7="1FFC
+\global\lccode"1FA8="1FA0 \global\uccode"1FA8="1FFC
+\global\lccode"1FA9="1FA1 \global\uccode"1FA9="1FFC
+\global\lccode"1FAA="1FA2 \global\uccode"1FAA="1FFC
+\global\lccode"1FAB="1FA3 \global\uccode"1FAB="1FFC
+\global\lccode"1FAC="1FA4 \global\uccode"1FAC="1FFC
+\global\lccode"1FAD="1FA5 \global\uccode"1FAD="1FFC
+\global\lccode"1FAE="1FA6 \global\uccode"1FAE="1FFC
+\global\lccode"1FAF="1FA7 \global\uccode"1FAF="1FFC
+\global\lccode"1FB0="1FB0 \global\uccode"1FB0="1FB8
+\global\lccode"1FB1="1FB1 \global\uccode"1FB1="1FB9
+\global\lccode"1FB2="1FB2 \global\uccode"1FB2="1FBC
+\global\lccode"1FB3="1FB3 \global\uccode"1FB3="1FBC
+\global\lccode"1FB4="1FB4 \global\uccode"1FB4="1FBC
+\global\lccode"1FB6="1FB6 \global\uccode"1FB6="0391
+\global\lccode"1FB7="1FB7 \global\uccode"1FB7="1FBC
+\global\lccode"1FB8="1FB0 \global\uccode"1FB8="1FB8
+\global\lccode"1FB9="1FB1 \global\uccode"1FB9="1FB9
+\global\lccode"1FBA="1F70 \global\uccode"1FBA="0391
+\global\lccode"1FBB="1F71 \global\uccode"1FBB="0391
+\global\lccode"1FBC="1FB3 \global\uccode"1FBC="1FBC
+\global\lccode"1FBD="1FBD \global\uccode"1FBD="1FBD
+\global\lccode"1FC2="1FC2 \global\uccode"1FC2="1FCC
+\global\lccode"1FC3="1FC3 \global\uccode"1FC3="1FCC
+\global\lccode"1FC4="1FC4 \global\uccode"1FC4="1FCC
+\global\lccode"1FC6="1FC6 \global\uccode"1FC6="0397
+\global\lccode"1FC7="1FC7 \global\uccode"1FC7="1FCC
+\global\lccode"1FC8="1F72 \global\uccode"1FC8="0395
+\global\lccode"1FC9="1F73 \global\uccode"1FC9="0395
+\global\lccode"1FCA="1F74 \global\uccode"1FCA="0397
+\global\lccode"1FCB="1F75 \global\uccode"1FCB="0397
+\global\lccode"1FCC="1FC3 \global\uccode"1FCC="1FCC
+\global\lccode"1FD0="1FD0 \global\uccode"1FD0="1FD8
+\global\lccode"1FD1="1FD1 \global\uccode"1FD1="1FD9
+\global\lccode"1FD2="1FD2 \global\uccode"1FD2="03AA
+\global\lccode"1FD3="1FD3 \global\uccode"1FD3="03AA
+\global\lccode"1FD6="1FD6 \global\uccode"1FD6="0399
+\global\lccode"1FD7="1FD7 \global\uccode"1FD7="03AA
+\global\lccode"1FD8="1FD0 \global\uccode"1FD8="1FD8
+\global\lccode"1FD9="1FD1 \global\uccode"1FD9="1FD9
+\global\lccode"1FDA="1F76 \global\uccode"1FDA="0399
+\global\lccode"1FDB="1F77 \global\uccode"1FDB="0399
+\global\lccode"1FE0="1FE0 \global\uccode"1FE0="1FE8
+\global\lccode"1FE1="1FE1 \global\uccode"1FE1="1FE9
+\global\lccode"1FE2="1FE2 \global\uccode"1FE2="03AB
+\global\lccode"1FE3="1FE3 \global\uccode"1FE3="03AB
+\global\lccode"1FE4="1FE4 \global\uccode"1FE4="03A1
+\global\lccode"1FE5="1FE5 \global\uccode"1FE5="03A1
+\global\lccode"1FE6="1FE6 \global\uccode"1FE6="03A5
+\global\lccode"1FE7="1FE7 \global\uccode"1FE7="03AB
+\global\lccode"1FE8="1FE0 \global\uccode"1FE8="1FE8
+\global\lccode"1FE9="1FE1 \global\uccode"1FE9="1FE9
+\global\lccode"1FEA="1F7A \global\uccode"1FEA="03A5
+\global\lccode"1FEB="1F7B \global\uccode"1FEB="03A5
+\global\lccode"1FEC="1FE5 \global\uccode"1FEC="1FEC
+\global\lccode"1FF2="1FF2 \global\uccode"1FF2="1FFC
+\global\lccode"1FF3="1FF3 \global\uccode"1FF3="1FFC
+\global\lccode"1FF4="1FF4 \global\uccode"1FF4="1FFC
+\global\lccode"1FF6="1FF6 \global\uccode"1FF6="03A9
+\global\lccode"1FF7="1FF7 \global\uccode"1FF7="1FFC
+\global\lccode"1FF8="1F78 \global\uccode"1FF8="039F
+\global\lccode"1FF9="1F79 \global\uccode"1FF9="039F
+\global\lccode"1FFA="1F7C \global\uccode"1FFA="03A9
+\global\lccode"1FFB="1F7D \global\uccode"1FFB="03A9
+\global\lccode"1FFC="1FF3 \global\uccode"1FFC="1FFC
+% \end{macrocode}
+% \iffalse
+%</xgreek-fixes.def>
%<*gloss-acadien.ldf>
% \fi
% \clearpage
@@ -2697,7 +8367,7 @@ to track the issues and follow progress.
}
\def\noextras@afrikaans{%
- \noafrikaans@shorthands%
+ \ifafrikaans@babelshorthands\noafrikaans@shorthands\fi%
}
\def\blockextras@afrikaans{%
@@ -3152,12 +8822,6 @@ to track the issues and follow progress.
% \subsection{gloss-arabic.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-arabic.ldf}[polyglossia: module for arabic]
-\ifluatex
- \xpg@warning{Arabic is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
\RequireBidi
\RequirePackage{arabicnumbers}
\RequirePackage{hijrical}
@@ -3192,6 +8856,8 @@ and may look very wrong.}
\setlanguagealias*[locale=default]{arabic}{apd}
\setlanguagealias*[locale=mashriq]{arabic}{ar-PS}
+\define@boolkey{arabic}[arabic@]{abjadalph}[true]{}
+
\newif\ifeastern@numerals
\def\tmp@mashriq{mashriq}
\def\tmp@maghrib{maghrib}
@@ -3326,6 +8992,19 @@ and may look very wrong.}
\def\@ornatebracearabic#1{\RL{\char"FD3F\@arabic#1\char"FD3E}}
\def\@ornatebracealph#1{\RL{\char"FD3F\@alph#1\char"FD3E}}
+\def\abjadalph#1{\expandafter\arabic@abjad@alph{\number#1}}
+
+% This is a poor man's Arabic alphanumeric. It just uses the alphabet and
+% thus ends at 28.
+\def\arabic@abjad@alph#1{\ifcase#1%
+ \or ا\or ب\or\abjad@three\or د\or و\or ه‍\or ز%
+ \or ح\or ط\or ي\or ك\or ل\or م\or ن%
+ \or س\or ع\or ف\or ص\or ق\or ر\or ش%
+ \or ت\or ث\or خ\or ذ\or ض\or ظ\or غ%
+ \else\xpg@ill@value{#1}{arabic@abjad@alph}\fi%
+}
+
+
\def\abjadmaghribi#1{%
\ifnum#1>1999\xpg@ill@value{#1}{abjad}%
\else
@@ -3360,8 +9039,13 @@ and may look very wrong.}
\ifnum#1=\z@\fi\abj@maghribi@num@iii}
\def\arabic@numbers{%
+ \ifarabic@abjadalph
+ \let\@alph\abjadalph%
+ \let\@Alph\abjadalph%
+ \else
\let\@alph\abjad%
\let\@Alph\abjad%
+ \fi
}
\def\noarabic@numbers{%
@@ -3994,7 +9678,7 @@ and may look very wrong.}
\def\@Ccdash{\leavevmode
\nobreak\cyrdash\nobreak\hskip.35em\ignorespaces}%
\ifx\cyrdash\undefined
- \def\cyrdash{\hbox to.8em{--\hss--}}%
+ \def\cyrdash{\hbox to.8em{\textendash\hss\textendash}}%
\fi
\declare@shorthand{belarusian}{",}{\nobreak\hskip.2em\ignorespaces}%
}
@@ -4179,7 +9863,7 @@ and may look very wrong.}
\def\noextras@belarusian{%
\ifcyrillic@numerals\nobelarusian@numbers\fi%
- \nobelarusian@shorthands%
+ \ifbelarusian@babelshorthands\nobelarusian@shorthands\fi%
}
\def\blockextras@belarusian{%
@@ -4205,13 +9889,6 @@ and may look very wrong.}
\ProvidesFile{gloss-bengali.ldf}[polyglossia: module for bengali]
-\ifluatex
- \xpg@warning{Bengali is not supported with LuaTeX.\MessageBreak
- I will proceed with the compilation, but\MessageBreak
- the output is not guaranteed to be correct\MessageBreak
- and may look very wrong.}
-\fi
-
\RequirePackage{devanagaridigits}
\RequirePackage{bengalidigits}
@@ -4796,18 +10473,23 @@ and may look very wrong.}
\csname normal@char\string"\endcsname l%
\else
\leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
- \setbox0\hbox{l}\setbox1\hbox{l\/}%
+ \setbox0\hbox{l}%
\xpg@if@char@available{00B7}%
- {\setbox2\hbox{\char"00B7}}%
- {\setbox2\hbox{.}}%
- \advance\raiselldim by \the\fontdimen5\the\font
+ {\setbox2\hbox{\char"00B7}\setbox1\hbox{l}}%
+ {\setbox2\hbox{.}\setbox1\hbox{l\/}}%
+ \setbox3\hbox{.}%
+ \advance\raiselldim by \the\fontdimen5\the\font%
\advance\raiselldim by -\ht2%
\leftllkern=-.25\wd0%
\advance\leftllkern by \wd1%
\advance\leftllkern by -\wd0%
+ \advance\leftllkern by -0.5\wd2%
+ \advance\leftllkern by 0.5\wd3%
\rightllkern=-.25\wd0%
\advance\rightllkern by -\wd1%
\advance\rightllkern by \wd0%
+ \advance\rightllkern by -0.5\wd2%
+ \advance\rightllkern by 0.5\wd3%
\allowhyphens\discretionary{l-}{l}%
{\hbox{l}\kern\leftllkern\xpg@raiseddot%
\kern\rightllkern\hbox{l}}\allowhyphens
@@ -4819,19 +10501,24 @@ and may look very wrong.}
\csname normal@char\string"\endcsname L%
\else
\leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
- \setbox0\hbox{L}\setbox1\hbox{L\/}%
+ \setbox0\hbox{L}%
\xpg@if@char@available{00B7}%
- {\setbox2\hbox{\char"00B7}}%
- {\setbox2\hbox{.}}%
+ {\setbox2\hbox{\char"00B7}\setbox1\hbox{L}}%
+ {\setbox2\hbox{.}\setbox1\hbox{L\/}}%
+ \setbox3\hbox{.}%
\advance\raiselldim by .5\ht0%
\advance\raiselldim by -.5\ht2%
\leftllkern=-.125\wd0%
\advance\leftllkern by \wd1%
\advance\leftllkern by -\wd0%
+ \advance\leftllkern by -0.5\wd2%
+ \advance\leftllkern by 0.5\wd3%
\rightllkern=-\wd0%
\divide\rightllkern by 6%
\advance\rightllkern by -\wd1%
\advance\rightllkern by \wd0%
+ \advance\rightllkern by -0.5\wd2%
+ \advance\rightllkern by 0.5\wd3%
\allowhyphens\discretionary{L-}{L}%
{\hbox{L}\kern\leftllkern\xpg@raiseddot%
\kern\rightllkern\hbox{L}}\allowhyphens
@@ -4889,7 +10576,7 @@ and may look very wrong.}
\space de~\number\year}}
\def\noextras@catalan{%
- \nocatalan@shorthands%
+ \ifcatalan@babelshorthands\nocatalan@shorthands\fi%
}
\def\blockextras@catalan{%
@@ -5184,7 +10871,7 @@ and may look very wrong.}
}
\def\noextras@croatian{%
- \nocroatian@shorthands%
+ \ifcroatian@babelshorthands\nocroatian@shorthands\fi%
}
\def\blockextras@croatian{%
@@ -5313,7 +11000,7 @@ and may look very wrong.}
\chardef\czech@boundary=4095 %
\def\newXeTeXintercharclass{%
\e@alloc\XeTeXcharclass\chardef
- \xe@alloc@intercharclass\m@ne\@ucharclass@boundary}
+ \xe@alloc@intercharclass\m@ne\@ucharclass@boundary}%
\else
\chardef\czech@boundary=255
\fi
@@ -5342,6 +11029,24 @@ and may look very wrong.}
% Add nonbreakable space after single-letter word to
% prevent them to land at the end of a line
+% vlna code taken and adapted from xevlna.sty
+\ifxetex
+ \def\czech@nointerchartoks{\let\czech@interchartoks\czech@PreCSpreposition}%
+ \def\czech@PreCSpreposition{%
+ \def\next{}%
+ \ifnum\catcode`\ =10 % nothing will be done in verbatim
+ \ifmmode % nothing in math
+ \else
+ \let\czech@interchartoks\czech@nointerchartoks
+ \let\next\czech@ExamineCSpreposition
+ \fi\fi
+ \next%
+ }%
+ \def\czech@ExamineCSpreposition #1{#1\futurelet\next\czech@ProcessCSpreposition}%
+ \def\czech@ProcessCSpreposition{\ifx\next\czech@XeTeXspace\nobreak\fi}%
+ \futurelet\czech@XeTeXspace{ }\czech@nointerchartoks
+\fi
+
\def\czech@vlna{%
\ifluatex
\preventsingleon
@@ -5368,21 +11073,8 @@ and may look very wrong.}
\XeTeXcharclass `\a \czech@nonsyllabicpreposition
\XeTeXcharclass `\I \czech@nonsyllabicpreposition
\XeTeXcharclass `\i \czech@nonsyllabicpreposition
- \XeTeXinterchartoks \czech@boundary \czech@nonsyllabicpreposition {\czech@interchartoks}
- \XeTeXinterchartoks \czech@openpunctuation \czech@nonsyllabicpreposition {\czech@interchartoks}
- \def\czech@nointerchartoks{\let\czech@interchartoks\czech@PreCSpreposition}
- \def\czech@PreCSpreposition{\def\next{}%
- \ifnum\catcode`\ =10 % nothing will be done in verbatim
- \ifmmode % nothing in math
- \else
- \let\czech@interchartoks\czech@nointerchartoks
- \let\next\czech@ExamineCSpreposition
- \fi \fi
- \next%
- }
- \def\czech@ExamineCSpreposition ##1{##1\futurelet\next\czech@ProcessCSpreposition}
- \def\czech@ProcessCSpreposition{\ifx\next\czech@XeTeXspace\nobreak\fi}
- \futurelet\czech@XeTeXspace{ }\czech@nointerchartoks
+ \XeTeXinterchartoks \czech@boundary \czech@nonsyllabicpreposition {\czech@interchartoks}%
+ \XeTeXinterchartoks \czech@openpunctuation \czech@nonsyllabicpreposition {\czech@interchartoks}%
\fi
}
@@ -5448,7 +11140,7 @@ and may look very wrong.}
}
\def\noextras@czech{%
- \noczech@shorthands%
+ \ifczech@babelshorthands\noczech@shorthands\fi%
\noczech@hyphens%
\noczech@vlna%
\ifxetex\XeTeXinterchartokenstate=0\fi%
@@ -5526,11 +11218,12 @@ and may look very wrong.}
\def\proofname{Bevis}%
\def\glossaryname{Gloseliste}%
}
+
\def\datedanish{%
\def\today{\number\day.~\ifcase\month\or
januar\or februar\or marts\or april\or maj\or juni\or
juli\or august\or september\or oktober\or november\or december\fi
- \space\number\year}
+ \space\number\year}%
}
% \end{macrocode}
@@ -5843,12 +11536,7 @@ and may look very wrong.}
% \subsection{gloss-divehi.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-divehi.ldf}[polyglossia: module for divehi]
-\ifluatex
- \xpg@warning{Divehi is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequireBidi
\PolyglossiaSetup{divehi}{
bcp47=dv,
@@ -6006,7 +11694,7 @@ and may look very wrong.}
}
\def\noextras@dutch{%
- \nodutch@shorthands%
+ \ifdutch@babelshorthands\nodutch@shorthands\fi%
}
\def\blockextras@dutch{%
@@ -6721,7 +12409,7 @@ and may look very wrong.}
\space\number\year}}
\def\noextras@finnish{%
- \nofinnish@shorthands%
+ \iffinnish@babelshorthands\nofinnish@shorthands\fi%
}
\def\blockextras@finnish{%
@@ -7604,7 +13292,7 @@ and may look very wrong.}
\def\@Ccdash{\leavevmode
\nobreak\cyrdash\nobreak\hskip.35em\ignorespaces}%
\ifx\cyrdash\undefined
- \def\cyrdash{\hbox to.8em{--\hss--}}%
+ \def\cyrdash{\hbox to.8em{\textendash\hss\textendash}}%
\fi
\declare@shorthand{georgian}{",}{\nobreak\hskip.2em\ignorespaces}%
}
@@ -7749,7 +13437,7 @@ and may look very wrong.}
\def\noextras@georgian{%
\ifgeorgian@numerals\nogeorgian@numbers\fi%
- \nogeorgian@shorthands%
+ \ifgeorgian@babelshorthands\nogeorgian@shorthands\fi%
}
\def\blockextras@georgian{%
@@ -7970,14 +13658,14 @@ and may look very wrong.}
\declare@shorthand{german}{"R}{\textormath{\bbl@disc@german R{RR}}{R}}%
\declare@shorthand{german}{"t}{\textormath{\bbl@disc@german t{tt}}{t}}%
\declare@shorthand{german}{"T}{\textormath{\bbl@disc@german T{TT}}{T}}%
- \declare@shorthand{german}{"f}{\textormath{\bbl@discff}{f}}%
+ \declare@shorthand{german}{"f}{\texorpdfstring{\textormath{\bbl@discff}{f}}{f}}%
\def\bbl@discff{\penalty\@M
- \afterassignment\bbl@insertff \let\bbl@nextff= }%
+ \afterassignment\bbl@insertff \cslet{bbl@nextff}{ }}%
\def\bbl@insertff{%
\if f\bbl@nextff
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\relax\discretionary{ff-}{f}{ff}\allowhyphens}{f\bbl@nextff}}%
- \let\bbl@nextff=f%
+ \cslet{bbl@nextff}{f}%
\declare@shorthand{german}{"-}{\nobreak\-\nobreak\hskip\z@skip}%
\declare@shorthand{german}{"|}{\textormath{\penalty\@M\discretionary{-}{}{\kern.03em}}{}}%
\declare@shorthand{german}{""}{\hskip\z@skip}%
@@ -8082,15 +13770,15 @@ and may look very wrong.}
}
\def\noextras@german{%
- \nogerman@shorthands%
+ \ifgerman@babelshorthands\nogerman@shorthands\fi%
}
\def\blockextras@german{%
- \ifgerman@babelshorthands\german@shorthands\fi
+ \ifgerman@babelshorthands\german@shorthands\fi%
}
\def\inlineextras@german{%
- \ifgerman@babelshorthands\german@shorthands\fi
+ \ifgerman@babelshorthands\german@shorthands\fi%
}
% \end{macrocode}
@@ -8579,12 +14267,7 @@ and may look very wrong.}
% \subsection{gloss-hebrew.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-hebrew.ldf}[polyglossia: module for hebrew]
-\ifluatex
- \xpg@warning{Hebrew is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequireBidi
\RequirePackage{hebrewcal}
@@ -8691,23 +14374,23 @@ and may look very wrong.}
\fi
}
-% Bidi inserts an RTL mark (0x200f) before any number, forcing numbers to
-% RTL. Hebrew uses LTR numbers, though. So we insert an LTR mark to revert
-% the directionality
\ifxetex
- \newcommand\xpg@hebrew@DigitsDotDashInterCharToks{\ifbool{@nonlatin}{\char"200E }{}}
+ \let\xpg@orig@DigitsDotDashInterCharToks\DigitsDotDashInterCharToks%
\fi
\def\hebrew@ltr@numbers{%
\ifxetex
- \XeTeXinterchartoks \bidi@sepmark@charclass \bidi@digits@charclass = {\xpg@hebrew@DigitsDotDashInterCharToks}%
+ % Bidi inserts an RTL mark (0x200f) between number and number separator (- .),
+ % forcing numbers to RTL. This is wrong for Hebrew.
+ % So we defunc the respective command.
+ \renewcommand*{\DigitsDotDashInterCharToks}{}
\fi%
}
\def\nohebrew@ltr@numbers{%
\ifxetex
- % This is bidi's original intervention
- \XeTeXinterchartoks \bidi@sepmark@charclass \bidi@digits@charclass = {\DigitsDotDashInterCharToks}%
+ % Restore bidi's \DigitsDotDashInterCharToks
+ \let\DigitsDotDashInterCharToks\xpg@orig@DigitsDotDashInterCharToks%
\fi%
}
@@ -8852,7 +14535,7 @@ and may look very wrong.}
\def\listfigurename{चित्रों की सूची}%
\def\listtablename{तालिकाओं की सूची}%
\def\pagename{पृष्ठ}%
- \def\partname{खणड}%
+ \def\partname{खण्ड}%
\def\prefacename{प्रस्तावना}% प्राक्कथन
\def\refname{हवाले}%
\def\tablename{तालिका}%
@@ -9572,21 +15255,21 @@ and may look very wrong.}
\def\noextras@italian{%
- \lccode\string"2019=\z@
- \noitalian@shorthands
- \xpgit@savedvalues
+ \lccode\string"2019=\z@%
+ \ifitalian@babelshorthands\noitalian@shorthands\fi%
+ \xpgit@savedvalues%
}
\def\blockextras@italian{%
- \lccode\string"2019=\string"2019
- \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
- \finalhyphendemerits=50000000
- \ifitalian@babelshorthands\italian@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+ \finalhyphendemerits=50000000%
+ \ifitalian@babelshorthands\italian@shorthands\fi%
}
\def\inlineextras@italian{%
- \lccode\string"2019=\string"2019
- \ifitalian@babelshorthands\italian@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \ifitalian@babelshorthands\italian@shorthands\fi%
}
%%% CHANGES END %%%
% \end{macrocode}
@@ -9880,12 +15563,7 @@ and may look very wrong.}
%
% This work consists of the file gloss-kannada.ldf
\ProvidesFile{gloss-kannada.ldf}[polyglossia: module for kannada]
-\ifluatex
- \xpg@warning{Kannada is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\PolyglossiaSetup{kannada}{
bcp47=kn,
script=Kannada,
@@ -10720,7 +16398,9 @@ and may look very wrong.}
% \subsection{gloss-kurdish.ldf}
% \begin{macrocode}
% Created on September 1, 2019
-% Sina Ahmadi (https://sinaahmadi.github.io/)
+% Last updated on May 17, 2020
+% Sina Ahmadi (ahmadi.sina@outlook.com)
+% For more information, visit the Kurdish XeLaTeX Users Group at https://github.com/KurdishXeLaTeX
\ProvidesFile{gloss-kurdish.ldf}[polyglossia: module for Kurdish]
\RequireBidi
@@ -10848,7 +16528,6 @@ and may look very wrong.}
\define@key{kurdish}{locale}[default]{%
\def\@kurdish@locale{#1}}
-
%TODO add option for CALENDAR
% Register default options
@@ -10859,9 +16538,9 @@ and may look very wrong.}
}%
\def\kurdishNativemonth#1{\ifcase#1%
- \or رێبه‌ندان\or ره‌شه‌مێ\or خاكه‌لێوه‌\or گوڵان\or جۆزه‌ردان\or پووشپه‌ڕ\or خه‌رمانان\or گه‌لاوێژ\or ره‌زبه‌ر\or گه‌ڵارێزان\or سه‌رماوه‌ز\or به‌فرانبار\fi}
+ \or رێبەندان\or رەشەمێ\or خاكەلێوە\or گوڵان\or جۆزەردان\or پووشپەڕ\or خەرمانان\or گەلاوێژ\or رەزبەر\or گەڵارێزان\or سەرماوەز\or بەفرانبار\fi}
\def\kurdishmonth#1{\ifcase#1%
- \or کانونی دووەم\or شوبات\or ئازار\or نیسان\or ئایار\or حوزه‌یران\or ته‌ممووز\or ئاب\or ئه‌یلوول\or تشرینی یه‌كه‌م\or تشرینی دووهه‌م\or كانوونی یه‌كه‌م\fi}
+ \or كانوونی دووهەم\or شوبات\or ئازار\or نیسان\or ئایار\or حوزەیران\or تەممووز\or ئاب\or ئەیلوول\or تشرینی یەكەم\or تشرینی دووهەم\or كانوونی یەكەم\fi}
%\Hijritoday is now locale-aware and will format the date with this macro:
\DefineFormatHijriDate{kurdish}{%
@@ -10871,27 +16550,27 @@ and may look very wrong.}
}
\def\captionskurdish@sorani@arabic{%
- \def\prefacename{\@ensure@RTL{پێشه‌كی}}%
- \def\refname{\@ensure@RTL{سه‌رچاوه‌کان}}%
- \def\abstractname{\@ensure@RTL{پوخته‌}}%
- \def\bibname{\@ensure@RTL{کتێبنامه‌}}%
- \def\chaptername{\@ensure@RTL{به‌ندی}}%
+ \def\prefacename{\@ensure@RTL{پێشەكی}}%
+ \def\refname{\@ensure@RTL{سەرچاوەکان}}%
+ \def\abstractname{\@ensure@RTL{پوختە}}%
+ \def\bibname{\@ensure@RTL{کتێبنامە}}%
+ \def\chaptername{\@ensure@RTL{بەندی}}%
\def\appendixname{\@ensure@RTL{پاشکۆ}}%
- \def\contentsname{\@ensure@RTL{نێوه‌ڕۆک}}%
- \def\listfigurename{\@ensure@RTL{لیستی وێنه‌کان}}%
- \def\listtablename{\@ensure@RTL{لیستی خشته‌کان}}%
+ \def\contentsname{\@ensure@RTL{نێوەڕۆک}}%
+ \def\listfigurename{\@ensure@RTL{لیستی وێنەکان}}%
+ \def\listtablename{\@ensure@RTL{لیستی خشتەکان}}%
\def\indexname{\@ensure@RTL{پێنوێن}}%
- \def\figurename{\@ensure@RTL{وێنه‌}}%
- \def\tablename{\@ensure@RTL{خشتە}}%
- \def\partname{\@ensure@RTL{به‌شی}}%
+ \def\figurename{\@ensure@RTL{وێنەی}}%
+ \def\tablename{\@ensure@RTL{خشتەی}}%
+ \def\partname{\@ensure@RTL{بەشی}}%
\def\enclname{\@ensure@RTL{هاوپێچ}}%
- \def\ccname{\@ensure@RTL{روونووس}}%
+ \def\ccname{\@ensure@RTL{ڕوونووس}}%
\def\headtoname{\@ensure@RTL{بۆ}}%
- \def\pagename{\@ensure@RTL{لاپه‌ڕه‌}}%
- \def\seename{\@ensure@RTL{چاو لێکه‌ن}}%
- \def\alsoname{\@ensure@RTL{هه‌روه‌ها چاو لێکه‌ن}}%
+ \def\pagename{\@ensure@RTL{لاپەڕە}}%
+ \def\seename{\@ensure@RTL{چاو لێکەن}}%
+ \def\alsoname{\@ensure@RTL{هەروەها چاو لێکەن}}%
\def\proofname{\@ensure@RTL{سەلماندن}}%
- \def\glossaryname{\@ensure@RTL{فه‌رهه‌نگۆک}}%
+ \def\glossaryname{\@ensure@RTL{فەرهەنگۆک}}%
}
\def\captionskurdish@sorani@latin{%
@@ -10901,17 +16580,17 @@ and may look very wrong.}
\def\bibname{Kitêbname}%
\def\chaptername{Bendî}%
\def\appendixname{Paşko}%
- \def\contentsname{Nêwerrok}%
+ \def\contentsname{Nêweřok}%
\def\listfigurename{Lîstî Wênekan}%
\def\listtablename{Lîstî Xiştekan}%
- \def\indexname{Pêrrist}%
+ \def\indexname{Pêřist}%
\def\figurename{Wêney}%
\def\tablename{Xiştey}%
\def\partname{Beşî}%
\def\enclname{Hawpêç}%
- \def\ccname{Rûnûs}%
+ \def\ccname{Řûnûs}%
\def\headtoname{Bo}%
- \def\pagename{Laperre}%
+ \def\pagename{Lapeře}%
\def\seename{Çaw lêken}%
\def\alsoname{Herweha çaw lêken}%
\def\proofname{Selmandin}%
@@ -10920,7 +16599,7 @@ and may look very wrong.}
\def\captionskurdish@kurmanji@latin{%
\def\prefacename{Peşgotin}%
- \def\refname{Pirtuken bijartî}%
+ \def\refname{Jêder}%
\def\abstractname{Kurtebîr}%
\def\bibname{Çavkanîya Pirtukan}%
\def\chaptername{Serê}%
@@ -10937,14 +16616,14 @@ and may look very wrong.}
\def\headtoname{Ji bo}%
\def\pagename{Rûpelê}%
\def\seename{binêra}%
- \def\alsoname{le vêya ji binêra}%
+ \def\alsoname{li vêya jî binêra}%
\def\proofname{Delîl}%
\def\glossaryname{Çavkanîya lêkolînê}%
}
\def\captionskurdish@kurmanji@arabic{%
\def\prefacename{\@ensure@RTL{پێشگۆتن}}%
- \def\refname{\@ensure@RTL{پرتووکێن بژارتی}}%
+ \def\refname{\@ensure@RTL{ژێدەر}}%
\def\abstractname{\@ensure@RTL{کورتەبیر}}%
\def\bibname{\@ensure@RTL{چاڤکانییا پرتووکان}}%
\def\chaptername{\@ensure@RTL{سەرێ}}%
@@ -10976,17 +16655,17 @@ and may look very wrong.}
\def\datekurdish@sorani@latin{%
\def\today{%
- \number\day.~\ifcase\month\or
+ \number\day ~\ifcase\month\or
\januaryname\or \februaryname\or \marchname\or \aprilname\or
\mayname\or \junename\or \julyname\or \augustname\or
\septembername\or \octobername\or \novembername\or
\decembername\or \@ctrerr\fi~\number\year}%
\def\ontoday{%
- \number\day’ê~\ifcase\month\or
+ \number\day î~\ifcase\month\or
\januaryname\or \februaryname\or \marchname\or \aprilname\or
\mayname\or \junename\or \julyname\or \augustname\or
\septembername\or \octobername\or \novembername\or
- \decembername\or \@ctrerr\fi ê~\number\year}%
+ \decembername\or \@ctrerr\fi î~\number\year}%
\def\januaryname{Kanûnî Yekem}%
\def\februaryname{Şubat}%
\def\marchname{Azar}%
@@ -11003,13 +16682,13 @@ and may look very wrong.}
\def\datekurdish@kurmanji@latin{%
\def\today{%
- \number\day.~\ifcase\month\or
+ \number\day ~\ifcase\month\or
\januaryname\or \februaryname\or \marchname\or \aprilname\or
\mayname\or \junename\or \julyname\or \augustname\or
\septembername\or \octobername\or \novembername\or
\decembername\or \@ctrerr\fi~\number\year}%
\def\ontoday{%
- \number\day’ê~\ifcase\month\or
+ \number\day ê~\ifcase\month\or
\januaryname\or \februaryname\or \marchname\or \aprilname\or
\mayname\or \junename\or \julyname\or \augustname\or
\septembername\or \octobername\or \novembername\or
@@ -11028,8 +16707,11 @@ and may look very wrong.}
\def\decembername{Çileya Pêşîn}%
}
+\def\kurdishmonthkurmanji#1{\ifcase#1%
+ چلەیا پاشین \or شبات \or ئادار \or نیسان \or گولان \or حەزیران \or تیرمەهـ \or تەباخ \or ئیلۆن \or چریا پێشین \or چریا پاشین \or چلەیا پێشین\fi}
+
\def\datekurdish@kurmanji@arabic{%
- \datekurdish@sorani@arabic% FIXME: correct?
+ \def\today{\@ensure@RTL{\kurdishnumber\day\space\kurdishmonthkurmanji{\month}\space\kurdishnumber\year}}%
}
% TODO: babel-kurmanji has these "alternative" month names
@@ -11193,12 +16875,7 @@ and may look very wrong.}
% \subsection{gloss-lao.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-lao.ldf}[polyglossia: module for Lao]
-\ifluatex
- \xpg@warning{Lao is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\PolyglossiaSetup{lao}{
bcp47=lo,
script=Lao,
@@ -11972,7 +17649,7 @@ and may look very wrong.}
% prosodic shorthand environment.
% The active ' character may cause problems with the unicode-math package
% (in case Latin is used as a secondary language, see #394). We have to
-% turn it of if Latin is not the main language.
+% turn it off if Latin is not the main language.
\protected@write \@auxout { } { \shorthandoff {=} } % for the aux file
@@ -12932,12 +18609,7 @@ and may look very wrong.}
% \subsection{gloss-malayalam.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-malayalam.ldf}[polyglossia: module for malayalam]
-\ifluatex
- \xpg@warning{Malayalam is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
% Translations provided by Kevin & Siji, 01-11-2009
\PolyglossiaSetup{malayalam}{
@@ -13007,12 +18679,7 @@ and may look very wrong.}
% TODO implement Hindu calendar (not used in day-to-day practice)
\ProvidesFile{gloss-marathi.ldf}[polyglossia: module for marathi]
-\ifluatex
- \xpg@warning{Marathi is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequirePackage{devanagaridigits}
\PolyglossiaSetup{marathi}{
@@ -13066,7 +18733,7 @@ and may look very wrong.}
\def\appendixname{परिशिष्ट}%
\def\contentsname{अनुक्रमणिका}%
\def\listfigurename{आकृत्यांची सूची}%
- \def\listtablename{कोष्टक सूची}%
+ \def\listtablename{कोष्टकसूची}%
\def\indexname{सूची}%
\def\figurename{आकृती}%
\def\tablename{कोष्टक}%
@@ -13075,10 +18742,10 @@ and may look very wrong.}
\def\seename{पाहा}%
\def\alsoname{हेदेखील पाहा}%
\def\enclname{समाविष्ट}%
- \def\ccname{सी.सी.}%
+ \def\ccname{प्रत}%
\def\headtoname{प्रति}%
\def\proofname{सिद्धता}%
- \def\glossaryname{संक्षेपसूची}%
+ \def\glossaryname{संज्ञांची सूची}%
\def\authorsand{आणि}%
}
@@ -13104,23 +18771,23 @@ and may look very wrong.}
}%
}
-\def\devanagari@akshar#1{\ifcase#1\or अ\or आ\or इ\or ई\or उ\or ऊ\or ए\or ऐ\or ओ\or औ\or अं\or अः\else\@ctrerr\fi}
+\def\devanagari@akshar#1{\ifcase#1\or अ\or आ\or इ\or ई\or उ\or ऊ\or ऋ\or ऌ\or ए\or ॲ\or ऐ\or ओ\or ऑ\or औ\or अं\or अः\else\@ctrerr\fi}
\def\devanagari@alph#1{%
\ifcase#1\or क\or ख\or ग\or घ\or ङ\or च\or छ\or ज\or झ\or ञ\or ट\or ठ\or ड\or ढ\or ण\or त\or थ\or द%
- \or ध\or न\or प\or फ\or ब\or भ\or म\or य\or र\or ल\or व\or श\or ष\or स\or ह\or ळ\else\@ctrerr%
+ \or ध\or न\or प\or फ\or ब\or भ\or म\or य\or र\or ल\or व\or श\or ष\or स\or ह\or ळ\or क्ष \or ज्ञ \else\@ctrerr%
\fi%
}
\def\devanagari@letter#1{%
\ifcase#1\or एक\or दोन\or तीन\or चार\or पाच\or सहा\or सात\or आठ\or नऊ\or दहा\or अकरा\or बारा\or तेरा\or चौदा%
- \or पंधरा\or सोळा\or सतरा\or अठरा\or एकोणीस\or वीसएकवीस\or बावीस\or तेवीस\or चोवीस\or पंचवीस\or सव्वीस\or सत्तावीस\or अठाव्वीस%
- \or एकोणतीस\or तीस\or एकतीस\or बत्तीस\or तेहेत्तीस \or चौतीस \or पस्तीस \or छत्तीस \or सतदिस \or अडतीस \or एकोणचाळीस \or चाळीस %
- \or एक्केचाळीस \or बेचाळीस \or त्रेचाळीस \or चौवेचाळीस\or पंचेचाळीस \or सेहेचाळीस \or सत्तेचाळीस \or अठ्ठेचाळीस \or एकोणपन्नास \or पन्नास %
- \or एक्कावन्न \or बावन्न \or त्रेपन्न \or चोपन्न \or पंचावन्न \or छपन्न\or सत्तावन्न \or अठ्ठावन्न \or एकोणसाठ \or साठ \or एकसष्ठ \or बासष्ठ \or त्रेसष्ट %
- \or चौसष्ठ \or पासष्ठ \or सहासष्ठ \or सदुष्ठ \or अडुसष्ठ \or एकोणसत्तर\or सत्तर \or एकाहत्तर \or बहात्तर \or त्र्याहत्तर \or चौऱ्याहत्तर \or पंच्याहत्तर %
- \or शहात्तर \or सत्याहत्तर \or अठ्याहत्तर \or एकोणऐशी \or ऐंशी\or एक्याऐंशी \or ब्याऐंशी \or त्र्याऐंशी \or चौऱ्याऐंशी \or पंच्याऐंशी \or शह्यांशी \or सत्यांऐंशी %
- \or अठ्ठ्याऐंशी \or एकोणनव्वद \or नव्वद \or एक्याण्णव\or ब्याण्णव \or त्र्याण्णव \or चौऱ्याण्णव \or पंच्याण्णव \or शहाण्णव \or सत्याण्णव \or अठ्याण्णव %
+ \or पंधरा\or सोळा\or सतरा\or अठरा\or एकोणीस\or वीस\or एकवीस\or बावीस\or तेवीस\or चोवीस\or पंचवीस\or सव्वीस\or सत्तावीस\or अठ्ठावीस%
+ \or एकोणतीस\or तीस\or एकतीस\or बत्तीस\or तेहतीस \or चौतीस \or पस्तीस \or छत्तीस \or सदतीस \or अडतीस \or एकोणचाळीस \or चाळीस %
+ \or एकेचाळीस \or बेचाळीस \or त्रेचाळीस \or चव्वेचाळीस \or पंचेचाळीस \or शेहेचाळीस \or सत्तेचाळीस \or अठ्ठेचाळीस \or एकोणपन्नास \or पन्नास %
+ \or एकावन्न \or बावन्न \or त्रेपन्न \or चौपन्न \or पंचावन्न \or छप्पन्न\or सत्तावन्न \or अठ्ठावन्न \or एकोणसाठ \or साठ \or एकसष्ट \or बासष्ट \or त्रेसष्ट %
+ \or चौसष्ट \or पासष्ट \or सहासष्ट \or सदुष्ट \or अडुसष्ट \or एकोणसत्तर\or सत्तर \or एकाहत्तर \or बाहत्तर \or त्र्याहत्तर \or चौऱ्याहत्तर \or पंचाहत्तर %
+ \or शाहत्तर \or सत्त्याहत्तर \or अठ्ठ्याहत्तर \or एकोणऐंशी \or ऐंशी\or एक्याऐंशी \or ब्याऐंशी \or त्र्याऐंशी \or चौऱ्याऐंशी \or पंच्याऐंशी \or श्याऐंशी \or सत्त्याऐंशी %
+ \or अठ्ठ्याऐंशी \or एकोणनव्वद \or नव्वद \or एक्याण्णव\or ब्याण्णव \or त्र्याण्णव \or चौऱ्याण्णव \or पंचाण्णव \or शहाण्णव \or सत्त्याण्णव \or अठ्याण्णव %
\or नव्याण्णव \or शंभर\else\@ctrerr%
\fi%
}
@@ -13142,19 +18809,6 @@ and may look very wrong.}
\let\@Roman\xpg@save@Roman
}
-\def\blockextras@marathi{%
- \let\xpg@orig@baselinestretch\baselinestrech%
- \renewcommand{\baselinestretch}{1.2}%
- \renewcommand{\labelitemii}{$\rightarrow$}%
-}
-
-\let\xpg@orig@labelitemii\labelitemii
-
-\def\noextras@marathi{%
- \let\baselinestrech\xpg@orig@baselinestretch%
- \let\labelitemii\xpg@orig@labelitemii%
-}
-
% \end{macrocode}
% \iffalse
%</gloss-marathi.ldf>
@@ -13309,7 +18963,7 @@ and may look very wrong.}
\def\@Ccdash{\leavevmode
\nobreak\cyrdash\nobreak\hskip.35em\ignorespaces}%
\ifx\cyrdash\undefined
- \def\cyrdash{\hbox to.8em{--\hss--}}%
+ \def\cyrdash{\hbox to.8em{\textendash\hss\textendash}}%
\fi
\declare@shorthand{mongolian}{",}{\nobreak\hskip.2em\ignorespaces}%
}
@@ -13423,7 +19077,7 @@ and may look very wrong.}
\def\noextras@mongolian{%
\ifcyrillic@numerals\nomongolian@numbers\fi%
- \nomongolian@shorthands%
+ \ifmongolian@babelshorthands\nomongolian@shorthands\fi%
}
\def\blockextras@mongolian{%
@@ -13925,20 +19579,20 @@ and may look very wrong.}
\finalhyphendemerits=\the\finalhyphendemerits}
}
\def\noextras@occitan{%
- \lccode\string"2019=\z@
- \nooccitan@shorthands
- \xpgoc@savedvalues
+ \lccode\string"2019=\z@%
+ \ifoccitan@babelshorthands\nooccitan@shorthands\fi%
+ \xpgoc@savedvalues%
}
\def\blockextras@occitan{%
- \lccode\string"2019=\string"2019
- \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
- \finalhyphendemerits=50000000
- \ifoccitan@babelshorthands\occitan@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+ \finalhyphendemerits=50000000%
+ \ifoccitan@babelshorthands\occitan@shorthands\fi%
}
\def\inlineextras@occitan{%
- \lccode\string"2019=\string"2019
- \ifoccitan@babelshorthands\occitan@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \ifoccitan@babelshorthands\occitan@shorthands\fi%
}
%% Distributable under the LaTeX Project Public License,
%% version 1.3c or higher (your choice). The latest version of
@@ -13959,12 +19613,7 @@ and may look very wrong.}
% \subsection{gloss-persian.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-persian.ldf}[polyglossia: module for persian]
-\ifluatex
- \xpg@warning{Persian is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequireBidi
\RequirePackage{arabicnumbers}
\RequirePackage{farsical}
@@ -14211,21 +19860,21 @@ and may look very wrong.}
\def\noextras@piedmontese{%
- \lccode\string"2019=\z@
- \nopiedmontese@shorthands
- \xpgpms@savedvalues
+ \lccode\string"2019=\z@%
+ \ifpiedmontese@babelshorthands\nopiedmontese@shorthands\fi%
+ \xpgpms@savedvalues%
}
\def\blockextras@piedmontese{%
- \lccode\string"2019=\string"2019
- \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
- \finalhyphendemerits=50000000
- \ifpiedmontese@babelshorthands\piedmontese@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+ \finalhyphendemerits=50000000%
+ \ifpiedmontese@babelshorthands\piedmontese@shorthands\fi%
}
\def\inlineextras@piedmontese{%
- \lccode\string"2019=\string"2019
- \ifpiedmontese@babelshorthands\piedmontese@shorthands\fi
+ \lccode\string"2019=\string"2019%
+ \ifpiedmontese@babelshorthands\piedmontese@shorthands\fi%
}
%%% CHANGES END %%%
% \end{macrocode}
@@ -14354,10 +20003,8 @@ and may look very wrong.}
% brazilian:
\def\portuguese@variant{brazil}%
\SetLanguageKeys{portuguese}{babelname=brazil,bcp47=pt-BR}%
- \xpg@ifdefined{brazil}{}%
- {\xpg@warning{No hyphenation patterns were loaded for "Portuguese (Brazil)"\MessageBreak
- I will use the standard patterns for Portuguese instead}%
- \adddialect\l@brazil\l@portuges\relax}%
+ % There are no specific brazil patterns
+ \adddialect\l@brazil\l@portuges\relax%
\fi
\xpg@info{Option: portuguese, variant=\xpg@val}%
}{\xpg@warning{Unknown portuguese variant `#1'}}
@@ -14621,19 +20268,26 @@ and may look very wrong.}
\xpg@info{Option: Russian, numerals=\xpg@val}%
}{\xpg@warning{Unknown Russian numerals value `#1'}}
-\define@boolkey{russian}[russian@]{indentfirst}[true]{
- \ifrussian@indentfirst
- \SetLanguageKeys{russian}{indentfirst=true}
- \else
- \SetLanguageKeys{russian}{indentfirst=false}
- \fi
+\define@boolkey{russian}[russian@]{indentfirst}[true]{%
+ \ifrussian@indentfirst
+ \SetLanguageKeys{russian}{indentfirst=true}%
+ \else
+ \SetLanguageKeys{russian}{indentfirst=false}%
+ \fi%
}
\define@boolkey{russian}[russian@]{babelshorthands}[true]{}
+% Force punctuation after heading number
+\define@boolkey{russian}[russian@]{forceheadingpunctuation}[true]{}
+
% Register default options
-\xpg@initialize@gloss@options{russian}{babelshorthands=false,spelling=modern,numerals=arabic,indentfirst=false}
+\xpg@initialize@gloss@options{russian}{babelshorthands=false,
+ spelling=modern,
+ numerals=arabic,
+ indentfirst=true,
+ forceheadingpunctuation=true}
\ifsystem@babelshorthands
@@ -14681,7 +20335,7 @@ and may look very wrong.}
\def\@Ccdash{\leavevmode
\nobreak\cyrdash\nobreak\hskip.35em\ignorespaces}%
\ifx\cyrdash\undefined
- \def\cyrdash{\hbox to.8em{--\hss--}}%
+ \def\cyrdash{\hbox to.8em{\textendash\hss\textendash}}%
\fi
\declare@shorthand{russian}{",}{\nobreak\hskip.2em\ignorespaces}%
}
@@ -14778,39 +20432,46 @@ and may look very wrong.}
\space \number\year\space г.}%
}
-% The following is based on some ideas from ruscor.sty
+% Russian needs trailing dots in all headings
+\def\xpg@save@autodot{}
+\ifdef{\KOMAScript}{%
+ \let\xpg@save@autodot\autodot%
+}
+
\def\russian@capsformat{%
+ \ifrussian@forceheadingpunctuation%
\ifdef{\KOMAScript}{%
- \ifdef{\chapterformat}{%
- \renewcommand{\chapterformat}{\prechapter\thechapter\postchapter}}{}%
- \ifdef{\sectionformat}{%
- \renewcommand{\sectionformat}{\presection\thesection\postsection}}{}%
- \ifdef{\subsectionformat}{%
- \renewcommand{\subsectionformat}{\presubsection\thesubsection\postsubsection}}{}%
- \ifdef{\subsubsectionformat}{%
- \renewcommand{\subsubsectionformat}{\presubsubsection\thesubsubsection\postsubsubsection}}{}%
- \ifdef{\paragraphformat}{%
- \renewcommand{\paragraphformat}{\preparagraph\theparagraph\postparagraph}}{}%
- \ifdef{\subparagraphformat}{%
- \renewcommand{\subparagraphformat}{\presubparagraph\thesubparagraph\postsubparagraph}}{}%
+ \renewcommand*\autodot{.}%
}{%
+ % The following is based on some ideas from ruscor.sty
\def\@seccntformat##1{\csname pre##1\endcsname%
\csname the##1\endcsname%
\csname post##1\endcsname}%
- }%
- \def\@aftersepkern{\hspace{0.5em}}%
- \def\postchapter{.\@aftersepkern}%
- \def\postsection{.\@aftersepkern}%
- \def\postsubsection{.\@aftersepkern}%
- \def\postsubsubsection{.\@aftersepkern}%
- \def\postparagraph{.\@aftersepkern}%
- \def\postsubparagraph{.\@aftersepkern}%
- \def\prechapter{}%
- \def\presection{}%
- \def\presubsection{}%
- \def\presubsubsection{}%
- \def\preparagraph{}%
- \def\presubparagraph{}%
+ \def\@aftersepkern{\hspace{0.5em}}%
+ \def\postchapter{.\@aftersepkern}%
+ \def\postsection{.\@aftersepkern}%
+ \def\postsubsection{.\@aftersepkern}%
+ \def\postsubsubsection{.\@aftersepkern}%
+ \def\postparagraph{.\@aftersepkern}%
+ \def\postsubparagraph{.\@aftersepkern}%
+ \def\prechapter{}%
+ \def\presection{}%
+ \def\presubsection{}%
+ \def\presubsubsection{}%
+ \def\preparagraph{}%
+ \def\presubparagraph{}%
+ }%
+ \fi%
+}
+
+\def\norussian@capsformat{%
+ \ifrussian@forceheadingpunctuation%
+ \ifdef{\KOMAScript}{%
+ \let\autodot\xpg@save@autodot%
+ }{%
+ \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
+ }%
+ \fi%
}
\newcommand{\russiannumerals}[2]{\russiannumber{#2}}
@@ -14885,24 +20546,9 @@ and may look very wrong.}
}
\def\noextras@russian{%
- \ifdef{\KOMAScript}{%
- \ifdef{\chapterformat}{%
- \renewcommand{\chapterformat}{\thechapter\autodot\enskip}}{}%
- \ifdef{\sectionformat}{%
- \renewcommand{\sectionformat}{\thesection\autodot\enskip}}{}%
- \ifdef{\subsectionformat}{%
- \renewcommand{\subsectionformat}{\thesubsection\autodot\enskip}}{}%
- \ifdef{\subsubsectionformat}{%
- \renewcommand{\subsubsectionformat}{\thesubsubsection\autodot\enskip}}{}%
- \ifdef{\paragraphformat}{%
- \renewcommand{\paragraphformat}{\theparagraph\autodot\enskip}}{}%
- \ifdef{\subparagraphformat}{%
- \renewcommand{\subparagraphformat}{\thesubparagraph\autodot\enskip}}{}%
- }{%
- \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
- }%
+ \norussian@capsformat%
\ifcyrillic@numerals\norussian@numbers\fi%
- \norussian@shorthands%
+ \ifrussian@babelshorthands\norussian@shorthands\fi%
}
\def\blockextras@russian{%
@@ -15061,12 +20707,6 @@ and may look very wrong.}
% \subsection{gloss-sanskrit.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-sanskrit.ldf}[polyglossia: module for sanskrit]
-\ifluatex
- \xpg@warning{Sanskrit is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
\RequirePackage{devanagaridigits}
@@ -15249,7 +20889,8 @@ and may look very wrong.}
indentfirst=true,
fontsetup=false,
localnumeral=serbiannumerals,
- Localnumeral=Serbiannumerals
+ Localnumeral=Serbiannumerals,
+ babelname=serbian
%TODO localalph
}
@@ -15271,7 +20912,7 @@ and may look very wrong.}
\or
% latin:
\@serbian@cyrfalse
- \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,bcp47=sr-Latn}
+ \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,babelname=serbian,bcp47=sr-Latn}
\xpg@fontsetup@latin{serbian}%
%TODO \def\serbian@language{\language=\l@serbianlat}%
% or should we use Croatian patterns as a fallback for the time being???
@@ -15579,7 +21220,7 @@ and may look very wrong.}
\chardef\slovak@boundary=4095 %
\def\newXeTeXintercharclass{%
\e@alloc\XeTeXcharclass\chardef
- \xe@alloc@intercharclass\m@ne\@ucharclass@boundary}
+ \xe@alloc@intercharclass\m@ne\@ucharclass@boundary}%
\else
\chardef\slovak@boundary=255
\fi
@@ -15608,6 +21249,24 @@ and may look very wrong.}
% Add nonbreakable space after single-letter word to
% prevent them to land at the end of a line
+% vlna code taken and adapted from xevlna.sty
+\ifxetex
+ \def\slovak@nointerchartoks{\let\slovak@interchartoks\slovak@PreCSpreposition}%
+ \def\slovak@PreCSpreposition{%
+ \def\next{}%
+ \ifnum\catcode`\ =10 % nothing will be done in verbatim
+ \ifmmode % nothing in math
+ \else
+ \let\slovak@interchartoks\slovak@nointerchartoks
+ \let\next\slovak@ExamineCSpreposition
+ \fi\fi
+ \next%
+ }%
+ \def\slovak@ExamineCSpreposition #1{#1\futurelet\next\slovak@ProcessCSpreposition}%
+ \def\slovak@ProcessCSpreposition{\ifx\next\slovak@XeTeXspace\nobreak\fi}%
+ \futurelet\slovak@XeTeXspace{ }\slovak@nointerchartoks
+\fi
+
\def\slovak@vlna{%
\ifluatex
\preventsingleon
@@ -15634,21 +21293,8 @@ and may look very wrong.}
\XeTeXcharclass `\a \slovak@nonsyllabicpreposition
\XeTeXcharclass `\I \slovak@nonsyllabicpreposition
\XeTeXcharclass `\i \slovak@nonsyllabicpreposition
- \XeTeXinterchartoks \slovak@boundary \slovak@nonsyllabicpreposition {\slovak@interchartoks}
- \XeTeXinterchartoks \slovak@openpunctuation \slovak@nonsyllabicpreposition {\slovak@interchartoks}
- \def\slovak@nointerchartoks{\let\slovak@interchartoks\slovak@PreCSpreposition}
- \def\slovak@PreCSpreposition{\def\next{}%
- \ifnum\catcode`\ =10 % nothing will be done in verbatim
- \ifmmode % nothing in math
- \else
- \let\slovak@interchartoks\slovak@nointerchartoks
- \let\next\slovak@ExamineCSpreposition
- \fi \fi
- \next%
- }
- \def\slovak@ExamineCSpreposition ##1{##1\futurelet\next\slovak@ProcessCSpreposition}
- \def\slovak@ProcessCSpreposition{\ifx\next\slovak@XeTeXspace\nobreak\fi}
- \futurelet\slovak@XeTeXspace{ }\slovak@nointerchartoks
+ \XeTeXinterchartoks \slovak@boundary \slovak@nonsyllabicpreposition {\slovak@interchartoks}%
+ \XeTeXinterchartoks \slovak@openpunctuation \slovak@nonsyllabicpreposition {\slovak@interchartoks}%
\fi
}
@@ -15714,7 +21360,7 @@ and may look very wrong.}
}
\def\noextras@slovak{%
- \noslovak@shorthands%
+ \ifslovak@babelshorthands\noslovak@shorthands\fi%
\noslovak@hyphens%
\noslovak@vlna%
\ifxetex\XeTeXinterchartokenstate=0\fi%
@@ -16354,12 +22000,7 @@ and may look very wrong.}
% \subsection{gloss-syriac.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-syriac.ldf}[polyglossia: module for syriac]
-\ifluatex
- \xpg@warning{Syriac is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequireBidi
\RequirePackage{arabicnumbers}
@@ -16543,12 +22184,7 @@ and may look very wrong.}
% \subsection{gloss-tamil.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-tamil.ldf}[polyglossia: module for tamil]
-\ifluatex
- \xpg@warning{Tamil is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
% Translations provided by Kevin & Siji, 01-11-2009
\PolyglossiaSetup{tamil}{
@@ -16614,12 +22250,7 @@ and may look very wrong.}
% \subsection{gloss-telugu.ldf}
% \begin{macrocode}
\ProvidesFile{gloss-telugu.ldf}[polyglossia: module for telugu]
-\ifluatex
- \xpg@warning{Telugu is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
% Translations provided by Anmol Sharma <unmole.in@gmail.com>
\PolyglossiaSetup{telugu}{
@@ -16697,12 +22328,6 @@ and may look very wrong.}
%%%% Thai Linux Working Group
%%%% http://linux.thai.net/
%%%%
-\ifluatex
- \xpg@warning{Thai is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
\PolyglossiaSetup{thai}{
bcp47=th,
script=Thai,
@@ -17292,7 +22917,7 @@ and may look very wrong.}
\def\@Ccdash{\leavevmode
\nobreak\cyrdash\nobreak\hskip.35em\ignorespaces}%
\ifx\cyrdash\undefined
- \def\cyrdash{\hbox to.8em{--\hss--}}
+ \def\cyrdash{\hbox to.8em{\textendash\hss\textendash}}%
\fi
\declare@shorthand{ukrainian}{",}{\nobreak\hskip.2em\ignorespaces}%
}
@@ -17370,7 +22995,7 @@ and may look very wrong.}
\def\ukrainiannumber#1{%
\ifcyrillic@numerals
\ifcyrillic@asbuk@numerals
- \serbian@asbuk@alph{#1}%
+ \ukrainian@asbuk@alph{#1}%
\else
\cyr@alph{#1}%
\fi
@@ -17382,7 +23007,7 @@ and may look very wrong.}
\def\Ukrainiannumber#1{%
\ifcyrillic@numerals
\ifcyrillic@asbuk@numerals
- \serbian@asbuk@Alph{#1}%
+ \ukrainian@asbuk@Alph{#1}%
\else
\cyr@Alph{#1}%
\fi
@@ -17402,25 +23027,29 @@ and may look very wrong.}
% This is a poor man's cyrillic alphanumeric. It just uses the alphabet and
% thus ends at 30.
-\def\ukranian@asbuk@Alph#1{\ifcase#1\or
+\def\ukrainian@asbuk@Alph#1{\ifcase#1\or
А\or Б\or В\or Г\or Д\or Е\or Ж\or
З\or И\or К\or Л\or М\or Н\or О\or
П\or Р\or С\or Т\or У\or Ф\or Х\or
Ц\or Ч\or Ш\or Щ\or Э\or Ю\or Я%
- \else\xpg@ill@value{#1}{ukranian@asbuk@Alph}\fi%
+ \else\xpg@ill@value{#1}{ukrainian@asbuk@Alph}\fi%
}
-\def\ukranian@asbuk@alph#1{\ifcase#1\or
+\def\ukrainian@asbuk@alph#1{\ifcase#1\or
а\or б\or в\or г\or д\or е\or ж\or
з\or и\or к\or л\or м\or н\or о\or
п\or р\or с\or т\or у\or ф\or х\or
ц\or ч\or ш\or щ\or э\or ю\or я%
- \else\xpg@ill@value{#1}{ukranian@asbuk@alph}\fi%
+ \else\xpg@ill@value{#1}{ukrainian@asbuk@alph}\fi%
}
\def\ukrainian@numbers{%
- \let\@Alph\ukrainian@Alph%
- \let\@alph\ukrainian@alph%
+ \ifcyrillic@numerals
+ \def\ukrainian@alph##1{\expandafter\ukrainiannumeral\expandafter{\the##1}}%
+ \def\ukrainian@Alph##1{\expandafter\Ukrainiannumeral\expandafter{\the##1}}%
+ \let\@Alph\ukrainian@Alph%
+ \let\@alph\ukrainian@alph%
+ \fi
}
\def\noukrainian@numbers{%
@@ -17431,13 +23060,13 @@ and may look very wrong.}
\def\noextras@ukrainian{%
\def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
\ifcyrillic@numerals\noukrainian@numbers\fi
- \noukrainian@shorthands%
+ \ifukrainian@babelshorthands\noukrainian@shorthands\fi%
}
\def\blockextras@ukrainian{%
\ukrainian@capsformat%
- \ifcyrillic@numerals\ukrainian@numbers\fi
- \ifukrainian@babelshorthands\ukrainian@shorthands\fi
+ \ifcyrillic@numerals\ukrainian@numbers\fi%
+ \ifukrainian@babelshorthands\ukrainian@shorthands\fi%
}
\def\inlineextras@ukrainian{%
@@ -17492,12 +23121,7 @@ and may look very wrong.}
% \begin{macrocode}
%%% Adapted from a file contributed by Kamal Abdali
\ProvidesFile{gloss-urdu.ldf}[polyglossia: module for Urdu]
-\ifluatex
- \xpg@warning{Urdu is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
\RequireBidi
\RequirePackage{arabicnumbers}
\RequirePackage{hijrical}
@@ -18765,21 +24389,21 @@ local left_bracket_chars = {
-- all right bracket characters, referenced by their Unicode slot
local right_bracket_chars = {
- [0x29] = true, -- right parenthesis
- [0x5D] = true, -- right square bracket
- [0x7D] = true, -- right curly bracket
+ [0x29] = true, -- right parenthesis
+ [0x5D] = true, -- right square bracket
+ [0x7D] = true, -- right curly bracket
[0x27E9] = true -- mathematical right angle bracket
}
-- question and exclamation marks, referenced by their Unicode slot
local question_exclamation_chars = {
- [0x21] = true, -- exclamation mark !
- [0x3F] = true, -- question mark ?
+ [0x21] = true, -- exclamation mark !
+ [0x3F] = true, -- question mark ?
[0x203C] = true, -- double exclamation mark ‼
[0x203D] = true, -- interrobang ‽
[0x2047] = true, -- double question mark ⁇
[0x2048] = true, -- question exclamation mark ⁈
- [0x2049] = true, -- exclamation question mark ⁉
+ [0x2049] = true -- exclamation question mark ⁉
}
-- from nodes-tst.lua, adapted
@@ -18905,9 +24529,12 @@ local function process(head)
if id == glyph_code then
local attr = has_attribute(current, punct_attr)
if attr then
- local char = utf8.char(current.char) -- requires Lua 5.3
- local leftspace = left_space[attr][char]
- local rightspace = right_space[attr][char]
+ local char, leftspace, rightspace
+ if current.char <= 0x10FFFF then -- greater values may cause problems with utf8.char
+ char = utf8.char(current.char)
+ leftspace = left_space[attr][char]
+ rightspace = right_space[attr][char]
+ end
if leftspace or rightspace then
local fontparameters = fonts.hashes.parameters[current.font]
local unit, stretch, shrink, spacing_node
@@ -18915,14 +24542,14 @@ local function process(head)
local prev = getprev(current)
local space_exception = false
if prev then
- local prevprev = getprev(prev)
-- do not add space after left (opening) bracket and between question/exclamation marks
space_exception = someleftbracket(prev) or question_exclamation_sequence(prev, current)
- if somespace(prev) then
-- TODO: there is a question here: do we override a preceding space or not?...
- if somepenalty(prevprev, 10000) then
- head = remove_node(head, prevprev)
- end
+ while somespace(prev) do
+ head = remove_node(head, prev)
+ prev = getprev(current)
+ end
+ if somepenalty(prev, 10000) then
head = remove_node(head, prev)
end
end
@@ -18952,10 +24579,10 @@ local function process(head)
space_exception = somerightbracket(next)
local nextnext = getnext(next)
if somepenalty(next, 10000) and somespace(nextnext) then
- head = remove_node(head, next)
- head = remove_node(head, nextnext)
- elseif somespace(next) then
- head = remove_node(head, next)
+ head, next = remove_node(head, next)
+ end
+ while somespace(next) do
+ head, next = remove_node(head, next)
end
end
if rightspace.unit == "quad" then
@@ -19368,52 +24995,68 @@ polyglossia.newloader_loaded_languages = newloader_loaded_languages
% \Finale
%
% \iffalse
-%<*../README.md>
-# THE POLYGLOSSIA PACKAGE v1.49
-## Multilingual typesetting with XeLaTeX and LuaLaTeX
+%<*Changelog>
+1.50 (09-10-2020)
-This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX
-(with a few languages incompletely supported for the latter). This version
-includes support for over 70 different languages, some of which in different
-regional or national varieties, or using a different writing system.
+New features:
-Polyglossia makes it possible to automate the following tasks:
+ * Polyglossia now uses the Harfbuzz renderer by default with LuaTeX
+ output. This brings LuaTeX on par with XeTeX for all scripts (#337).
+ The renderer can be changed via the new global luatexrenderer option.
+ * The (previously inadvertently working) hyphenrules environment that ceased
+ to work after a recent babel update is back and now officially supported.
+ The environment now also supports language options and aliases (#427).
+ * New command \setlanghyphenmins to adapt hyphenation thresholds of languages
+ and varieties.
+ * New command \abjadalph for Arabic with corresponding option (#431).
+ * Replace consecutive glues around punctuation by the correct amount of space
+ with LuaLaTeX for French, ecclesiastic Latin, and Sanskrit (#437).
-* Loading the appropriate hyphenation patterns.
-* Setting the script and language tags of the current font (if possible and
- available), using the package fontspec.
-* Switching to a font assigned by the user to a particular script or language.
-* Adjusting some typographical conventions in function of the current language
- (such as afterindent, frenchindent, spaces before or after punctuation marks,
- etc.).
-* Redefining the document strings (like “chapter”, “figure”, “bibliography”).
-* Adapting the formatting of dates (for non-gregorian calendars via external
- packages bundled with polyglossia: currently the Hebrew, Islamic and Farsi
- calendars are supported).
-* For languages that have their own numeration system, modifying the formatting
- of numbers appropriately.
-* Ensuring the proper directionality if the document contains languages
- written from right to left (via the packages bidi and luabidi, available
- separately).
+Bug fixes:
-# LICENCE
+ * Remove warning about missing Brazil patterns (#404).
+ * Fix incompatibility with recent babel release (#408).
+ * Fixed some spellings in Marathi (#409).
+ * Fix spacing of geminating dot in Catalan (#410).
+ * Fix incompatibility of Marathi with Beamer.
+ * Correct \partname in Hindi (#416).
+ * Updates and improvements to Kurdish (#418).
+ * Only activate shorthand character if babelshorthands is true (#421).
+ * Fix whitespace issue in Czech and Slovak with vlna=true (#423).
+ * Fix whitespace issue in Danish (#424).
+ * Fix catcode conflicts that might occur in language definition files
+ f. ex. when loaded from a LaTeX3 class (#67, #425).
+ * Robustify font family switches (#428).
+ * Fix whitespace issue in Russian indentfirst option (#433).
+ * In Russian, indentfirst is now again default (#434).
+ * Fix LaTeX error with arabic numbering in Ukrainian (#440).
+ * Fix directionality after Hebrew decimal numbers (#441).
+ * Fix babelname of Latin Serbian (#442).
+ * Fix recording of secondary languages in \xpg@bloaded and \xpg@bcp@loaded
+ lists (#443).
+ * Simplify and robustify section heading modification in Russian
+ and introduce option forceheadingpunctuation (#444).
+ * Fix Cyrillic dash (via babelshorthand "---) when TeX ligatures
+ are disabled (#445)
+ * Fix problem with large character indices in Lua module for punctuation
+ spacing
-Copyright (c) 2008-2010 François Charette, 2013 Élie Roux, 2011-2020 Arthur Reutenauer,
-Copyright (c) 2019-2020 Bastien Roucariès, 2019-2020 Jürgen Spitzmüller
+Interface and defaults changes:
-Except where otherwise noted, Polyglossia is placed under the terms of the MIT licence
-(https://opensource.org/licenses/MIT).
+ * Polyglossia now uses the Harfbuzz renderer by default with LuaTeX
+ output. See new features section.
-# BUGS
+Build fixes:
-If you run into a bug, or suspect you do, or you have a request or comment, please
-use the GitHub issue tracker: http://github.com/reutenauer/polyglossia/issues
+ * Fix a bug in the dtx build script which was the reason for an utterly
+ incomplete polyglossia.dtx file (#420).
-This is more efficient than contacting the maintainer by email as it allows me
-to track the issues and follow progress.
-%</../README.md>
-%<*Changelog>
-1.49 (???)
+Documentation improvements:
+ * Document how to change \lefthyphenmin and \righthyphenmin for a language
+ (#435).
+
+
+1.49 (08-04-2020)
New features:
diff --git a/macros/unicodetex/latex/polyglossia/polyglossia.pdf b/macros/unicodetex/latex/polyglossia/polyglossia.pdf
index 6c1979411b..64a81bfe41 100644
--- a/macros/unicodetex/latex/polyglossia/polyglossia.pdf
+++ b/macros/unicodetex/latex/polyglossia/polyglossia.pdf
Binary files differ