From 03964f11f0331968e99fa5a3d614f25a7b3f8a95 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sat, 10 Oct 2020 03:01:27 +0000 Subject: CTAN sync 202010100301 --- macros/unicodetex/latex/polyglossia/README.md | 9 +- .../unicodetex/latex/polyglossia/polyglossia.dtx | 6511 ++++++++++++++++++-- .../unicodetex/latex/polyglossia/polyglossia.pdf | Bin 269164 -> 279264 bytes 3 files changed, 6081 insertions(+), 439 deletions(-) (limited to 'macros/unicodetex') 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 % %<*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 % % @@ -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}. % @@ -2547,9 +2676,5550 @@ to track the issues and follow progress. % % % -% \StopEventually{} -% \section{Implementation} +% \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 = {,} +%% TODO: localnumeral = +%% 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[]{}{} +\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 \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 \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, but more suitable +% for specific (esp. tag-based) aliases +% where \text 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 {}, but more suitable +% for specific (esp. tag-based) aliases +% where {} 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 +\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 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{}{}{}{} +\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 +% +%<*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 +%%% Copyright (C) 2000-2001 Behdad Esfahbod +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\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 +% +%<*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 +% +%<*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 +% +%<*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-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-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-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-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-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.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 +% +%<*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 +% +%<*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 +% +%<*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 +% +%<*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 +% %<*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 % @@ -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 \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) + +New features: -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. + * 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). -Polyglossia makes it possible to automate the following tasks: +Bug fixes: -* 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). + * 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 -# LICENCE +Interface and defaults changes: -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 + * Polyglossia now uses the Harfbuzz renderer by default with LuaTeX + output. See new features section. -Except where otherwise noted, Polyglossia is placed under the terms of the MIT licence -(https://opensource.org/licenses/MIT). +Build fixes: -# BUGS + * Fix a bug in the dtx build script which was the reason for an utterly + incomplete polyglossia.dtx file (#420). -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 +Documentation improvements: + * Document how to change \lefthyphenmin and \righthyphenmin for a language + (#435). -This is more efficient than contacting the maintainer by email as it allows me -to track the issues and follow progress. -% -%<*Changelog> -1.49 (???) + +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 Binary files a/macros/unicodetex/latex/polyglossia/polyglossia.pdf and b/macros/unicodetex/latex/polyglossia/polyglossia.pdf differ -- cgit v1.2.3