texlive[56613] Master/texmf-dist: polyglossia (9oct20)

commits+karl at tug.org commits+karl at tug.org
Fri Oct 9 22:23:22 CEST 2020


Revision: 56613
          http://tug.org/svn/texlive?view=revision&revision=56613
Author:   karl
Date:     2020-10-09 22:23:21 +0200 (Fri, 09 Oct 2020)
Log Message:
-----------
polyglossia (9oct20)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/polyglossia/README.md
    trunk/Master/texmf-dist/doc/latex/polyglossia/example-arabic.pdf
    trunk/Master/texmf-dist/doc/latex/polyglossia/example-korean.pdf
    trunk/Master/texmf-dist/doc/latex/polyglossia/example-thai.pdf
    trunk/Master/texmf-dist/doc/latex/polyglossia/examples.pdf
    trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.pdf
    trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.tex
    trunk/Master/texmf-dist/source/latex/polyglossia/polyglossia.dtx
    trunk/Master/texmf-dist/tex/latex/polyglossia/babelsh.def
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-afrikaans.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-arabic.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-belarusian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-bengali.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-catalan.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-croatian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-czech.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-danish.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-divehi.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-dutch.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-finnish.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-georgian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-german.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hebrew.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hindi.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-italian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kannada.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kurdish.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-lao.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-latin.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-malayalam.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-marathi.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-mongolian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-occitan.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-persian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-piedmontese.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-portuguese.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-russian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-sanskrit.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-serbian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-slovak.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-syriac.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-tamil.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-telugu.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-thai.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-ukrainian.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-urdu.ldf
    trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia-punct.lua
    trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia.sty

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/polyglossia/README.md	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/doc/latex/polyglossia/README.md	2020-10-09 20:23:21 UTC (rev 56613)
@@ -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:
 

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/example-arabic.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/example-korean.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/example-thai.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/examples.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.tex	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/doc/latex/polyglossia/polyglossia.tex	2020-10-09 20:23:21 UTC (rev 56613)
@@ -67,6 +67,12 @@
      \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}%
@@ -141,7 +147,7 @@
 \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:
 
@@ -540,11 +546,19 @@
 		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}
@@ -609,17 +623,22 @@
 \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}
 %
 \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
@@ -707,25 +726,49 @@
 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}
 %
 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}
+%
+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.
 
@@ -775,15 +818,23 @@
 		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}
@@ -801,14 +852,13 @@
 	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 “).
@@ -815,6 +865,19 @@
 		\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}
@@ -827,7 +890,8 @@
 	With ¦spelling=classic¦, captions and dates adhere to the Taraškievica (or
 	Belarusian classical) orthography rather than the standard orthography.
 \end{itemize}
-%
+
+\condbreak{\baselineskip}
 \paragraph*{Commands:}
 \begin{itemize}
      \item \Cmd\Asbuk: produces uppercased Cyrillic alphanumerals, for environments such as ¦enumerate¦.
@@ -1069,20 +1133,31 @@
 		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.
@@ -1122,10 +1197,10 @@
 
 		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 (ſ)
@@ -1441,18 +1516,30 @@
 	\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:
@@ -1513,13 +1600,25 @@
 	\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.
 % These are commented out in gloss-russian
 %		\item[¦",¦] thinspace for initials with a breakpoint in following surname.
 %		\item[¦"‘¦] for German left double quotes (looks like ,,).
@@ -1527,6 +1626,10 @@
 %		\item[¦"<¦] for French left double quotes (looks like <<).
 %		\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
@@ -1723,14 +1826,13 @@
 	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.
 		% These are commented out in gloss-ukrainian
 		%		\item[¦",¦] thinspace for initials with a breakpoint in following surname.
 		%		\item[¦"‘¦] for German left double quotes (looks like ,,).
@@ -1738,6 +1840,19 @@
 		%		\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}
@@ -2023,7 +2138,7 @@
 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)}
@@ -2161,9 +2276,9 @@
 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}.
 

Modified: trunk/Master/texmf-dist/source/latex/polyglossia/polyglossia.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/polyglossia/polyglossia.dtx	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/source/latex/polyglossia/polyglossia.dtx	2020-10-09 20:23:21 UTC (rev 56613)
@@ -8,13 +8,12 @@
 \iffalse
 %</internal>
 %<*README>
-# THE POLYGLOSSIA PACKAGE v1.49
+# THE POLYGLOSSIA PACKAGE v1.50
 ## Multilingual typesetting with XeLaTeX and LuaLaTeX
 
-This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX
-(with a few languages incompletely supported for the latter). This version
-includes support for over 70 different languages, some of which in different
-regional or national varieties, or using a different writing system.
+This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX.
+This version includes support for over 70 different languages, some of which in
+different regional or national varieties, or using a different writing system.
 
 Polyglossia makes it possible to automate the following tasks:
 
@@ -95,6 +94,21 @@
 \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 @@
 %<*internal>
 \generate{\file{polyglossia.ins}{\from{polyglossia.dtx}{batchfile}}}
 \nopreamble\nopostamble
-\generate{\file{../README.md}{\from{polyglossia.dtx}{../README.md}}}
 \generate{\file{Changelog}{\from{polyglossia.dtx}{Changelog}}}
 \generate{\file{examples.tex}{\from{polyglossia.dtx}{examples.tex}}}
 \generate{\file{example-arabic.tex}{\from{polyglossia.dtx}{example-arabic.tex}}}
 \generate{\file{example-thai.tex}{\from{polyglossia.dtx}{example-thai.tex}}}
+\generate{\file{README.md}{\from{polyglossia.dtx}{README}}}
 \endgroup
 %</internal>
 %
@@ -424,6 +438,12 @@
      \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 @@
 % \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 @@
 % 		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 @@
 % \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 @@
 % 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 @@
 % 		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,14 +1234,13 @@
 % 	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 “).
@@ -1183,6 +1247,19 @@
 % 		\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 @@
 % 	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 @@
 % 		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 @@
 % 
 % 		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 @@
 % 	\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 @@
 % 	\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 @@
 % ^^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 @@
 % 	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 @@
 % ^^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 @@
 % 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 @@
 % In alphabetical order: \TA{Ignas Anikevicius}, \TA{Sina Ahmadi}, \TA{Wouter Bolsterlee}, \TA{Christian Buhtz},
 % \TA{Zgarbul Andrey}, \TA{Oleg Domanov}, \TA{Philipp Gesang}, \TA{Kevin Godby}, \TA{Enrico Gregorio},
 % \TA{Khaled Hosny}, \TA{Najib Idrissi}, user \TA{julroy67}, \TA{Dohyun Kim}, \TA{Phil Kime}, \TA{Mike Kroutikov},
-% \TA{Ivan Kokan}, \TA{Caleb Maclennan}, \TA{José Mancera}, \TA{Yevgen Pogribnyi}, \TA{Will Robertson}, \TA{Maïeul Rouquette},
-% \TA{Elie Roux}, \TA{Hugo Roy},  \TA{Guy Rutenberg}, \TA{Philipp Stephani}, \TA{Niranjan Tambe}, \TA{Keno Wehr},
-% \TA{Dominik Wujastyk}, \TA{Sertaç Ö. Yıldız}, \TA{Maksim Zholudev}, \TA{Yan Zhou}, and \TA{Stefan Zlatinov}.
+% \TA{Ivan Kokan}, \TA{Caleb Maclennan}, \TA{José Mancera}, \TA{Miquel Ortega}, \TA{Yevgen Pogribnyi}, \TA{Will Robertson},
+% \TA{Maïeul Rouquette}, \TA{Elie Roux}, \TA{Hugo Roy},  \TA{Guy Rutenberg}, \TA{Philipp Stephani}, \TA{Niranjan Tambe},
+% \TA{Keno Wehr}, \TA{Dominik Wujastyk}, \TA{Sertaç Ö. Yıldız}, \TA{Maksim Zholudev}, \TA{Yan Zhou}, and \TA{Stefan Zlatinov}.
 % Their respective contributions can be identified from the contributor statistics on
 % \href{https://github.com/reutenauer/polyglossia/graphs/contributors}{GitHub}.
 % 
@@ -2550,6 +2679,5547 @@
 % \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 at babel.sty}{\@empty} % this "fakes" babel
+\def\languageshorthands#1{\relax} %this is for scrlttr2 class
+\def\bbl at cs#1{\csname bbl@#1\endcsname}%
+\AtEndPreamble{\let\bbl at set@language\xpg at set@language at aux} %for biblatex
+\AtEndPreamble{\let\bbl at main@language\xpg at 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 at alloc@intercharclass at top}
+  {\chardef\xpg at boundaryclass=\@cclv}
+  {\let\xpg at boundaryclass=\e at alloc@intercharclass at top}
+
+% Useful for getting list of loaded languages and variants. Like babel's bbl at loaded
+\let\xpg at loaded\@empty% list of loaded languages (polyglossia name)
+\let\xpg at vloaded\@empty% list of loaded variants
+\let\xpg at bloaded\@empty% list of loaded languages (babel name)
+\let\xpg at bcp@loaded\@empty% list of loaded languages (bcp-47 id)
+
+% counter in latin
+\def\latinalph#1{\expandafter\latin at alph\csname c@#1\endcsname}
+\def\latinAlph#1{\expandafter\latin at Alph\csname c@#1\endcsname}
+
+% select language hook
+\cs_new_nopar:Nn \polyglossia at AtBeginDocument@selectlanguage: {}
+% \disablehyphenation hook
+\cs_new_nopar:Nn \polyglossia at AtBeginDocument@hyphenation: {}
+
+% hook to be executed at begin of document
+\cs_new_nopar:Nn \polyglossia at AtBeginDocument: {
+  % save various command
+  \let\latin at alph\@alph   % TODO rename when we have the C locale
+  \let\latin at Alph\@Alph   % TODO rename when we have the C locale
+  % push to C language gloss
+  \let\polyglossia at Clang@@arabic\@arabic
+  \let\polyglossia at Clang@arabic\arabic
+  
+  \xpg at initial@setup
+  % apply \familydefault changes
+  \xpg at set@familydefault
+}
+
+\AtBeginDocument{
+  \polyglossia at 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 at AtBeginDocument@selectlanguage:
+  % If hyphenation disabling has been requested in preamble, do it now
+  \polyglossia at AtBeginDocument@hyphenation:
+}
+
+%% custom message macros
+\providecommand*{\xpg at error}[1]{%
+   \PackageError{polyglossia}{#1}{}%
+}
+
+\providecommand*{\xpg at warning}[1]{%
+   \PackageWarning{polyglossia}{#1}%
+}
+
+\providecommand*{\xpg at info}[1]{%
+   \PackageInfo{polyglossia}%
+   {#1\@gobble}%
+} %% the \@gobble is to prevent displaying the line nr
+
+%TODO change all instances of \xpg at nopatterns in gloss-*.ldf files
+\providecommand*{\xpg at nopatterns@fallback}[2][nohyphenation]{%
+   \xpg at 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 at nopatterns}[1]{%
+   \xpg at warning{No~ hyphenation~ patterns~ were~ loaded~ for~ `#1'\MessageBreak
+         I~ will~ use~ \string\language=\string\l at nohyphenation\space instead}%
+   %%TODO? \expandafter\adddialect\csname l@#1\endcsname\l at nohyphenation\relax
+   }
+
+\def\xpg at ill@value#1#2{%
+  \xpg at warning{Illegal~ value~ (#1)~ for~ #2}}
+
+% error out if lang is not loaded
+\cs_new_nopar:Nn \polyglossia at error@iflangnotloaded:n
+{
+  \cs_if_exist:cF{#1 at loaded}
+  {
+    \xpg at 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 at warn#1{%
+   \ifcsundef{#1}{\xpg at warning{ \expandafter\string\csname #1\endcsname\space is~ not~ defined}}%
+   {\csname #1\endcsname}}
+
+%% ensure directionality if bidi is loaded, else ignore
+\def\@@ensure at dir#1{\ifcsundef{@ensure at dir}{#1}{\@ensure at dir{#1}}}
+\def\@@ensure at maindir#1{\ifcsundef{@ensure at maindir}{#1}{\@ensure at 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 at 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 at setpardirection:n}{%
+  \str_case_e:nnTF{#1}{%
+       {LR}{\relax}%
+       {RL}{\xpg at error{right-to-left,~ but~ (lua)bidi~ package~ was~ not~ loaded!}}%
+     }%
+     {}%
+     {\xpg at error{Unknown~ language~ direction~ #1 ~(base~ wrapper)}}%
+}
+\cs_new_nopar:Nn{\polyglossia at settextdirection:n}{%
+  \str_case_e:nnTF{#1}{%
+       {LR}{\relax}%
+       {RL}{\xpg at error{right-to-left,~ but~ (lua)bidi~ package~ was~ not~ loaded!}}%
+     }%
+     {}%
+     {\xpg at error{Unknown~ language~ direction~ #1 ~(base~ wrapper)}}%
+}
+\AtEndOfPackageFile*{bidi}{%
+  \ExplSyntaxOn%
+  \cs_gset_nopar:Nn{\polyglossia at setpardirection:n}{%
+    \str_case_e:nnTF{#1}{%
+        {LR}{\setLR}%
+        {RL}{\setRL}%
+      }%
+      {}%
+      {\xpg at error{Unknown~ language~ direction~ #1 ~(bidi~ wrapper)}}%
+  }%
+  \cs_gset_nopar:Nn{\polyglossia at settextdirection:n}{%
+    \str_case_e:nnTF{#1}{%
+        {LR}{\LRE}%
+        {RL}{\RLE}%
+      }%
+      {}%
+      {\xpg at error{Unknown~ language~ direction~ #1 ~(bidi~ wrapper)}}%
+  }%
+  \ExplSyntaxOff%
+}
+\AtEndOfPackageFile*{luabidi}{%
+  \ExplSyntaxOn%
+  \cs_gset_nopar:Nn{\polyglossia at setpardirection:n}{%
+    \str_case_e:nnTF{#1}{%
+        {LR}{\setLR}%
+        {RL}{\setRL}%
+      }
+      {}%
+      {\xpg at error{Unknown~ language~ direction~ #1 ~(luabidi~ wrapper)}}%
+  }%
+  \cs_gset_nopar:Nn{\polyglossia at settextdirection:n}{%
+    \str_case_e:nnTF{#1}{%
+        {LR}{\LRE}%
+        {RL}{\RLE}%
+      }
+      {}%
+      {\xpg at 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 at nopatterns@fallback - i.e. with a warning: e.g. sanskrit for hindi, or catalan for asturian. – Also for languages with variants!  (English and German, etc.)
+%% script : the name of the script (as understood by fontspec) – default is Latin
+%% scripttag : the OpenType tag for the script
+%% langtag : the OpenType tag for the language
+%% hyphenmins : the hyphenmins for this language (comma-sep list of two integers)
+%% frenchspacing : boolean
+%% indentfirst : boolean
+%% fontsetup : boolean
+%% TODO: nouppercase : boolean (for scripts like Arabic, Devanagari, etc which have no concept of uppercase/lowercase)
+%% TODO: localalph = {<alph_csname>,<Alph_csname>}
+%% TODO: localnumeral = <csname>
+%%       or even better localdigits = {0123456789} for fully automatic setup
+\newif\if at xpg@language at really@defined@
+\newcommand*\PolyglossiaSetup[2]{%
+  \polyglossia at keys_define_lang:n{#1}%
+  \keys_set:nn { polyglossia / #1 } { #2 }%
+  \prop_log:N{\polyglossia at langsetup}
+  \polyglossia_setup_hyphen:n {#1}
+  %define booleans etoolbox style and set defaults
+  %% TODO ? \providetoggle{#1 at setup@done}%
+  % we initialize these so that we can use \gappto below
+  \csgdef{init at extras@#1}{}%
+  \csgdef{init at noextras@#1}{}% we don't use this yet: remove?
+  % here we do the fontsetup:
+  \polyglossia at lang@autosetupfont:n{#1}
+  %% TODO? \toggletrue{#1 at 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 at 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 at 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 at ifdefined{##1}{
+                  % test if language hyphenation is nohyphenation
+                  \cs_if_eq:cNF{l@#1}{\l at 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 at set@hyphenation at 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 at ifdefined{#1}{}%
+    {
+      \xpg at nopatterns{#1}
+      \expandafter\adddialect\csname l@#1\endcsname\l at nohyphenation\relax
+    }%
+  }%
+  \csdef{#1 at language}{%
+    \polyglossia at setup@language at patterns{#1}%
+  }%
+  % setup hyphenmins
+  \exp_args:NNe \clist_set:Nn \l_tmpa_clist
+    { \prop_item:Nn \polyglossia at langsetup {#1 / hyphenmins} }
+  \cs_if_eq:cNF {l@#1} \l at nohyphenation
+    {
+      \use:x
+        {
+          \exp_not:N \setlocalhyphenmins {#1}
+            { \clist_item:Nn \l_tmpa_clist {1} }
+            { \clist_item:Nn \l_tmpa_clist {2} }
+        }
+    }
+}
+
+\newcommand*\polyglossia at setup@language at patterns[1]{%
+  \ifbool{xpg at hyphenation@disabled}{%
+    \xdef\xpg at 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 at nohyphenation
+          {
+            \language=\l at nohyphenation
+          }
+          {
+            \xpg at set@hyphenation at patterns{#1}
+          }
+      }
+      {%
+        % Since this function is sometimes called from the gloss files
+        % directly, we need to check whether the requested hyphenname exists.
+        \xpg at ifdefined{#1}{}%
+        {%
+          \xpg at nopatterns{#1}
+          \expandafter\adddialect\csname l@#1\endcsname\l at nohyphenation\relax%
+        }%
+        \xpg at set@hyphenation at patterns{#1}
+      }
+  }
+}
+
+\prop_new:N \polyglossia at langsetup
+
+\cs_new_protected:Npn \polyglossia at keys_define_lang:n #1 {
+  \keys_define:nn {polyglossia}{
+    % the script font
+    #1 / script
+       .code:n = {
+          \prop_gput:Nnn{\polyglossia at langsetup}{#1/script}{##1}
+          \prop_gput:Nnx{\polyglossia at 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 at langsetup}{#1/scripttag}{##1}},
+    #1 / scripttag
+       .default:n = {},
+    #1 / scripttag
+      .initial:n = {},
+    % the language full name
+    #1 / language
+       .code:n = {\prop_gput:Nnn{\polyglossia at 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 at 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 at 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 at 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 at langsetup}{#1/direction}{##1}}
+           {\xpg at 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 at error{hypenmins~should~be~a~list~of~two~entries,~got~"##1"}}
+      % set prop
+      \prop_gput:Nnn \polyglossia at 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 at error{totalhyphenhypenmin~should~be~a~single~entry,~got~"##1"}}
+      % set prop
+      \prop_gput:Nnn \polyglossia at langsetup {#1/totalhyphenmin} {##1}
+    },
+    #1 / totalhyphenmin
+      .value_required:n = false,
+    % frenchspacing
+    #1 / frenchspacing
+    .code:n = {
+        \str_case_e:nnTF{##1}{
+            {true}{}
+            {false}{}
+          }
+          {}
+          {\xpg at error{frenchspacing~should~be~true~or~false. Is~ "##1"~ for~ language~ "#1"}}
+        \prop_gput:Nnn{\polyglossia at 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 at error{indentfirst~should~be~true~or~false. Is~ "##1"~ for~ language "#1"}}
+      \prop_gput:Nnn{\polyglossia at 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 at error{fontsetup~should~be~true~or~false. Is "##1"~ for~ language~ "#1"}}
+       \prop_gput:Nnn{\polyglossia at langsetup}{#1/fontsetup}{##1}
+       },
+    #1 / fontsetup
+      .default:n = true,
+    #1 / fontsetup
+      .initial:n = false,
+    % environment name
+    #1 / envname
+       .code:n = {
+           \prop_gput:Nnn{\polyglossia at 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 at 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 at langsetup}{#1/localnumeral}{##1}
+            \prop_gput:Nnn{\polyglossia at langsetup}{#1/Localnumeral}{##1}
+         },
+    #1 / localnumeral.value_required:n = true,
+    #1 / localnumeral.initial:n = {polyglossia at C@localnumeral},
+    % uppercased
+    #1 / Localnumeral
+         . code:n =  {
+            \prop_gput:Nnn{\polyglossia at langsetup}{#1/Localnumeral}{##1}
+         },
+    #1 / Localnumeral.value_required:n = true,
+    #1 / Localnumeral.initial:n = {polyglossia at C@localnumeral}
+  }
+}
+
+% TODO move to C module
+\newcommand*{\polyglossia at C@localnumeral}[2]{
+   \polyglossia at 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 at 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 at 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 at 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 at lang@frenchspacing:n}{
+  \prop_get:NxNTF \polyglossia at langsetup {#1/frenchspacing} \l_tmpa_tl
+      {
+        \str_case_e:nnF{\l_tmpa_tl}{
+          {true}{\frenchspacing}
+          {false}{\nonfrenchspacing}
+        }
+        {\xpg at error{frenchspacing~should~be~true~or~false. Is~"\l_tmpa_ttl"~ for~ language~ "#1"}}
+      }
+      {
+        \xpg at error{Could~ not~ retrieve~ key~ frenchspacing~ for~ language~ "#1"}
+        \prop_show:N{\polyglossia at langsetup}
+      }
+}
+
+\cs_new_nopar:Nn{\polyglossia at lang@indentfirst:n}{
+  \prop_get:NxNTF \polyglossia at langsetup {#1/indentfirst} \l_tmpa_tl
+      {
+        \str_case_e:nnF{\l_tmpa_tl}{
+          {true}{\french at indent}
+          {false}{\nofrench at indent}
+        }
+        {\xpg at error{indentfirst~should~be~true~or~false. Is~"\l_tmpa_ttl"~ for~ language~ "#1"}}
+      }
+      {
+        \xpg at error{Could~ not~ retrieve~ key~ indentfirst~ for~ language~ "#1"}
+        \prop_show:N{\polyglossia at langsetup}
+      }
+}
+
+
+\cs_new:Nn{\polyglossia at lang@setpardirection:n}{
+  \prop_get:NxNTF \polyglossia at langsetup {#1/direction} \l_tmpa_tl
+      {
+        \polyglossia at setpardirection:n{\l_tmpa_tl}
+      }
+      {
+        \xpg at error{Could~ not~ retrieve~ key~ direction~ for~ language~ "#1"}
+        \prop_show:N{\polyglossia at langsetup}
+      }
+}
+
+
+\cs_new:Nn{\polyglossia at lang@settextdirection:nn}{
+  \prop_get:NxNTF \polyglossia at langsetup {#1/direction} \l_tmpa_tl
+      {
+        \polyglossia at settextdirection:n{\l_tmpa_tl}{#2}
+      }
+      {
+        \xpg at error{Could~ not~ retrieve~ key~ direction~ for~ language~ "#1"}
+        \prop_show:N{\polyglossia at langsetup}
+      }
+}
+
+\AtEndDocument{\prop_log:N{\polyglossia at langsetup}}
+\def\xpg at lastlanguage{0}%
+
+\providebool{xpg at hyphenation@disabled}%
+\boolfalse{xpg at hyphenation@disabled}
+
+\def\xpg at 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 at AtBeginDocument@hyphenation: {
+        \xpg@@disablehyphenation%
+     }%
+  \fi%
+}
+
+\def\xpg@@disablehyphenation{%
+  \ifbool{xpg at hyphenation@disabled}{}{%
+    \booltrue{xpg at hyphenation@disabled}%
+    \xdef\xpg at lastlanguage{\the\language}%
+    % We do not call \xpg at set@hyphenation at patterns here to avoid a warning message.
+    % "nohyphenation" is not listed in language.dat.lua.
+    \language=\l at nohyphenation%
+  }%
+}
+
+\def\xpg at enablehyphenation{%
+  \ifbool{xpg at hyphenation@disabled}{%
+    \boolfalse{xpg at hyphenation@disabled}%
+    \language=\csname xpg at lastlanguage\endcsname%
+  }{}%
+}
+
+\let\disablehyphenation\xpg at disablehyphenation
+\let\enablehyphenation\xpg at enablehyphenation
+
+%\def\xpg at fontsetup#1{\xpg at csifdef@warn{xpg at fontsetup@#1}}
+%\def\xpg at fontsetup@none#1{\csgdef{#1 at font}{\ifcsdef{#1font}{\csname #1font\endcsname}{}}} %<-- simplistic
+%\def\xpg at fontsetup@custom#1{\csuse{#1 at font}}
+
+\cs_new:Nn \polyglossia at lang@autosetupfont:n {
+  \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/fontsetup}}{true}
+  {
+    \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/lcscript}}{latin}%
+         {\xpg at fontsetup@latin{#1}}
+         {\xpg at fontsetup@nonlatin{#1}}
+  }
+  {
+    \xpg at 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 at addfontfeature@language:nn {
+  \bool_if:nTF{\tl_if_empty_p:n{#1} || \tl_if_empty_p:n{#2}}
+  {
+    % maybe an error ?
+    \xpg at 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 at 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 at addfontfeature@script:nn {
+  \bool_if:nTF{\tl_if_empty_p:n{#1} || \tl_if_empty_p:n{#2}}
+  {
+    % maybe an error ?
+    \xpg at warning{Asking~ to~ add~ empty~ feature~to~ latin~ font
+                 (Script="#2"~ to~ scripttag~ "#1")}
+  }
+  {
+    \fontspec_if_script:nTF{#1}
+       {\addfontfeature{Script=#2}}
+       {\xpg at 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 at addfontfeature@script:nn { on , no, oo , Vn, nV, VV , xn, nx, xx}
+
+\def\xpg at fontsetup@latin#1{%
+  \begingroup
+  \csgdef{#1 at font@rm}{%
+    \cs_if_exist_use:cF{#1font}{
+      \rmfamilylatin
+      \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+    }
+  }
+  \csgdef{#1 at font@sf}{%
+    \cs_if_exist_use:cF{#1fontsf}{
+      \sffamilylatin
+      \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+    }%
+  }%
+  \csgdef{#1 at font@tt}{%
+    \cs_if_exist_use:cF{#1fonttt}{
+      \ttfamilylatin
+      \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+    }%
+  }%
+  \endgroup
+}
+
+\def\xpg at fontsetup@nonlatin#1{%
+  \begingroup
+  \csgdef{#1 at font@rm}{%
+    \cs_if_exist_use:cF{#1font}
+      {
+       \providetoggle{#1 at use@script at font}%
+       \str_if_eq:nnTF{\prop_item:Nn{\polyglossia at langsetup}{#1/script}}{\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+        {\rmfamilylatin}%
+        {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia at langsetup}{#1/lcscript} font}
+          {
+             \toggletrue{#1 at use@script at font}%
+           }
+           {
+             \rmfamilylatin
+           }
+       }
+       \iftoggle{#1 at use@script at font}{}{%
+           \polyglossia at addfontfeature@script:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/scripttag}}
+                                                 {\prop_item:Nn{\polyglossia at langsetup}{#1/script}}
+       }%
+       \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+      }}%
+  \csgdef{#1 at font@sf}{%
+    \cs_if_exist_use:cF{#1fontsf}%
+      {
+       \providetoggle{#1 at use@script at fontsf}%
+       \str_if_eq:nnTF{\prop_item:Nn{\polyglossia at langsetup}{#1/script}}{\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+        {\sffamilylatin}%
+        {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia at langsetup}{#1/lcscript} fontsf}
+          {
+             \toggletrue{#1 at use@script at fontsf}%
+           }
+           {
+             \sffamilylatin
+           }
+       }
+       \iftoggle{#1 at use@script at fontsf}{}{%
+           \polyglossia at addfontfeature@script:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/scripttag}}
+                                                 {\prop_item:Nn{\polyglossia at langsetup}{#1/script}}
+       }%
+       \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+      }}%
+  \csgdef{#1 at font@tt}{%
+    \cs_if_exist_use:cF{#1fonttt}%
+      {
+       \providetoggle{#1 at use@script at fonttt}%
+       \str_if_eq:nnTF{\prop_item:Nn{\polyglossia at langsetup}{#1/script}}{\prop_item:Nn{\polyglossia at langsetup}{#1/language}}
+       {\ttfamilylatin}%
+       {\cs_if_exist_use:cTF{\prop_item:Nn{\polyglossia at langsetup}{#1/lcscript} fonttt}
+           {
+             \toggletrue{#1 at use@script at fonttt}%
+           }
+           {
+             \ttfamilylatin
+           }
+       }
+       \iftoggle{#1 at use@script at fonttt}{}{%
+           \polyglossia at addfontfeature@script:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/scripttag}}
+                                                 {\prop_item:Nn{\polyglossia at langsetup}{#1/script}}
+       }%
+       \polyglossia at addfontfeature@language:xx{\prop_item:Nn{\polyglossia at langsetup}{#1/langtag}}
+                                              {\prop_item:Nn{\polyglossia at 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 at local@marks:n} {}
+\cs_new_nopar:Nn {\polyglossia at enable@local at marks:}
+{
+      \xpg at info{Option:~ localmarks}%
+      \cs_gset_nopar:Nn \polyglossia at local@marks:n
+      {%
+         \def\xpg at tmp@lang{##1}%
+         \DeclareRobustCommand\markboth[2]{%
+            \begingroup
+               \let\label\relax \let\index\relax \let\glossary\relax
+               \unrestored at protected@xdef\@themark
+               {%
+                {\lowercase{\foreignlanguage{\xpg at tmp@lang}}{\protect\@@ensure at maindir{####1}}}%
+                {\lowercase{\foreignlanguage{\xpg at tmp@lang}}{\protect\@@ensure at maindir{####2}}}%
+               }%
+               \@temptokena \expandafter{\@themark}%
+               \mark{\the\@temptokena}%
+            \endgroup
+            \if at nobreak\ifvmode\nobreak\fi\fi%
+         }%
+         \DeclareRobustCommand\markright[1]{%
+            \begingroup
+               \let\label\relax \let\index\relax \let\glossary\relax
+               \expandafter\@markright\@themark
+               {\lowercase{\foreignlanguage{\xpg at tmp@lang}}{\protect\@@ensure at maindir{####1}}}%
+               \@temptokena \expandafter{\@themark}%
+               \mark{\the\@temptokena}%
+            \endgroup
+            \if at 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 at maindir{####1}}%
+%            \unrestored at protected@xdef\@themark{%
+%               {\the\@temptokena}%
+%               {\protect\@@ensure at maindir{####3}}%
+%            }%
+%         }%
+      }%
+}
+
+
+% Easy way out – Arthur, 2012-08-01
+\ifcsdef{newXeTeXintercharclass}{%
+% to reset the intercharclass of a character to "normal"
+\newXeTeXintercharclass\xpg at normalclass %TODO
+}{}
+
+\ifxetex
+%% when no patterns are available, we use \l at nohyphenation, assigned to 255
+%%  (suggestion by Enrico Gregorio)
+  \@ifundefined{l at nohyphenation}{\chardef\l at nohyphenation=255 }{}
+\else\ifluatex
+  \@ifundefined{l at nohyphenation}{\chardef\l at 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 at nogloss#1{%
+   \xpg at 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 at nohyphenation\relax}%
+  %  {\setlocalhyphenmins{#1}{2}{3}}%
+  %\csdef{#1 at language}{\language=\csname l@#1\endcsname}%
+}
+
+\newcommand{\xpg at input}[1]{%
+  % Store catcode of @ before making at letter
+  \chardef\xpg at saved@at at catcode\catcode`\@
+  \makeatletter
+  \input{#1}%
+  % restore former @ catcode
+  \catcode`\@=\xpg at saved@at 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 at restore@tilde at catcode{\catcode 126 = \the\catcode 126\relax}
+    \catcode 126 = 13
+    \xpg at input{gloss-#2.ldf}
+    \setkeys{#2}{#1}
+    % restore former ~ catcode
+    \xpg at restore@tilde at catcode
+  }
+  {
+    \xpg at nogloss{#2}
+  }
+}
+
+% load a master language from an alias file
+\newcommand*\xpg at load@master at language[1] {
+   \xpg at input{gloss-#1.ldf}
+   \ifcsundef{#1 at loaded}%
+   {
+     \exp_args:Nx\polyglossia at define@language at cmd:n{#1}%
+   }{}
+   \polyglossia at register@language:nn{}{#1}%
+   \csgdef{#1 at loaded}{}%
+}
+
+
+% define environment and command
+\cs_new:Nn \polyglossia at define@language at cmd:n {
+  \ifcsundef{#1 at alias@lang}{%
+    \exp_args:Ne
+    \newenvironment {\prop_item:Nn{\polyglossia at langsetup}{#1/envname}} [1] []
+    {
+      \begin{otherlanguage}[##1]{#1}
+    }%
+    {
+      \end{otherlanguage}
+    }%
+    \exp_args:Nc \newcommand {text#1} [2][]
+    {%
+      \xpg at textlanguage[##1]{#1}{##2}%
+    }%
+  }{}
+}
+
+% provide way to define alias environment and command
+% \setlanguagealias[<options>]{<language>}{<alias>}
+\DeclareDocumentCommand \setlanguagealias {s O{} m m}
+{
+  % The starred version does not define commands and environments
+  \IfBooleanF {#1}
+    {
+     \ifcsundef{#4 at alias@lang}{%
+       \exp_args:Ne
+       \newenvironment {#4}
+       {
+         \begin{otherlanguage}[#2]{#3}
+       }%
+       {
+         \end{otherlanguage}
+       }%
+       \exp_args:Nc \newcommand {text#4} [2][]
+       {%
+         \xpg at textlanguage[#2,##1]{#3}{##2}%
+       }%
+     }{%
+       \exp_args:Ne
+       \renewenvironment {#4}
+       {
+         \begin{otherlanguage}[#2]{#3}
+       }%
+       {
+         \end{otherlanguage}
+       }%
+       \exp_args:Nc \renewcommand {text#4} [2][]
+       {%
+         \xpg at textlanguage[#2,##1]{#3}{##2}%
+       }%
+     }%
+  }%
+  \csgdef{#4 at alias@lang}{#3}%
+  \tl_if_blank:nF {#2} {\csgdef{#4 at alias@opts}{#2}}%
+}
+
+\cs_new:Nn \polyglossia at register@language:nn {
+   % register polyglossia language name
+   \ifcsundef{#2 at registered}{%
+       \global\edef\xpg at loaded{%
+           \ifx\xpg at loaded\@empty\else\xpg at loaded,\fi #2%
+        }%
+   }{}
+   \csgdef{#2 at registered}{}%
+   \tl_if_blank:nF {#1}{%
+      % Register the language options
+      \polyglossia at set@lang at options:nn {#2} {#1}%
+   }%
+   % register babelname
+   \def\xpg at tmp@babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+   \ifcsundef{\csname xpg at tmp@babelname\endcsname @bbl at registered}{%
+       \global\edef\xpg at bloaded{%
+           \ifx\xpg at bloaded\@empty\else\xpg at bloaded,\fi\xpg at tmp@babelname}%
+   }{}%
+   \csgdef{\csname xpg at tmp@babelname\endcsname @bbl at registered}{}%
+   % register BCP-47 ID
+   \def\xpg at tmp@bcpname{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+   \ifcsundef{\csname xpg at tmp@bcpname\endcsname @bcp at registered}{%
+       \global\edef\xpg at bcp@loaded{%
+           \ifx\xpg at bcp@loaded\@empty\else\xpg at bcp@loaded,\fi\xpg at tmp@bcpname}%
+   }{}%
+   \csgdef{\csname xpg at tmp@bcpname\endcsname @bcp at registered}{}%
+}
+
+
+\newcommand{\setdefaultlanguage}[2][]{%
+  \ifcsundef{#2 at loaded}%
+  {
+    \polyglossia_load_lang_definition:nn{#1}{#2}
+    % define environment and command (except for internal latex language)
+    \ifstrequal{#2}{latex}{}{%
+      \exp_args:Nx\polyglossia at define@language at cmd:n{#2}
+    }%
+    \csgdef{#2 at loaded}{}%
+  }
+  {
+    \relax
+  }
+  \ifcsdef{#2 at alias@lang}{%
+     \ifcsdef{#2 at alias@opts}{%
+       \exp_args:Nxx \polyglossia_load_lang_definition:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+       \exp_args:Nxx \polyglossia at set@default at language:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+     }{%
+       \polyglossia at set@default at language:nn {#1} {\csuse{#2 at alias@lang}}%
+     }%
+  }{%
+    \polyglossia at set@default at language:nn {#1} {#2}%
+  }%
+}
+
+\cs_new:Nn \polyglossia at set@default at language:nn
+{
+  \gdef\xpg at main@language{#2}%
+  \tl_if_blank:nTF {#1}{\gdef\mainlanguagevariant{}}{%
+     % Register the language options
+     \polyglossia at set@lang at options:nn {#2} {#1}%
+  }%
+  \csgdef{#2 at 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 at langsetup}{#2/direction}}{RL}{%
+    \str_case_e:nnF{\c_sys_engine_str}{%
+      {luatex}{\setRTLmain}
+      {xetex}{\@RTLmaintrue\setnonlatin}
+    }{}%
+  }{}%
+  \cs_gset_nopar:Nn \polyglossia at AtBeginDocument@selectlanguage: {
+    \selectbackgroundlanguage{#2}
+    \selectlanguage[#1]{#2}%
+  }
+  \xpg at info{Default~ language~ is~ #2}%
+  \polyglossia at set@language at name[#1]{#2}%
+  \def\mainlanguagename{#2}
+  % Store babelname of main language (for external packages such as biblatex)
+  \prop_get:NxNT \polyglossia at 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 at langsetup {#2/babelname} \l_tmpa_tl
+      { \edef\babelname{\l_tmpa_tl}% 
+        \cs_gset_eq:cc{#2 at gbabelname}{babelname}%
+      }
+  % Store BCP-47 id of main language
+  \prop_get:NxNT \polyglossia at langsetup {#2/bcp47} \l_tmpa_tl
+      { \csedef{mainbcp47id}{\l_tmpa_tl} }
+  % Store BCP-47 id of current language
+  \prop_get:NxNT \polyglossia at langsetup {#2/bcp47} \l_tmpa_tl
+      { \csedef{bcp47id}{\l_tmpa_tl}% 
+        \cs_gset_eq:cc{#2 at 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 at 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 at error{Invalid~ \string\mainlanguageid\space argument:~ #1}
+      }
+}
+
+\def\mainbabelname{}%
+\def\mainlanguagevariant{}%
+% Store main language variant for external packages
+\define at key{xpg at main@langvariant}{variant}{%
+  \gdef\mainlanguagevariant{#1}%
+}
+
+\def\babelname{}%
+\def\languagevariant{}%
+% Store current language variant for external packages
+\define at key{xpg at set@langvariant}{variant}{%
+  \def\languagevariant{#1}%
+}
+
+\newcommand*\polyglossia at set@language at name[2][]{
+  \def\languagename{#2}%
+  \tl_if_blank:nTF {#1}{%
+     \ifcsundef{#2 at gvar}{\def\languagevariant{}}{\def\languagevariant{\csuse{#2 at gvar}}}
+   }{%
+     % Register the language options
+     \polyglossia at set@lang at options:nn {#2} {#1}%
+  }%
+}
+
+
+\newcommand*{\resetdefaultlanguage}[2][]{%
+  \ifcsdef{#2 at alias@lang}{%
+     \ifcsdef{#2 at alias@opts}{%
+       \exp_args:Nxx \polyglossia at reset@default at language:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+     }{%
+       polyglossia at reset@default at language:nn {#1} {\csuse{#2 at alias@lang}}%
+     }%
+  }{%
+    polyglossia at reset@default at language:nn {#1} {#2}%
+  }%
+}
+
+\cs_new:Nn \polyglossia at reset@default at language:nn
+{
+  \polyglossia at error@iflangnotloaded:n{#2}
+  % disable globalnumbers of previously defined default language
+  \csuse{no\xpg at main@language @globalnumbers}
+  \csuse{noextras@\xpg at 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 at bbl@\mainbabelname}%
+  \csuse{init at noextras@\xpg at main@language}%
+  \polyglossia at set@language at name[#1]{#2}%
+  \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#2/direction}}{RL}{\@rlmaintrue\@rl at footnotetrue}{}%
+  \selectlanguage[#1]{#2}%
+  \selectbackgroundlanguage{#2}%
+  % Store babelname of current language (for external packages such as biblatex)
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbabelname}{%
+       \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+    }{%
+       \edef\babelname{\csuse{#2 at gbabelname}}%
+    }%
+  }{%
+    \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+  }%
+  % Store BCP-47 id of current language
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbcp47id}{%
+       \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+    }{%
+       \csedef{bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csedef{bcp47id}{\prop_item:Nn{\polyglossia at 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 at defaultfont@rm{%
+   \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+   \fontfamily\rmdefault%
+   \selectfont%
+}
+\DeclareRobustCommand\xpg at defaultfont@sf{%
+   \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+   \fontfamily\sfdefault%
+   \selectfont%
+}
+\DeclareRobustCommand\xpg at defaultfont@tt{%
+   \tl_if_empty:NF{\g__fontspec_nfss_enc_tl}{\fontencoding{\g__fontspec_nfss_enc_tl}}%
+   \fontfamily\ttdefault%
+   \selectfont%
+}
+
+\def\xpg at patch@fontfamilies{%
+  % This robustifies the redefinitions of \<xx>family (suggestion by Enrico Gregorio)
+  % e.g. to prevent expansion of the \familytype redefinition in auxiliary files
+  \csgappto{rmfamily~}{\def\familytype{rm}}
+  \csgappto{sffamily~}{\def\familytype{sf}}
+  \csgappto{ttfamily~}{\def\familytype{tt}}
+}
+
+% These switches activate the default fonts
+% Note that a simple \let\rmfamilylatin=\rmfamily
+% does not work reliably (see #24)
+\cs_gset_eq:cc{rmfamilylatin}{xpg at defaultfont@rm}%
+\cs_gset_eq:cc{sffamilylatin}{xpg at defaultfont@sf}%
+\cs_gset_eq:cc{ttfamilylatin}{xpg at defaultfont@tt}%
+
+\def\xpg at 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 at patch@fontfamilies%
+  % This (re-)saves the normalfont for the latin script since we may
+  % change normalfont in other scripts
+  \let\normalfontlatin=\normalfont%
+  % And for all cases, we also reset \<xx>familylatin
+  \cs_gset_eq:cc{rmfamilylatin}{xpg at defaultfont@rm}%
+  \cs_gset_eq:cc{sffamilylatin}{xpg at defaultfont@sf}%
+  \cs_gset_eq:cc{ttfamilylatin}{xpg at defaultfont@tt}%
+}
+
+\def\resetfontlatin{%
+  \DeclareRobustCommand\rmfamily{\xpg at defaultfont@rm}%
+  \DeclareRobustCommand\sffamily{\xpg at defaultfont@sf}%
+  \DeclareRobustCommand\ttfamily{\xpg at defaultfont@tt}%
+  \xpg at patch@fontfamilies%
+  \global\let\normalfont=\normalfontlatin%
+}
+
+\def\selectfontfamilylatin{%
+  \def\tmp at tt{tt}\def\tmp at sf{sf}%
+  \ifx\familytype\tmp at tt%
+    \ttfamilylatin%
+    \else\ifx\familytype\tmp at sf%
+      \sffamilylatin%
+      \else\rmfamilylatin\fi\fi}
+
+\def\xpg at select@fontfamily#1{%
+  \def\tmp at tt{tt}\def\tmp at sf{sf}%
+  \ifx\familytype\tmp at tt
+    \csuse at warn{#1 at font@tt}%
+  \else\ifx\familytype\tmp at sf
+    \csuse at warn{#1 at font@sf}%
+      \else\csuse at warn{#1 at font@rm}\fi\fi}
+
+\def\xpg at set@normalfont#1{%
+  \DeclareRobustCommand\rmfamily{\csuse{#1 at font@rm}}%
+  \DeclareRobustCommand\sffamily{\csuse{#1 at font@sf}}%
+  \DeclareRobustCommand\ttfamily{\csuse{#1 at font@tt}}%
+  \gdef\normalfont{\protect\xpg at select@fontfamily{#1}%
+                     \fontseries{\seriesdefault}\selectfont%
+                     \fontshape{\shapedefault}\selectfont}%
+  \gdef\reset at font{\protect\normalfont}%
+}
+
+\let\@@fterindentfalse\@afterindentfalse
+\def\french at indent{%
+    \let\@afterindentfalse\@afterindenttrue
+    \@afterindenttrue%
+}
+\def\nofrench at indent{%
+    \let\@afterindentfalse\@@fterindentfalse
+    \@afterindentfalse%
+}
+
+\newcommand*{\selectbackgroundlanguage}[1]{%
+  \ifcsdef{#1 at alias@lang}{%
+     \polyglossia at select@background at language:n {\csuse{#1 at alias@lang}}%
+  }{%
+     \polyglossia at select@background at language:n {#1}%
+  }%
+}
+
+\cs_new:Nn \polyglossia at select@background at language:n
+{
+  \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/lcscript}}{latin}
+                   {}
+                   {\xpg at set@normalfont{#1}}%
+  \csuse{#1 at globalnumbers}%
+}
+
+\newcommand{\setotherlanguage}[2][]{%
+  \ifcsundef{#2 at loaded}
+  {
+    \polyglossia_load_lang_definition:nn{#1}{#2}
+    % define environment and command
+    \exp_args:Nx\polyglossia at define@language at cmd:n{#2}
+    \ifcsdef{#2 at alias@lang}{%
+       \ifcsdef{#2 at alias@opts}{%
+         \exp_args:Nxx \polyglossia_load_lang_definition:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+         \exp_args:Nxx \polyglossia at set@other at language:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+       }{%
+         \polyglossia at set@other at language:nn {#1} {\csuse{#2 at alias@lang}}%
+       }%
+    }{%
+      \polyglossia at set@other at language:nn {#1} {#2}%
+    }%
+    \csgdef{#2 at loaded}{}%
+  }
+  {}
+}
+
+\cs_new:Nn \polyglossia at set@other at language:nn
+{
+  \polyglossia at register@language:nn{#1}{#2}%
+  % If a variant is set, store it.
+  \gdef\otherlanguagevariant{}
+  \tl_if_blank:nTF {#1}{}{%
+    % Register the language options
+    \polyglossia at set@lang at options:nn {#2} {#1}%
+  }%
+  \csgdef{#2 at gvar}{\otherlanguagevariant}%
+  \prop_get:NxNT \polyglossia at langsetup {#2/babelname} \l_tmpa_tl
+    { \xdef\otherlanguagebabelname{\l_tmpa_tl} }
+  \cs_gset_eq:cc{#2 at gbabelname}{otherlanguagebabelname}%
+}
+
+% Store main language variant for external packages
+\define at key{xpg at other@langvariant}{variant}{%
+  \gdef\otherlanguagevariant{#1}%
+}
+
+\newcommand\setotherlanguages[1]{%
+  \def\do##1{\setotherlanguage{##1}}%
+   \exp_args:Nx\docsvlist{#1}}%
+
+\def\common at language{% FIXME is this really needed???
+  \ifbool{xpg at hyphenation@disabled}{%
+    \xdef\xpg at lastlanguage{\z@}%
+  }{%
+    \language=\z@
+  }%
+  \lefthyphenmin=\tw@
+  \righthyphenmin=\thr@@}
+
+\def\xpg at initial@setup{%
+  \common at language%
+}
+
+
+% Alias to \text<lang>, but more suitable
+% for specific (esp. tag-based) aliases
+% where \text<alias> would cause clashes
+% (e.g., \textit)
+\newcommand\textlang[3][]{%
+  \ifcsdef{#2 at alias@lang}{%
+     \ifcsdef{#2 at alias@opts}{%
+       \exp_args:Nxx \xpg at textlanguage[\csuse{#2 at alias@opts},#1]{\csuse{#2 at alias@lang}}{#3}%
+     }{%
+       \xpg at textlanguage[#1]{\csuse{#2 at alias@lang}}{#3}%
+     }%
+  }{%
+    \xpg at textlanguage[#1]{#2}{#3}%
+  }%
+}%
+
+% Alias to {<lang>}, but more suitable
+% for specific (esp. tag-based) aliases
+% where {<alias>} would cause clashes
+% (e.g., \fi)
+\newenvironment{lang}[2][]{%
+  \begin{otherlanguage}[#1]{#2}%
+}{%
+  \end{otherlanguage}
+}%
+
+\providecommand{\foreignlanguage}{}
+
+% wrapper for foreignlanguage and otherlanguage*
+\newcommand*\polyglossia at setforeignlanguage[2][]{
+  \select@@language[#1]{#2}
+  \polyglossia at register@language:nn{#1}{#2}%
+  % Store babelname of current language (for external packages such as biblatex)
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbabelname}{%
+       \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+    }{%
+       \edef\babelname{\csuse{#2 at gbabelname}}%
+    }%
+  }{%
+    \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+  }%
+  % Store BCP-47 id of current language
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbcp47id}{%
+       \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+    }{%
+       \csedef{bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+  }%
+}
+
+% joint code of \foreignlanguage, otherlanguage*
+% and \text<lang>
+\newcommand{\xpg at otherlanguage}[2][]
+{%
+  \polyglossia at error@iflangnotloaded:n{#2}
+  \exp_args:Nne \setkeys{#2}{#1}%
+  \polyglossia at setforeignlanguage[#1]{#2}
+  % Hook for external packages such as biblatex
+  \polyglossia at 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 at bbl@\babelname}%
+}
+
+\renewcommand{\foreignlanguage}[3][]
+{%
+  \ifcsdef{#2 at alias@lang}{%
+     \ifcsdef{#2 at alias@opts}{%
+       \exp_args:Nxx \polyglossia at foreignlanguage:nnn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}} {#3}%
+     }{%
+       \polyglossia at foreignlanguage:nnn {#1} {\csuse{#2 at alias@lang}} {#3}%
+     }%
+  }{%
+    \polyglossia at foreignlanguage:nnn {#1} {#2} {#3}%
+  }%
+}
+
+\cs_new:Nn \polyglossia at foreignlanguage:nnn
+{
+   \polyglossia at error@iflangnotloaded:n{#2}
+   \bgroup
+   \xpg at otherlanguage[#1]{#2}%
+   \polyglossia at lang@settextdirection:nn{#2}{#3}%
+   \egroup
+}
+
+% otherlanguage* is the environment equivalent of \foreignlanguage
+\expandafter\providecommand\csname otherlanguage*\endcsname{}
+
+\renewenvironment{otherlanguage*}[2][]
+{%
+  \ifcsdef{#2 at alias@lang}{%
+     \ifcsdef{#2 at alias@opts}{%
+       \exp_args:Nxx \polyglossia at otherlanguage:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
+     }{%
+       \polyglossia at otherlanguage:nn {#1} {\csuse{#2 at alias@lang}}%
+     }%
+  }{%
+    \polyglossia at otherlanguage:nn {#1} {#2}%
+  }%
+}
+{\egroup}
+
+\cs_new:Nn \polyglossia at otherlanguage:nn
+{
+  \xpg at otherlanguage[#1]{#2}%
+  \polyglossia at lang@settextdirection:nn{#2}\bgroup%
+}
+
+% use by \text<lang> and \textlang. Equivalent to \foreignlanguage,
+% except that dates are localized.
+\newcommand\xpg at textlanguage[3][]{%
+  \polyglossia at error@iflangnotloaded:n{#2}
+   \bgroup
+   \xpg at 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 at bbl@\babelname}%
+   \polyglossia at lang@settextdirection:nn{#2}{#3}%
+   \egroup
+  % Reset the language's/script's font families
+  \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#2/lcscript}}{latin}{}{\resetfontlatin}%
+}
+
+
+% Define language-specific hyphenation exceptions
+\newcommand\pghyphenation[3][]{
+  \bgroup
+  \polyglossia at 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 at hook@setlanguage}{}
+
+\def\xpg at pop@language at i#1#2{%
+  \xpg at set@language at aux[#1]{#2}%
+  \xpg at hook@setlanguage
+  \let\emp at langname\@undefined}
+
+\DeclareDocumentCommand \selectlanguage {s O{} m}
+{%
+  \ifcsdef{#3 at alias@lang}{%
+     \ifcsdef{#3 at alias@opts}{%
+       \exp_args:Nxx \polyglossia at select@language:nnn {#1} {\csuse{#3 at alias@opts},#2} {\csuse{#3 at alias@lang}}%
+     }{%
+       \polyglossia at select@language:nnn {#1} {#2} {\csuse{#3 at alias@lang}}%
+     }%
+  }{%
+     \polyglossia at error@iflangnotloaded:n{#3}%
+     \polyglossia at select@language:nnn {#1} {#2} {#3}%
+  }
+}
+
+\cs_new:Nn \polyglossia at select@language:nnn
+{
+  \IfBooleanF {#1}
+    {
+      \cs_set_nopar:Npx \xpg at pop@language { \exp_not:N \xpg at pop@language at i {#2} {#3} }
+      \group_insert_after:N \xpg at pop@language
+    }
+  \tl_if_blank:nTF {#2}{}{%
+    % Register the language options
+    \polyglossia at set@lang at options:nn {#3} {#2}%
+   }%
+   % The starred variant does not write to the aux
+   \IfBooleanTF#1{%
+     \xpg at set@language at nonaux[#2]{#3}%
+   }{%
+     \xpg at set@language at aux[#2]{#3}%
+   }%
+   \ifluatex%
+     \directlua{polyglossia.select_language('\luatexluaescapestring{\string#3}',
+                     \the\csname l@#3\endcsname)}%
+   \fi%
+  \polyglossia at register@language:nn{#2}{#3}%
+}
+
+
+\cs_new:Nn \polyglossia at set@lang at options:nn
+{  
+    % If the optional argument sets a value for the key “variant”, copy it to xpg at langvariant
+    \clist_map_inline:nn { #2 } {%
+        \xpg at parsevariantkeyvalue##1=@xpg at 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 at initialize@gloss at options[2]{%
+   \polyglossia at set@lang at options:nn {#1} {#2}%
+}
+
+% Record synonymous keyvals such as variant=us and variant=american
+% Syntax: \xpg at set@alias at values{<lang>}{<key>}{<val>}{<alias vals, comma-separated>}
+\newcommand*\xpg at set@alias at values[4]{%
+   \prop_if_exist:cF { xpg at alias@keyvals@#1@#3 }
+      { \prop_new:c {xpg at alias@keyvals@#1@#3} }
+   \prop_put:cnn { xpg at alias@keyvals@#1@#3 }
+      {#2}{#4}
+   \prop_put:cnn { xpg at alias@keyvals@#1@#4 }
+      {#2}{#3}
+}
+
+% Patch xkeyval to record default values of keys
+\pretocmd{\XKV at define@default}{%
+   \csgdef{xpg at default@opt@\XKV at header #1}{#2}%
+}{}{\xpg at warning{Patching xkeyval failed!}}
+
+% Helper to get and register option keyvals
+\def\xpg at parsevariantkeyvalue#1=#2@#3:#4\relax{%
+   \def\@tmpa{#1}
+   \def\@tmpb{variant}
+   % variant values are stored in specific macros
+   % (\xpg at main@langvariant, \xpg at other@langvariant
+   % and \xpg at set@langvariant)
+   \ifx\@tmpa\@tmpb\setkeys{#3}{#1=#2}\fi
+   \tl_if_empty:nTF{#2}
+      {
+        \ifcsdef{xpg at default@opt at KV@#4@#1}%
+           {\xpg at store@opt at keyval#1:\csuse{xpg at default@opt at KV@#4@#1}=:#4\relax}%
+           {}%
+      }
+      { \xpg at store@opt at keyval#1:#2:#4\relax }
+}%
+
+% Store option keys and values
+% This strips trailing '=' from values.
+\def\xpg at store@opt at keyval#1:#2=:#3\relax{%
+   \prop_if_exist:cF { xpg at current@options@#3 }
+      { \prop_new:c {xpg at current@options@#3} }
+   \prop_put:cnn { xpg at current@options@#3 }
+      {#1}{#2}
+}
+
+
+\prg_set_conditional:Npnn \polyglossia at check@option at value:NNN #1#2#3 { p , T , F , TF }
+{
+  \prop_get:cnNTF {xpg at 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 at 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 at check@option at value:NNNTF{#1}{#2}{#3}{#4}{#5}%
+}
+
+
+% Append any variant to csv list of variants
+\define at key{xpg at langvariant}{variant}{%
+  \edef\xpg at vloaded{#1\ifx\xpg at vloaded\@empty\else,\xpg at vloaded\fi}%
+}
+
+\prg_set_conditional:Npnn \polyglossia at check@if at 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 at check@if at lang@loaded:NTF{#1 at loaded}{#2}{#3}%
+}
+
+% Same for babellanguage is loaded
+\newcommand*\ifbabellanguageloaded[3]{%
+  \polyglossia at check@if at lang@loaded:NTF{#1 at bbl@loaded}{#2}{#3}%
+}
+
+% Same for languageid
+\DeclareDocumentCommand \iflanguageidloaded {mmmm}
+{
+    \str_case:nnTF {#1}
+      {
+        {bcp-47}    { \polyglossia at check@if at lang@loaded:NTF{#2 at bcp@loaded}{#3}{#4} }
+        {bcp47}     { \polyglossia at check@if at lang@loaded:NTF{#2 at bcp@loaded}{#3}{#4} }
+      }
+      {}
+      {
+        \xpg at error{Invalid~ \string\iflanguageidloaded\space argument:~ #1}
+      }
+}
+
+% Check if the current font has a given glyph
+\prg_set_conditional:Npnn \polyglossia at check@if at 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 at 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 at if@char at available[3]{%
+  \polyglossia at check@if at char@available:NTF{#1}{#2}{#3}%
+}
+
+\newcommand*\charifavailable[2]{%
+   \xpg at if@char at available{#1}{\char"#1}{#2}%
+}
+
+
+\newcommand*{\xpg at set@language at nonaux}[2][]{%
+   \@select at language[#1]{#2}%
+}
+
+
+\newcommand*{\xpg at set@language at aux}[2][]{%
+   % Store babelname of current language (for external packages such as biblatex)
+   \tl_if_blank:nTF {#1}{%
+     \ifcsundef{#2 at gbabelname}{%
+        \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+     }{%
+        \edef\babelname{\csuse{#2 at gbabelname}}%
+     }%
+   }{%
+     \edef\babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+   }%
+   % Store BCP-47 id of current language
+   \tl_if_blank:nTF {#1}{%
+     \ifcsundef{#2 at gbcp47id}{%
+        \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+     }{%
+        \csedef{bcp47id}{\csuse{#2 at gbcp47id}}%
+     }%
+   }{%
+     \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+   }%
+   \@select at language[#1]{#2}%
+    % Write to the aux
+   \if at filesw%
+      \ifx#1\\\\%
+          \protected at write\@auxout{}{\protect\selectlanguage*{#2}}%
+          \addtocontents{toc}{\protect\selectlanguage*{#2}}%
+          \addtocontents{lof}{\protect\selectlanguage*{#2}}%
+          \addtocontents{lot}{\protect\selectlanguage*{#2}}%
+       \else
+          \protected at 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 at inbiditable}
+\AtBeginDocument{%
+  \@ifpackageloaded{bidi}{%
+     \patchcmd{\@tabular}%
+               {\if at RTLtab}%
+               {\if at RTLtab\booltrue{xpg at inbiditable}}%
+               {}% success
+               {\xpg at 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 at set@group at aux}{%
+   \if at filesw%
+      \ifbool{xpg at inbiditable}{%
+        \protected at write\@auxout{}{\egroup}%
+        \addtocontents{toc}{\egroup}%
+        \addtocontents{lof}{\egroup}%
+        \addtocontents{lot}{\egroup}%
+      }{%
+        \protected at 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 at unset@group at aux}{%
+   \if at filesw%
+      \ifbool{xpg at inbiditable}{%
+        \protected at write\@auxout{}{\bgroup}%
+        \addtocontents{toc}{\bgroup}%
+        \addtocontents{lof}{\bgroup}%
+        \addtocontents{lot}{\bgroup}%
+      }{%
+        \protected at write\@auxout{}{\egroup}%
+        \addtocontents{toc}{\egroup}%
+        \addtocontents{lof}{\egroup}%
+        \addtocontents{lot}{\egroup}%
+      }%
+    \fi
+}
+
+\prg_set_conditional:Npnn \polyglossia at check@ifdefined:N #1 { p , T , F , TF }{
+  \cs_if_exist:cTF {l@#1}
+    {
+      \cs_if_eq:cNTF {l@#1} \l at 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 at luatex@load at lang#1{%
+  % if \l@#1 is not properly defined, call lua function newloader(#1),
+  % and assign the returned number to \l@#1
+  \polyglossia at 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 at ifdefined[3]{%
+    % With luatex, we first need to define \l@#1.
+    \ifluatex
+      \polyglossia at luatex@load at lang{#1}%
+    \fi
+    \polyglossia at check@ifdefined:NTF{#1}{#2}{#3}%
+}%
+
+% Set \bbl at hyphendata@\the\language, which is (lua)babel's
+% hyphenation pattern hook
+% FIXME Clarifiy why/when this is needed.
+\newcommand*\xpg at set@bbl at hyphendata[1]{%
+    \ifluatex%
+        \ifcsdef{bbl at hyphendata@#1}{}{%
+            \global\@namedef{bbl at hyphendata@\the\language}{}%
+        }%
+    \fi% 
+}
+
+% Set hyphenation patterns for a given language. This does the right
+% thing both for XeTeX and LuaTeX
+\newcommand*\xpg at set@hyphenation at patterns[1]{%
+  \ifluatex
+    \polyglossia at luatex@load at lang{#1}%
+    \language=\csname l@#1\endcsname
+  \else
+    \ifxetex
+      \language=\csname l@#1\endcsname
+    \else
+      \xpg at 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 at language[2][]{
+   % hook for compatibility with biblatex
+   \select at language{#2}
+   \xpg at set@bbl at hyphendata{\the\language}
+   \xpg at initial@setup%
+   \select@@language[#1]{#2}%
+   % Hook for external packages such as biblatex
+   \polyglossia at language@switched%
+   \polyglossia at 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 at bbl@\babelname}%
+   \cs_if_exist_use:c{date at bbl@\babelname}%
+   \polyglossia at local@marks:n{#2}%
+   \csuse{init at extras@#2}%
+   \polyglossia at 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 at 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 at language#1{}
+
+% Hook for external packages such as biblatex
+\def\polyglossia at 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 at bbl@\babelname}
+}
+
+% Common code for `\select at 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 at langsetup}{\languagename/direction}}{RL}%
+            {%
+               \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#2/direction}}{RL}%
+                  {}% RTL -> RTL
+                  {\setlatin}% RTL -> LTR
+            }{%
+               \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#2/direction}}{RL}%
+                  {\setnonlatin}% LTR -> RTL
+                  {}% LTR -> LTR
+           }%
+     \fi
+  }%
+  \polyglossia at set@language at name[#1]{#2}%
+  % Set the language's/script's font families
+  \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#2/lcscript}}{latin}{\resetfontlatin}{\xpg at set@normalfont{#2}}%
+  \xpg at select@fontfamily{#2}%
+  \csuse at warn{#2 at language}%
+  \csuse{#2 at numbers}%
+  \use at localhyphenmins[#1]{#2}%
+  \polyglossia at lang@frenchspacing:n{#2}
+}
+
+
+\let\xpg at pop@language\relax
+
+\provideenvironment{otherlanguage}{}{}
+
+\newbool{xpg at 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 at langsetup}{\languagename/direction}}{RL}%
+       {%
+        \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/direction}}{RL}%
+           {}% RTL -> RTL
+           {\ifvmode\else\booltrue{xpg at noset@groups}\fi}% RTL -> LTR
+       }%
+  \fi%
+  \ifbool{xpg at noset@groups}{}{\xpg at set@group at aux}%
+  \selectlanguage[#1]{#2}%
+}
+{\ifbool{xpg at noset@groups}{}{\xpg at unset@group at aux}}
+
+\newcommand{\setlocalhyphenmins}[3]{%
+   \xpg at ifdefined{#1}{%
+      \expandafter\ifx\csname l@#1\endcsname\l at nohyphenation%
+        \xpg at warning{\string\setlocalhyphenmin\space~ useless~ for~ unhyphenated~ language~ #1}%
+      \else
+      \providehyphenmins{#1}{#2#3}%
+      \fi
+   }{%
+     \xpg at 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 at tmp@lang{#2}%
+  \edef\xpg at tmp@opts{#1}%
+  \ifcsdef{#2 at alias@lang}{%
+     \edef\xpg at tmp@lang{\csuse{#2 at alias@lang}}%
+     \ifcsdef{#2 at alias@opts}{%
+       \edef\xpg at tmp@opts{\csuse{#2 at alias@opts},#1}%
+     }{}%
+  }{}%
+  \bgroup
+  \polyglossia at error@iflangnotloaded:n{\xpg at tmp@lang}
+  \exp_args:Nne \setkeys{\xpg at tmp@lang}{\xpg at tmp@opts}%
+  % Store BCP-47 id of language
+  \tl_if_blank:nTF {\xpg at tmp@opts}{%
+    \ifcsundef{\csname xpg at tmp@lang\endcsname @gbcp47id}{%
+       \csedef{tmp at bcp47id}{\exp_args:Nne\prop_item:Nn{\polyglossia at langsetup}{\xpg at tmp@lang /bcp47}}%
+    }{%
+       \csedef{tmp at bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csedef{tmp at bcp47id}{\exp_args:Nne \prop_item:Nn{\polyglossia at langsetup}{\xpg at tmp@lang /bcp47}}%
+  }%
+  \xpg at warning{id: \csuse{tmp at bcp47id}}%
+  \csgdef{\csname tmp at bcp47id\endcsname @hyphenmins}{{#3}{#4}}%
+  \egroup
+}
+
+% \use at localhypenmins[options]{lang}
+\newcommand*\use at localhyphenmins[2][]{%
+  \bgroup
+  \polyglossia at error@iflangnotloaded:n{#2}
+  \setkeys{#2}{#1}%
+  % Store BCP-47 id of language
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbcp47id}{%
+       \csxdef{tmp at bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+    }{%
+       \csxdef{tmp at bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csxdef{tmp at bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+  }%
+  \egroup
+  \ifcsundef{\csname tmp at bcp47id\endcsname @hyphenmins}{%
+     \ifcsundef{#2hyphenmins}{}%
+        {%
+          \expandafter\expandafter\expandafter\set at hyphenmins\csname #2hyphenmins\endcsname\relax%
+        }
+   }{%
+      \edef\tmpa{\csuse{\csname tmp at bcp47id\endcsname @hyphenmins}}%
+      \expandafter\expandafter\expandafter\set at hyphenmins\tmpa\relax%
+   }
+   \ifluatex
+     % Set \totalhyphenmin if specified
+     \prop_get:NxNTF \polyglossia at langsetup {#2/totalhyphenmin} \l_tmpa_tl
+     {
+        \xpg at 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 at langsetup}{\languagename/direction}}{RL}%
+       {%
+        \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/direction}}{RL}%
+           {}% RTL -> RTL
+           {\ifvmode\else\booltrue{xpg at noset@groups}\fi}% RTL -> LTR
+       }%
+  \fi%
+  \ifbool{xpg at noset@groups}{}{\xpg at set@group at aux}%
+  % Check for real language name and options
+  \edef\xpg at tmp@lang{#2}%
+  \edef\xpg at tmp@opts{#1}%
+  \ifcsdef{#2 at alias@lang}{%
+     \edef\xpg at tmp@lang{\csuse{#2 at alias@lang}}%
+     \ifcsdef{#2 at alias@opts}{%
+       \edef\xpg at tmp@opts{\csuse{#2 at alias@opts},#1}%
+     }{}%
+  }{}%
+  \tl_if_blank:nF {\xpg at tmp@opts}{%
+     % Register the language options
+     \polyglossia at set@lang at options:nn {\xpg at tmp@lang} {\xpg at tmp@opts}%
+  }%
+  % Now switch patterns
+  \csuse at warn{\csuse{xpg at tmp@lang}@language}%
+  % And activate hyphenmins
+  \use at localhyphenmins[\xpg at tmp@opts]{\xpg at tmp@lang}%
+}
+{\ifbool{xpg at noset@groups}{}{\xpg at unset@group at 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 at 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 at info#1{\relax}% no latex info
+   \gdef\@font at info#1{\relax}% no latex font info
+   \gdef\@font at warning#1{\relax}% no latex font warnings
+   \gdef\zf at PackageInfo#1{\relax}% no fontspec info
+   \gdef\xpg at info#1{\relax}% no polyglossia info
+}
+
+\bool_if:nTF \l_polyglossia_localmarks_bool {
+  \polyglossia at enable@local at marks:
+}{}
+
+% compatibility
+\newif\ifsystem at babelshorthands
+\bool_if:nTF \l_polyglossia_babelshorthands_bool {
+  \system at babelshorthandstrue
+}{
+  \system at babelshorthandsfalse
+}
+
+%
+% FIXME these should also be loaded \AtEndOfPackage !!!
+\def\xpg at option#1#2{%
+  \ifcsundef{xpg at main@language}{\setdefaultlanguage}{\setotherlanguage}%
+    [#1]{#2}}
+\ExplSyntaxOff
+
+%    \end{macrocode}
+% \iffalse
+%</polyglossia.sty>
+%<*farsical.sty>
+% \fi
+% \clearpage
+% 
+% \subsection{farsical.sty}
+%    \begin{macrocode}
+\ProvidesPackage{farsical}
+        [2019/12/12 v0.2 %
+         Farsi (jalali) calendar]
+\ifluatex\RequirePackage{luabidi}\else\RequirePackage{bidi}\fi
+\RequirePackage{calc,arabicnumbers}
+
+%TODO - rewrite completely using calc 
+%%    - use Reingold & Dershowitz ME
+%% 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Modified from Arabiftoday.sty which is part of the Arabi package:
+%%%  Copyright (C) 2006 Youssef Jabri
+%%% itself a modification of the code in the FarsiTeX system:
+%%%  Copyright (C) 1996 Hassan Abolhassani
+%%%  Copyright (C) 1996-2001 Roozbeh Pournader <roozbeh at sharif.edu>
+%%%  Copyright (C) 2000-2001 Behdad Esfahbod <behdad at bamdad.org>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\ifJALALI at leap \newif\ifJALALI at kabiseh
+\newcount\JALALI at i  \newcount\JALALI at y  \newcount\JALALI at m  \newcount\JALALI at d
+\newcount\JALALI at latini    \newcount\JALALI at farsii
+\newcount\JALALI at latinii   \newcount\JALALI at farsiii
+\newcount\JALALI at latiniii  \newcount\JALALI at farsiiii
+\newcount\JALALI at latiniv   \newcount\JALALI at farsiiv
+\newcount\JALALI at latinv    \newcount\JALALI at farsiv
+\newcount\JALALI at latinvi   \newcount\JALALI at farsivi
+\newcount\JALALI at latinvii  \newcount\JALALI at farsivii
+\newcount\JALALI at latinviii \newcount\JALALI at farsiviii
+\newcount\JALALI at latinix   \newcount\JALALI at farsiix
+\newcount\JALALI at latinx    \newcount\JALALI at farsix
+\newcount\JALALI at latinxi   \newcount\JALALI at farsixi
+\newcount\JALALI at latinxii  \newcount\JALALI at farsixii
+                           \newcount\JALALI at farsixiii
+
+\newcount\JALALI at temp
+\newcount\JALALI at temptwo
+\newcount\JALALI at tempthree
+\newcount\JALALI at yModHundred
+\newcount\JALALI at thirtytwo
+\newcount\JALALI at dn
+\newcount\JALALI at sn
+\newcount\JALALI at mminusone
+
+% \ftoday renamed to \Jalalitoday - FC
+\def\Jalalitoday{%
+\JALALI at y=\year \JALALI at m=\month \JALALI at d=\day
+%
+\JALALI at temp=\JALALI at y
+\divide\JALALI at temp by 100\relax
+\multiply\JALALI at temp by 100\relax
+\JALALI at yModHundred=\JALALI at y
+\advance\JALALI at yModHundred by -\JALALI at temp\relax
+%
+\ifodd\JALALI at yModHundred
+   \JALALI at leapfalse
+\else
+   \JALALI at temp=\JALALI at yModHundred
+   \divide\JALALI at temp by 2\relax
+   \ifodd\JALALI at temp\JALALI at leapfalse
+   \else
+      \ifnum\JALALI at yModHundred=0%
+         \JALALI at temp=\JALALI at y
+         \divide\JALALI at temp by 400\relax
+         \multiply\JALALI at temp by 400\relax
+         \ifnum\JALALI at y=\JALALI at temp\JALALI at leaptrue\else\JALALI at leapfalse\fi
+      \else\JALALI at leaptrue
+      \fi
+   \fi
+\fi
+%
+\JALALI at latini=31\relax
+\ifJALALI at leap
+  \JALALI at latinii = 29\relax
+\else
+  \JALALI at latinii = 28\relax
+\fi
+\JALALI at latiniii = 31\relax
+\JALALI at latiniv  = 30\relax
+\JALALI at latinv = 31\relax
+\JALALI at latinvi = 30\relax
+\JALALI at latinvii = 31\relax
+\JALALI at latinviii = 31\relax
+\JALALI at latinix = 30\relax
+\JALALI at latinx = 31\relax
+\JALALI at latinxi = 30\relax
+\JALALI at latinxii = 31\relax
+%
+\JALALI at thirtytwo=32\relax
+%
+\JALALI at temp=\JALALI at y
+\advance\JALALI at temp by -17\relax
+\JALALI at temptwo=\JALALI at temp
+\divide\JALALI at temptwo by 33\relax
+\multiply\JALALI at temptwo by 33\relax
+\advance\JALALI at temp by -\JALALI at temptwo
+\ifnum\JALALI at temp=\JALALI at thirtytwo\JALALI at kabisehfalse
+\else
+   \JALALI at temptwo=\JALALI at temp
+   \divide\JALALI at temptwo by 4\relax
+   \multiply\JALALI at temptwo by 4\relax
+   \advance\JALALI at temp by -\JALALI at temptwo
+   \ifnum\JALALI at temp=\z@\JALALI at kabisehtrue\else\JALALI at 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 at tempthree=\JALALI at y                 % Number of Leap years
+\advance\JALALI at tempthree by -1
+\JALALI at temp=\JALALI at tempthree              % T := (MY-1) div 4
+\divide\JALALI at temp by 4\relax
+\JALALI at temptwo=\JALALI at tempthree           % T := T - ((MY-1) div 100)
+\divide\JALALI at temptwo by 100\relax
+\advance\JALALI at temp by -\JALALI at temptwo
+\JALALI at temptwo=\JALALI at tempthree           % T := T + ((MY-1) div 400)
+\divide\JALALI at temptwo by 400\relax
+\advance\JALALI at temp by \JALALI at temptwo
+\advance\JALALI at tempthree by -611       % Number of Kabise years
+\JALALI at temptwo=\JALALI at tempthree           % T := T - ((SY+10) div 33) * 8
+\divide\JALALI at temptwo by 33\relax
+\multiply\JALALI at temptwo by 8\relax
+\advance\JALALI at temp by -\JALALI at temptwo
+\JALALI at temptwo=\JALALI at tempthree           %
+\divide\JALALI at temptwo by 33\relax
+\multiply\JALALI at temptwo by 33\relax
+\advance\JALALI at tempthree by -\JALALI at temptwo
+\ifnum\JALALI at tempthree=32\advance\JALALI at temp by 1\fi % if (SY+10) mod 33=32 then Inc(T);
+\divide\JALALI at tempthree by 4\relax     % T := T - ((SY+10) mod 33) div 4
+\advance\JALALI at temp by -\JALALI at tempthree
+\advance\JALALI at temp by -137            % T := T - 137  Adjust the value
+\JALALI at farsii=31
+\advance\JALALI at farsii by -\JALALI at temp                 % now 31 - T is the farsii
+%
+\JALALI at farsiii = 30\relax
+\ifJALALI at kabiseh
+  \JALALI at farsiiii = 30\relax
+\else
+  \JALALI at farsiiii = 29\relax
+\fi
+\JALALI at farsiiv  = 31\relax
+\JALALI at farsiv   = 31\relax
+\JALALI at farsivi  = 31\relax
+\JALALI at farsivii = 31\relax
+\JALALI at farsiviii= 31\relax
+\JALALI at farsiix  = 31\relax
+\JALALI at farsix   = 30\relax
+\JALALI at farsixi  = 30\relax
+\JALALI at farsixii = 30\relax
+\JALALI at farsixiii= 30\relax
+%
+\JALALI at dn= 0\relax
+\JALALI at sn= 0\relax
+\JALALI at mminusone=\JALALI at m
+\advance\JALALI at mminusone by -1\relax
+%
+\JALALI at i=0\relax
+\ifnum\JALALI at i < \JALALI at mminusone
+\loop
+\advance \JALALI at i by 1\relax
+\advance\JALALI at dn by \csname JALALI at latin\romannumeral\the\JALALI at i\endcsname
+\ifnum\JALALI at i<\JALALI at mminusone \repeat
+\fi
+\advance \JALALI at dn by \JALALI at d
+%
+\JALALI at i=1\relax
+\JALALI at sn = \JALALI at farsii
+\ifnum \JALALI at sn<\JALALI at dn
+\loop
+\advance \JALALI at i by 1\relax
+\advance\JALALI at sn by \csname JALALI at farsi\romannumeral\the\JALALI at i\endcsname
+\ifnum \JALALI at sn<\JALALI at dn \repeat
+\fi
+\ifnum \JALALI at i < 4
+   \JALALI at m = 9 \advance\JALALI at m by \JALALI at i
+   \advance \JALALI at y by -622\relax
+\else
+   \JALALI at m = \JALALI at i \advance \JALALI at m by -3\relax
+   \advance \JALALI at y by -621\relax
+\fi
+\advance\JALALI at sn by -\csname JALALI at farsi\romannumeral\the\JALALI at i%
+\endcsname
+\ifnum\JALALI at i = 1
+  \JALALI at d = \JALALI at dn \advance \JALALI at d by 30 \advance\JALALI at d by -\JALALI at farsii
+\else
+  \JALALI at d = \JALALI at dn \advance \JALALI at d by -\JALALI at sn
+\fi
+%% DATE FORMATTING
+\if at RTL{\farsidigits{\number\JALALI at d}\space%
+\Jalalimonth{\JALALI at m}\space\farsidigits{\number\JALALI at y}}%
+\else
+\number\JALALI at d\space\JalalimonthEnglish{\JALALI at m}%
+\space\number\JALALI at y%
+\fi}
+%%%
+\def\Jalalimonth#1{\ifcase#1\or فروردین\or
+اردیبهشت\or خرداد\or تیر\or مرداد\or شهریور%
+\or مهر\or آبان\or آذر\or دی\or بهمن\or اسفند%
+\fi}
+\def\JalalimonthEnglish#1{\ifcase#1%
+\or Farvardīn\or Ordībehesht\or Khordād\or Tīr%
+\or Mordād\or Shahrīvar\or Mihr\or Ābān\or Āzar%
+\or Dai\or Bahman\or Esfand\fi}
+%    \end{macrocode}
+% \iffalse
+%</farsical.sty>
+%<*hebrewcal.sty>
+% \fi
+% \clearpage
+% 
+% \subsection{hebrewcal.sty}
+%    \begin{macrocode}
+\ProvidesPackage{hebrewcal}
+        [2019/12/03 v2.7 %
+         Hebrew calendar for polyglossia (adapted from hebcal.sty in Babel)]
+\RequirePackage{xkeyval}
+\ifluatex\RequirePackage{luabidi}\else\RequirePackage{bidi}\fi
+
+\newif\if at xpg@hebrewcal at marcheshvan
+\@xpg at hebrewcal@marcheshvanfalse
+
+\DeclareOption{marcheshvan}{\@xpg at hebrewcal@marcheshvantrue}
+
+\@ifundefined{if at xpg@hebrew at marcheshvan}{}{%
+  \if at xpg@hebrew at marcheshvan
+     \@xpg at 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 at 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 at 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 at 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 at HebrewLeap אדר\ ב'%
+           \else אדר%
+        \fi%
+    \else%
+        \ifcase#1%
+           % nothing for 0
+           \or תשרי%
+           \or\if at xpg@hebrewcal at 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 at HebrewLeap Adar II\else Adar\fi%
+    \else%
+        \ifcase #1%
+            % nothing for 0
+            \or Tishrei%
+            \or\if at xpg@hebrewcal at 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 at 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 at 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 at 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 at 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 at GregorianLeap%
+            \ifnum #1 > 2%        % if month after February
+                \advance #3 by 1% % add leap day
+            \fi%
+        \fi%
+        \global\@common = #3}%
+    #3 = \@common}
+\def\@GregorianDaysInPriorYears#1#2{%
+     {%
+         \countdef\tmpc = 4%      % \tmpc==\count4
+         \countdef\tmpb = 2%      % \tmpb==\count2
+         \tmpb = #1%              %
+         \advance \tmpb by -1%    %
+         \tmpc = \tmpb%           % \tmpc = \tmpb = year-1
+         \multiply \tmpc by 365%  % Days in prior years =
+         #2 = \tmpc%              % = 365*(year-1) ...
+         \tmpc = \tmpb%           %
+         \divide \tmpc by 4%      % \tmpc = (year-1)/4
+         \advance #2 by \tmpc%    % ... plus Julian leap days ...
+         \tmpc = \tmpb%           %
+         \divide \tmpc by 100%    % \tmpc = (year-1)/100
+         \advance #2 by -\tmpc%   % ... minus century years ...
+         \tmpc = \tmpb%           %
+         \divide \tmpc by 400%    % \tmpc = (year-1)/400
+         \advance #2 by \tmpc%    % ... plus 4-century years.
+         \global\@common = #2}%
+    #2 = \@common}
+\def\@AbsoluteFromGregorian#1#2#3#4{%
+    {%
+        \countdef\tmpd = 0%       % \tmpd==\count0
+        #4 = #1%                  % days so far this month
+        \@GregorianDaysInPriorMonths{#2}{#3}{\tmpd}%
+        \advance #4 by \tmpd%     % add days in prior months
+        \@GregorianDaysInPriorYears{#3}{\tmpd}%
+        \advance #4 by \tmpd%     % add days in prior years
+        \global\@common = #4}%
+    #4 = \@common}
+\def\HebrewFromGregorian#1#2#3#4#5#6{%
+    {%
+        \countdef\tmpx= 17%        % \tmpx==\count17
+        \countdef\tmpy= 18%        % \tmpy==\count18
+        \countdef\tmpz= 19%        % \tmpz==\count19
+        #6 = #3%                   %
+        \global\advance #6 by 3761%  approximation from above
+        \@AbsoluteFromGregorian{#1}{#2}{#3}{#4}%
+        \tmpz = 1  \tmpy = 1%
+        \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
+        \ifnum \tmpx > #4%              %
+            \global\advance #6 by -1% Hyear = Gyear + 3760
+            \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
+        \fi%                            %
+        \advance #4 by -\tmpx%     % Days in this year
+        \advance #4 by 1%          %
+        #5 = #4%                   %
+        \divide #5 by 30%          % Approximation for month from below
+        \loop%                     % Search for month
+            \@HebrewDaysInPriorMonths{#5}{#6}{\tmpx}%
+            \ifnum \tmpx < #4%
+                \advance #5 by 1%
+                \tmpy = \tmpx%
+        \repeat%
+        \global\advance #5 by -1%
+        \global\advance #4 by -\tmpy}}
+\ProcessOptions*
+%    \end{macrocode}
+% \iffalse
+%</hebrewcal.sty>
+%<*hijrical.sty>
+% \fi
+% \clearpage
+% 
+% \subsection{hijrical.sty}
+%    \begin{macrocode}
+\ProvidesPackage{hijrical}
+        [2010/07/12 v0.2 %
+         Islamic calendar]
+\RequirePackage{calc}
+\RequirePackage{arabicnumbers}
+\@ifpackageloaded{bidi}{}{\newif\if at 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 at correction}{\gdef\@hijri at correction{0}}{}
+\newcommand\Hijritoday[1][\@hijri at correction]{%
+ \@ifundefined{c at adj@day}{\global\newcounter{adj at day}}{}%
+ \setcounter{adj at day}{\the\day+#1}% 
+ \Hijridate{\year}{\month}{\value{adj at 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 at RTL\FormatHijriDate at defaultRTL\else\FormatHijriDate at 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 at RTL{%
+\arabicdigits{\value{Hijriday}}\space\HijriMonthArabic{\value{Hijrimonth}}\space\arabicdigits{\value{Hijriyear}}}}
+
+\DefineFormatHijriDate{defaultLTR}{%
+\number\value{Hijriday}\space\HijriMonthTranslit{\value{Hijrimonth}}\space\number\value{Hijriyear}}
+%    \end{macrocode}
+% \iffalse
+%</hijrical.sty>
+%<*polyglossia-french.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-french.lua}
+%    \begin{macrocode}
+require('polyglossia-punct')
+
+local function set_left_space(lang, char, kern, rubber)
+    polyglossia.add_left_spaced_character(lang, char, kern, "space", rubber)
+end
+
+local function set_right_space(lang, char, kern, rubber)
+    polyglossia.add_right_spaced_character(lang, char, kern, "space", rubber)
+end
+
+local function activate_french_punct(thincolonspace, autospaceguillemets)
+    -- We need different language tags here to make switching of options possible
+    -- within a paragraph.
+    local lang = "french"
+    if thincolonspace then
+        lang = lang.."-thincolon"
+    end
+    if autospaceguillemets then
+        lang = lang.."-autospace"
+    end
+
+    polyglossia.activate_punct(lang)
+    polyglossia.clear_spaced_characters(lang)
+
+    if thincolonspace then
+        set_left_space(lang, ':', 0.5)
+    else
+        set_left_space(lang, ':', 1, true) -- stretchable and shrinkable space
+    end
+
+    set_left_space(lang, '!', 0.5)
+    set_left_space(lang, '?', 0.5)
+    set_left_space(lang, ';', 0.5)
+    set_left_space(lang, '‼', 0.5)
+    set_left_space(lang, '⁇', 0.5)
+    set_left_space(lang, '⁈', 0.5)
+    set_left_space(lang, '⁉', 0.5)
+    set_left_space(lang, '‽', 0.5) -- U+203D (interrobang)
+
+    if autospaceguillemets then
+        set_left_space(lang, '»', 0.5)
+        set_left_space(lang, '›', 0.5)
+        set_right_space(lang, '«', 0.5)
+        set_right_space(lang, '‹', 0.5)
+    end
+end
+
+local function deactivate_french_punct()
+    polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_french_punct   = activate_french_punct
+polyglossia.deactivate_french_punct = deactivate_french_punct
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-french.lua>
+%<*polyglossia-korean.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-korean.lua}
+%    \begin{macrocode}
+--
+-- polyglossia-korean.lua
+--
+
+local glyph_id = node.id"glyph"
+local hbox_id  = node.id"hlist"
+local vbox_id  = node.id"vlist"
+local glue_id  = node.id"glue"
+local penalty_id = node.id"penalty"
+local disc_id  = node.id"disc"
+
+--
+-- attr_korean: variant = plain (0), classic (1), modern (2)
+--
+local attr_korean = luatexbase.attributes["xpg at attr@korean"]
+local attr_josa   = luatexbase.attributes["xpg at attr@autojosa"]
+
+--
+-- characters after which linebreak is not allowed
+--
+local nobr_after = {
+    [0x28] = 1, -- ( LEFT PARENTHESIS
+    [0x3C] = 1, -- < LESS-THAN SIGN
+    [0x5B] = 1, -- [ LEFT SQUARE BRACKET
+    [0x60] = 1, -- ` GRAVE ACCENT
+    [0x7B] = 1, -- { LEFT CURLY BRACKET
+    [0xAB] = 1, -- « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+    [0x2018] = 1, -- ‘ LEFT SINGLE QUOTATION MARK
+    [0x201C] = 1, -- “ LEFT DOUBLE QUOTATION MARK
+    [0x2329] = 1, -- 〈 LEFT-POINTING ANGLE BRACKET
+    [0x3008] = 1, -- 〈 LEFT ANGLE BRACKET
+    [0x300A] = 1, -- 《 LEFT DOUBLE ANGLE BRACKET
+    [0x300C] = 1, -- 「 LEFT CORNER BRACKET
+    [0x300E] = 1, -- 『 LEFT WHITE CORNER BRACKET
+    [0x3010] = 1, -- 【 LEFT BLACK LENTICULAR BRACKET
+    [0x3014] = 1, -- 〔 LEFT TORTOISE SHELL BRACKET
+    [0x3016] = 1, -- 〖 LEFT WHITE LENTICULAR BRACKET
+    [0x3018] = 1, -- 〘 LEFT WHITE TORTOISE SHELL BRACKET
+    [0x301A] = 1, -- 〚 LEFT WHITE SQUARE BRACKET
+    [0x301D] = 1, -- 〝 REVERSED DOUBLE PRIME QUOTATION MARK
+    [0xFE17] = 1, -- ︗ PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+    [0xFE35] = 1, -- ︵ PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+    [0xFE37] = 1, -- ︷ PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+    [0xFE39] = 1, -- ︹ PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+    [0xFE3B] = 1, -- ︻ PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+    [0xFE3D] = 1, -- ︽ PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+    [0xFE3F] = 1, -- ︿ PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+    [0xFE41] = 1, -- ﹁ PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+    [0xFE43] = 1, -- ﹃ PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+    [0xFE47] = 1, -- ﹇ PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+    [0xFE59] = 1, -- ﹙ SMALL LEFT PARENTHESIS
+    [0xFE5B] = 1, -- ﹛ SMALL LEFT CURLY BRACKET
+    [0xFE5D] = 1, -- ﹝ SMALL LEFT TORTOISE SHELL BRACKET
+    [0xFF08] = 1, -- ( FULLWIDTH LEFT PARENTHESIS
+    [0xFF3B] = 1, -- [ FULLWIDTH LEFT SQUARE BRACKET
+    [0xFF5B] = 1, -- { FULLWIDTH LEFT CURLY BRACKET
+    [0xFF5F] = 1, -- ⦅ FULLWIDTH LEFT WHITE PARENTHESIS
+    [0xFF62] = 1, -- 「 HALFWIDTH LEFT CORNER BRACKET
+}
+
+--
+-- characters before which linebreak is not allowed
+--   (currently, not much differences among the followings)
+--   1: normal chars
+--   2: hangul jamo vowels and trailing consonants
+--   3: kana small letters
+--   0: dashes (supress visible spacing)
+--
+local nobr_before = setmetatable({
+    [0x21] = 1, -- ! EXCLAMATION MARK
+    [0x22] = 1, -- " QUOTATION MARK
+    [0x27] = 1, -- ' APOSTROPHE
+    [0x29] = 1, -- ) RIGHT PARENTHESIS
+    [0x2C] = 1, -- , COMMA
+    [0x2D] = 0, -- - HYPHEN-MINUS
+    [0x2E] = 1, -- . FULL STOP
+    [0x2F] = 0, -- / SOLIDUS
+    [0x3A] = 0, -- : COLON
+    [0x3B] = 1, -- ; SEMICOLON
+    [0x3E] = 1, -- > GREATER-THAN SIGN
+    [0x3F] = 1, -- ? QUESTION MARK
+    [0x5C] = 0, -- \ REVERSE SOLIDUS
+    [0x5D] = 1, -- ] RIGHT SQUARE BRACKET
+    [0x7D] = 1, -- } RIGHT CURLY BRACKET
+    [0x7E] = 0, -- ~ TILDE
+    [0xB7] = 1, -- · MIDDLE DOT
+    [0xBB] = 1, -- » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+    [0x2013] = 0, -- – EN DASH
+    [0x2014] = 0, -- — EM DASH
+    [0x2015] = 1, -- ― HORIZONTAL BAR
+    [0x2019] = 1, -- ’ RIGHT SINGLE QUOTATION MARK
+    [0x201D] = 1, -- ” RIGHT DOUBLE QUOTATION MARK
+    [0x2025] = 1, -- ‥ TWO DOT LEADER
+    [0x2026] = 1, -- … HORIZONTAL ELLIPSIS
+    [0x232A] = 1, -- 〉 RIGHT-POINTING ANGLE BRACKET
+    [0x3001] = 1, -- 、 IDEOGRAPHIC COMMA
+    [0x3002] = 1, -- 。 IDEOGRAPHIC FULL STOP
+    [0x3005] = 1, -- 々 IDEOGRAPHIC ITERATION MARK
+    [0x3009] = 1, -- 〉 RIGHT ANGLE BRACKET
+    [0x300B] = 1, -- 》 RIGHT DOUBLE ANGLE BRACKET
+    [0x300D] = 1, -- 」 RIGHT CORNER BRACKET
+    [0x300F] = 1, -- 』 RIGHT WHITE CORNER BRACKET
+    [0x3011] = 1, -- 】 RIGHT BLACK LENTICULAR BRACKET
+    [0x3015] = 1, -- 〕 RIGHT TORTOISE SHELL BRACKET
+    [0x3017] = 1, -- 〗 RIGHT WHITE LENTICULAR BRACKET
+    [0x3019] = 1, -- 〙 RIGHT WHITE TORTOISE SHELL BRACKET
+    [0x301B] = 1, -- 〛 RIGHT WHITE SQUARE BRACKET
+    [0x301C] = 1, -- 〜 WAVE DASH
+    [0x301E] = 1, -- 〞 DOUBLE PRIME QUOTATION MARK
+    [0x301F] = 1, -- 〟 LOW DOUBLE PRIME QUOTATION MARK
+    [0x3035] = 1, -- 〵 VERTICAL KANA REPEAT MARK LOWER HALF
+    [0x303B] = 1, -- 〻 VERTICAL IDEOGRAPHIC ITERATION MARK
+    [0x303C] = 1, -- 〼 MASU MARK
+    [0x3041] = 3, -- ぁ HIRAGANA LETTER SMALL A
+    [0x3043] = 3, -- ぃ HIRAGANA LETTER SMALL I
+    [0x3045] = 3, -- ぅ HIRAGANA LETTER SMALL U
+    [0x3047] = 3, -- ぇ HIRAGANA LETTER SMALL E
+    [0x3049] = 3, -- ぉ HIRAGANA LETTER SMALL O
+    [0x3063] = 3, -- っ HIRAGANA LETTER SMALL TU
+    [0x3083] = 3, -- ゃ HIRAGANA LETTER SMALL YA
+    [0x3085] = 3, -- ゅ HIRAGANA LETTER SMALL YU
+    [0x3087] = 3, -- ょ HIRAGANA LETTER SMALL YO
+    [0x308E] = 3, -- ゎ HIRAGANA LETTER SMALL WA
+    [0x3095] = 3, -- ゕ HIRAGANA LETTER SMALL KA
+    [0x3096] = 3, -- ゖ HIRAGANA LETTER SMALL KE
+    [0x3099] = 1, --  COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
+    [0x309A] = 1, --  COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+    [0x309B] = 1, -- ゛ KATAKANA-HIRAGANA VOICED SOUND MARK
+    [0x309C] = 1, -- ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+    [0x309D] = 1, -- ゝ HIRAGANA ITERATION MARK
+    [0x309E] = 1, -- ゞ HIRAGANA VOICED ITERATION MARK
+    [0x30A0] = 1, -- ゠ KATAKANA-HIRAGANA DOUBLE HYPHEN
+    [0x30A1] = 3, -- ァ KATAKANA LETTER SMALL A
+    [0x30A3] = 3, -- ィ KATAKANA LETTER SMALL I
+    [0x30A5] = 3, -- ゥ KATAKANA LETTER SMALL U
+    [0x30A7] = 3, -- ェ KATAKANA LETTER SMALL E
+    [0x30A9] = 3, -- ォ KATAKANA LETTER SMALL O
+    [0x30C3] = 3, -- ッ KATAKANA LETTER SMALL TU
+    [0x30E3] = 3, -- ャ KATAKANA LETTER SMALL YA
+    [0x30E5] = 3, -- ュ KATAKANA LETTER SMALL YU
+    [0x30E7] = 3, -- ョ KATAKANA LETTER SMALL YO
+    [0x30EE] = 3, -- ヮ KATAKANA LETTER SMALL WA
+    [0x30F5] = 3, -- ヵ KATAKANA LETTER SMALL KA
+    [0x30F6] = 3, -- ヶ KATAKANA LETTER SMALL KE
+    [0x30FB] = 1, -- ・ KATAKANA MIDDLE DOT
+    [0x30FC] = 1, -- ー KATAKANA-HIRAGANA PROLONGED SOUND MARK
+    [0x30FD] = 1, -- ヽ KATAKANA ITERATION MARK
+    [0x30FE] = 1, -- ヾ KATAKANA VOICED ITERATION MARK
+    [0xFE30] = 1, -- ︰ PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+    [0xFE31] = 1, -- ︱ PRESENTATION FORM FOR VERTICAL EM DASH
+    [0xFE32] = 1, -- ︲ PRESENTATION FORM FOR VERTICAL EN DASH
+    [0xFE36] = 1, -- ︶ PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+    [0xFE38] = 1, -- ︸ PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+    [0xFE3A] = 1, -- ︺ PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+    [0xFE3C] = 1, -- ︼ PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+    [0xFE3E] = 1, -- ︾ PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+    [0xFE40] = 1, -- ﹀ PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+    [0xFE42] = 1, -- ﹂ PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+    [0xFE44] = 1, -- ﹄ PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+    [0xFE48] = 1, -- ﹈ PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+    [0xFE5A] = 1, -- ﹚ SMALL RIGHT PARENTHESIS
+    [0xFE5C] = 1, -- ﹜ SMALL RIGHT CURLY BRACKET
+    [0xFE5E] = 1, -- ﹞ SMALL RIGHT TORTOISE SHELL BRACKET
+    [0xFF01] = 1, -- ! FULLWIDTH EXCLAMATION MARK
+    [0xFF09] = 1, -- ) FULLWIDTH RIGHT PARENTHESIS
+    [0xFF0C] = 1, -- , FULLWIDTH COMMA
+    [0xFF0E] = 1, -- . FULLWIDTH FULL STOP
+    [0xFF1A] = 1, -- : FULLWIDTH COLON
+    [0xFF1B] = 1, -- ; FULLWIDTH SEMICOLON
+    [0xFF1F] = 1, -- ? FULLWIDTH QUESTION MARK
+    [0xFF3D] = 1, -- ] FULLWIDTH RIGHT SQUARE BRACKET
+    [0xFF5D] = 1, -- } FULLWIDTH RIGHT CURLY BRACKET
+    [0xFF60] = 1, -- ⦆ FULLWIDTH RIGHT WHITE PARENTHESIS
+    [0xFF61] = 1, -- 。 HALFWIDTH IDEOGRAPHIC FULL STOP
+    [0xFF63] = 1, -- 」 HALFWIDTH RIGHT CORNER BRACKET
+    [0xFF64] = 1, -- 、 HALFWIDTH IDEOGRAPHIC COMMA
+    [0xFF65] = 1, -- ・ HALFWIDTH KATAKANA MIDDLE DOT
+    [0xFF9E] = 1, -- ゙ HALFWIDTH KATAKANA VOICED SOUND MARK
+    [0xFF9F] = 1, -- ゚ HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+}, { __index = function(_,c)
+        if c >= 0x1160  and c <= 0x11FF  then return 2 end
+        if c >= 0xD7B0  and c <= 0xD7FF  then return 2 end
+        if c >= 0x302A  and c <= 0x302F  then return 1 end
+        if c >= 0x31F0  and c <= 0x31FF  then return 3 end
+        if c >= 0xFF67  and c <= 0xFF70  then return 3 end
+        if c >= 0xFE00  and c <= 0xFE0F  then return 1 end
+        if c >= 0xFE10  and c <= 0xFE19 and not (c == 0xFE17) then return 1 end
+        if c >= 0xFE50  and c <= 0xFE58  then return 1 end
+        if c >= 0xE0100 and c <= 0xE01EF then return 1 end
+    end
+})
+
+--
+-- whether 'c' is a cjk character
+--
+local function is_cjk (c)
+    return c >= 0xAC00  and c <= 0xD7FF
+    or     c >= 0x1100  and c <= 0x11FF
+    or     c >= 0xA960  and c <= 0xA97F
+    or     c >= 0x2E80  and c <= 0x9FFF
+    or     c >= 0xF900  and c <= 0xFAFF
+    or     c >= 0xFE10  and c <= 0xFE1F
+    or     c >= 0xFE30  and c <= 0xFE6F
+    or     c >= 0xFF00  and c <= 0xFFEF
+    or     c >= 0x1F100 and c <= 0x1F2FF
+    or     c >= 0x20000 and c <= 0x2FA1F
+    or     nobr_after[c]  and c > 0x2014
+    or     nobr_before[c] and c > 0x2014
+end
+
+--
+-- classify cjk characters
+--   1: openings
+--   2: closings
+--   3: centered chars
+--   4: full stops
+--   5: ellipses
+--   6: exclamation and question marks
+--   0: all others
+--
+local charclass = setmetatable({
+    [0x2018] = 1, [0x201C] = 1, [0x2329] = 1, [0x3008] = 1,
+    [0x300A] = 1, [0x300C] = 1, [0x300E] = 1, [0x3010] = 1,
+    [0x3014] = 1, [0x3016] = 1, [0x3018] = 1, [0x301A] = 1,
+    [0x301D] = 1, [0xFE17] = 1, [0xFE35] = 1, [0xFE37] = 1,
+    [0xFE39] = 1, [0xFE3B] = 1, [0xFE3D] = 1, [0xFE3F] = 1,
+    [0xFE41] = 1, [0xFE43] = 1, [0xFE47] = 1, [0xFF08] = 1,
+    [0xFF3B] = 1, [0xFF5B] = 1, [0xFF5F] = 1, [0xFF62] = 1,
+    [0x2019] = 2, [0x201D] = 2, [0x232A] = 2, [0x3001] = 2,
+    [0x3009] = 2, [0x300B] = 2, [0x300D] = 2, [0x300F] = 2,
+    [0x3011] = 2, [0x3015] = 2, [0x3017] = 2, [0x3019] = 2,
+    [0x301B] = 2, [0x301E] = 2, [0x301F] = 2, [0xFE10] = 2,
+    [0xFE11] = 2, [0xFE18] = 2, [0xFE36] = 2, [0xFE38] = 2,
+    [0xFE3A] = 2, [0xFE3C] = 2, [0xFE3E] = 2, [0xFE40] = 2,
+    [0xFE42] = 2, [0xFE44] = 2, [0xFE48] = 2, [0xFF09] = 2,
+    [0xFF0C] = 2, [0xFF3D] = 2, [0xFF5D] = 2, [0xFF60] = 2,
+    [0xFF63] = 2, [0xFF64] = 2, [0x00B7] = 3, [0x30FB] = 3,
+    [0xFF1A] = 3, [0xFF1B] = 3, [0xFF65] = 3, [0x3002] = 4,
+    [0xFE12] = 4, [0xFF0E] = 4, [0xFF61] = 4, [0x2015] = 5,
+    [0x2025] = 5, [0x2026] = 5, [0xFE19] = 5, [0xFE30] = 5,
+    [0xFE31] = 5, [0xFE15] = 6, [0xFE16] = 6, [0xFF01] = 6,
+    [0xFF1F] = 6,
+}, { __index = function() return 0 end })
+
+--
+-- table for spacing between char classes
+--   1 stands for 0.5*fontsize when variant=classic
+--
+local intercharclass = { [0] =
+    { [0] = nil,    {1,1},  nil,    {.5,.5} },
+    { [0] = nil,    nil,    nil,    {.5,.5} },
+    { [0] = {1,1},  {1,1},  nil,    {.5,.5}, nil,    {1,1},  {1,1} },
+    { [0] = {.5,.5},{.5,.5},{.5,.5},{1,.5},  {.5,.5},{.5,.5},{.5,.5} },
+    { [0] = {1,0},  {1,0},  nil,    {1.5,.5},nil,    {1,0},  {1,0} },
+    { [0] = nil,    {1,1},  nil,    {.5,.5} },
+    { [0] = {1,1},  {1,1},  nil,    {.5,.5} },
+}
+
+--
+-- get a new penalty node
+--
+local function get_new_penalty (p)
+    local penalty = node.new("penalty")
+    penalty.penalty = p
+    return penalty
+end
+
+--
+-- get a new glue node
+--
+local function get_new_glue (...)
+    local glue = node.new("glue")
+    node.setglue(glue, ...)
+    return glue
+end
+
+--
+-- return 0.5*fontsize of given fontid
+--   space: true if variant=modern; then 0.5*interword_space
+--
+local function get_font_size (fid, space)
+    local size = font.getparameters(fid)
+    if space then
+        size = size and size.space or 196608
+    else
+        size = size and size.quad  or 655360
+    end
+    return size/2
+end
+
+--
+-- charclass 1 thru 4 will be packed in \hbox to 0.5em{\hss? curr \hss?}
+--   when variant=classic/modern
+--
+local function glyph_to_box (head, curr, class)
+    local g, h = curr
+    local size = get_font_size(g.font)
+    head, curr = node.remove(head, curr)
+    g.next, g.prev = nil, nil
+    local hss = get_new_glue(0, 65536, 65536, 2, 2)
+    if class == 1 then
+        h, hss.next, g.prev = hss, g, hss
+    elseif class == 2 or class == 4 then
+        h, g.next, hss.prev = g, hss, g
+    else
+        local hss2 = node.copy(hss)
+        h, hss.next, g.prev, g.next, hss2.prev = hss, g, hss, hss2, g
+    end
+    h = nodes.simple_font_handler(h)
+    local box = node.hpack(h, size, "exactly")
+    if curr then
+        head, curr = node.insert_before(head, curr, box)
+    else
+        head, curr = node.insert_after(head, node.tail(head), box)
+    end
+    return head, curr
+end
+
+--
+-- insert spacing defined as charclass[a][b] between a and b
+--   f:    fontid
+--   var:  variant = plain, classic, modern
+--   cc:   charclass of current char
+--   nc:   charclass of next char
+--   nobr: linebreak is not allowed
+--
+local function insert_cjk_penalty_glue (head, curr, f, var, cc, nc, nobr)
+    if nobr or cc == 1 or nc > 1 then
+        local penalty = get_new_penalty(10000)
+        head, curr = node.insert_after(head, curr, penalty)
+    end
+    local factor = get_font_size(f, var == 2)
+    local t = intercharclass[cc][nc]
+    local glue = get_new_glue(t[1]*factor, nil, t[2]*factor)
+    head, curr = node.insert_after(head, curr, glue)
+    return head, curr
+end
+
+--
+-- insert inter-character spacing in other normal cases
+--   f:   fontid
+--   var: variant = plain, classic, modern
+--   x:   true between cjk and non-cjk (a little more spacing)
+--
+local function insert_penalty_glue (head, curr, f, var, x)
+    if var ~= 1 then
+        local penalty = get_new_penalty(50)
+        head, curr = node.insert_after(head, curr, penalty)
+    end
+    local size, glue = get_font_size(f, x and var == 2)
+    if x then
+        glue = get_new_glue(size/2, size/4, size/8)
+    else
+        glue = get_new_glue(0, size/10, size/50)
+    end
+    head, curr = node.insert_after(head, curr, glue)
+    return head, curr
+end
+
+--
+-- main process for linebreak and inter-character spacing
+--   lb: true if pre_linebreak_filter
+--
+local function korean_break (head, lb)
+    local curr = head
+    while curr do
+        if curr.id == glyph_id then
+            local var = node.has_attribute(curr, attr_korean)
+            if var then
+                local c, f = curr.char or 0, curr.font or 0
+                local cc, cjkc = charclass[c], is_cjk(c)
+
+                -- compress cjk punctuations when charclass is 1 thru 4
+                if var > 0 and cc > 0 and cc < 5 then
+                    head, curr = glyph_to_box(head, curr, cc)
+                end
+
+                local next = curr.next
+                if next and next.id == glyph_id then
+                    local n = next.char or 0
+                    local nc = charclass[n]
+                    local nobr = nobr_before[n] or nobr_after[c]
+
+                    -- insert spacing as of intercharclass
+                    if var > 0 and intercharclass[cc][nc] then
+                        head, curr = insert_cjk_penalty_glue(head, curr, f, var, cc, nc, nobr)
+
+                    -- or insert spacing when linebreak is allowed
+                    elseif not nobr then
+                        local cjkn = is_cjk(n)
+
+                        -- if curr or next is cjk char
+                        if cjkc or cjkn then
+
+                            -- if between cjk and non-cjk
+                            if var > 0 and not (cjkc and cjkn) and nobr_before[c] ~= 0 then
+                                head, curr = insert_penalty_glue(head, curr, f, var, true)
+
+                            -- or under pre_linebreak_filter
+                            elseif lb then
+                                head, curr = insert_penalty_glue(head, curr, f, var)
+                            end
+                        end
+                    end
+                end
+            end
+        end
+        curr = curr.next
+    end
+    return head
+end
+
+--
+-- process for reordering hangul tone marks (U+302E, U+302F)
+--   some hangul fonts (eg. Noto CJK) are so designed that hangul tone marks
+--   should be moved to the first position of a syllable.
+--   Currently, this functionality is not provided by luaotfload.
+--
+local function reorder_tm (head)
+    local curr, tone = node.slide(head)
+    while curr do
+        if curr.id == glyph_id and node.has_attribute(curr, attr_korean) then
+            local f = font.getfont(curr.font) or font.fonts[curr.font]
+            if f and f.hb then -- harfbuzz do the right thing
+                tone = nil
+            else
+                local c, wd = curr.char or 0, curr.width or 0
+                if (c == 0x302E or c == 0x302F) and wd > 0 then
+                    tone = curr
+                elseif tone and not nobr_before[c] then
+                    head = node.remove(head, tone)
+                    tone.next, tone.prev = nil, nil
+                    head, curr = node.insert_before(head, curr, tone)
+                    tone = nil
+                end
+            end
+        end
+        curr = curr.prev
+    end
+    return head
+end
+
+--
+-- automatic josa selection
+--
+local josa_table = {
+    --          consonant ㄹ, vowel,  other consonants
+    [0xAC00] = {0xC774,       0xAC00, 0xC774}, -- 가 => 이, 가, 이
+    [0xC740] = {0xC740,       0xB294, 0xC740}, -- 은 => 은, 는, 은
+    [0xC744] = {0xC744,       0xB97C, 0xC744}, -- 을 => 을, 를, 을
+    [0xC640] = {0xACFC,       0xC640, 0xACFC}, -- 와 => 과, 와, 과
+    [0xC73C] = {nil,          nil,    0xC73C}, -- 으(로) =>   ,  , 으
+    [0xC774] = {0xC774,       nil,    0xC774}, -- 이(라) => 이,  , 이
+}
+
+--
+-- helper function for number-like characters
+--
+local function josa_char_num (t, c)
+    c = c % 10 + 0x30
+    return t[c] or 2
+end
+
+--
+-- decide josa selection
+--
+local josa_code = setmetatable({
+    [0x30] = 3, [0x31] = 1, [0x33] = 3, [0x36] = 3, [0x37] = 1,
+    [0x38] = 1, [0x4C] = 1, [0x4D] = 3, [0x4E] = 3, [0x6C] = 1,
+    [0x6D] = 3, [0x6E] = 3, [0xFB02] = 1, [0xFB04] = 1,
+},{ __index = function(t,c)
+        if c >= 0xAC00 and c <= 0xD7A3 then
+            c = (c - 0xAC00) % 28 + 0x11A7
+        end
+        if c >= 0x11A8 and c <= 0x11FF then
+            if c == 0x11AF then return 1 end
+            return 3
+        end
+        if c >= 0xD7CB and c <= 0xD7FB then return 3 end
+        if c >= 0x2170 and c <= 0x217F then c = c - 0x10 end
+        if c >= 0x2160 and c <= 0x216F then
+            if c >= 0x216C then return 3 end
+            return josa_char_num(t, c - 0x215F)
+        end
+        if c >= 0x2460 and c <= 0x2473 then return josa_char_num(t, c - 0x245F) end
+        if c >= 0x2474 and c <= 0x2487 then return josa_char_num(t, c - 0x2473) end
+        if c >= 0x2488 and c <= 0x249B then return josa_char_num(t, c - 0x2487) end
+        if c >= 0x249C and c <= 0x24B5 then return t[c - 0x249C + 0x61] or 2 end
+        if c >= 0x24B6 and c <= 0x24CF then return t[c - 0x24B6 + 0x61] or 2 end
+        if c >= 0x24D0 and c <= 0x24E9 then return t[c - 0x24D0 + 0x61] or 2 end
+        if c >= 0x3131 and c <= 0x318E then
+            if c == 0x3139 then return 1 end
+            if c >= 0x314F and c <= 0x3163 or c >= 0x3187 then return 2 end
+            return 3
+        end
+        if c >= 0x3260 and c <= 0x327E then c = c - 0x60 end
+        if c >= 0x3200 and c <= 0x321E then
+            if c == 0x3203 then return 1 end
+            if c >= 0x320E then return 2 end
+            return 3
+        end
+        if c >= 0xFF10 and c <= 0xFF19 then return josa_char_num(t, c - 0xFF10) end
+        if c >= 0xFF21 and c <= 0xFF3A then return t[c - 0xFF21 + 0x61] or 2 end
+        if c >= 0xFF41 and c <= 0xFF5A then return t[c - 0xFF41 + 0x61] or 2 end
+        return 2
+    end
+})
+
+--
+-- obtain char that comes just before the josa
+--
+local function get_prev_char (p)
+    while p do
+        if p.id == glyph_id then
+            local pc = p.char or 0
+            if not nobr_after[pc] then
+                if not nobr_before[pc] or nobr_before[pc] >= 2 then
+                    return pc
+                end
+            end
+        elseif p.id == hbox_id or p.id == vbox_id then
+            local pc = get_prev_char(node.slide(p.head))
+            if pc then return pc end
+        end
+        p = p.prev
+    end
+end
+
+--
+-- main process of josa selection
+--
+local function auto_josa (head)
+    local curr, tofree = head, {}
+    while curr do
+        if curr.id == glyph_id then
+            local josa = node.has_attribute(curr, attr_josa)
+            if josa then
+                local cc = curr.char or 0
+                if josa == 0 then
+                    josa = josa_code[get_prev_char(curr.prev) or 0x30]
+                end
+                if cc == 0xC774 then
+                    local n = curr.next
+                    if n and n.char and n.char >= 0xAC00 and n.char <= 0xD7A3 then
+                    else
+                        cc = 0xAC00
+                    end
+                end
+                local new = josa_table[cc]
+                if new then
+                    cc = new[josa]
+                    if cc then
+                        curr.char = cc
+                    else
+                        head = node.remove(head, curr)
+                        table.insert(tofree, curr)
+                    end
+                end
+                node.unset_attribute(curr, attr_josa)
+            end
+        end
+        curr = curr.next
+    end
+    for _,v in ipairs(tofree) do node.free(v) end
+    return head
+end
+
+--
+-- now register to luatex callbacks
+--   As char value of glyphs can be changed by opentype GSUB process,
+--   we have to occupy the first position among callback functions.
+--
+local prepend_to_callback
+if luatexbase.base_add_to_callback then
+    prepend_to_callback = function(name, func, desc)
+        luatexbase.add_to_callback(name, func, desc, 1)
+    end
+else
+    prepend_to_callback = function(name, func, desc)
+        local t = { {func, desc} }
+        for _,v in ipairs(luatexbase.callback_descriptions(name)) do
+            table.insert(t, {luatexbase.remove_from_callback(name, v)})
+        end
+        for _,v in ipairs(t) do
+            luatexbase.add_to_callback(name, v[1], v[2])
+        end
+    end
+end
+
+prepend_to_callback ("pre_linebreak_filter",
+    function(head)
+        head = auto_josa(head)
+        head = korean_break(head, true)
+        head = reorder_tm(head)
+        return head
+    end,
+    "polyglossia.lang_korean")
+
+prepend_to_callback ("hpack_filter",
+    function(head)
+        head = auto_josa(head)
+        head = korean_break(head)
+        head = reorder_tm(head)
+        return head
+    end,
+    "polyglossia.lang_korean")
+
+-- vim:ft=lua:tw=0:sw=4:ts=4:expandtab
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-korean.lua>
+%<*polyglossia-latin.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-latin.lua}
+%    \begin{macrocode}
+require('polyglossia-punct')
+
+-- For ecclesiastic Latin (and sometimes for Italian) a very small space is
+-- used for the punctuation. The ecclesiastic package uses a space of
+-- 0.3\fontdimen2, where \fontdimen2 is a interword space, which is typically
+-- between 1/4 and 1/3 of a quad. We choose a half of a \thinspace here.
+local hairspace = 0.08333 -- 1/12
+
+local function space_left(char)
+    polyglossia.add_left_spaced_character('latin', char, hairspace, 'quad')
+end
+
+local function space_right(char)
+    polyglossia.add_right_spaced_character('latin', char, hairspace, 'quad')
+end
+
+polyglossia.clear_spaced_characters('latin')
+space_left('!')
+space_left('?')
+space_left('‼')
+space_left('⁇')
+space_left('⁈')
+space_left('⁉')
+space_left('‽') -- U+203D (interrobang)
+space_left(':')
+space_left(';')
+space_left('»')
+space_left('›')
+space_right('«')
+space_right('‹')
+
+local function activate_latin_punct()
+    polyglossia.activate_punct('latin')
+end
+
+local function deactivate_latin_punct()
+    polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_latin_punct   = activate_latin_punct
+polyglossia.deactivate_latin_punct = deactivate_latin_punct
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-latin.lua>
+%<*polyglossia-punct.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-punct.lua}
+%    \begin{macrocode}
+require('polyglossia') -- just in case...
+
+local add_to_callback      = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+local priority_in_callback = luatexbase.priority_in_callback
+local new_attribute        = luatexbase.new_attribute
+
+local node = node
+
+local insert_node_before = node.insert_before
+local insert_node_after  = node.insert_after
+local remove_node        = node.remove
+local has_attribute      = node.has_attribute
+local node_copy          = node.copy
+local new_node           = node.new
+local end_of_math        = node.end_of_math
+local getnext            = node.getnext
+local getprev            = node.getprev
+
+-- node types according to node.types()
+local glue_code    = node.id"glue"
+local glyph_code   = node.id"glyph"
+local penalty_code = node.id"penalty"
+local kern_code    = node.id"kern"
+local math_code    = node.id"math"
+
+-- we need some node subtypes
+local userkern = 1
+local userskip = 0
+local removable_skip = {
+    [0]  = true, -- userskip
+    [13] = true, -- spaceskip
+    [14] = true, -- xspaceskip
+}
+
+-- we make a new node, so that we can copy it later on
+local kern_node = new_node(kern_code)
+kern_node.subtype = userkern -- this kern can be removed later on
+
+local function get_kern_node(dim)
+    local n = node_copy(kern_node)
+    n.kern = dim
+    return n
+end
+
+local glue_node = new_node(glue_code)
+glue_node.subtype = userskip
+
+local function get_glue_node(dim, stretch, shrink)
+    local n   = node_copy(glue_node)
+    n.width   = dim
+    n.stretch = stretch
+    n.shrink  = shrink
+    return n
+end
+
+local penalty_node   = new_node(penalty_code)
+penalty_node.penalty = 10000
+
+local function get_penalty_node()
+    return node_copy(penalty_node)
+end
+
+-- all possible space characters according to section 6.2 of the Unicode Standard
+-- https://www.unicode.org/versions/Unicode12.0.0/ch06.pdf
+local space_chars = {
+    [0x20] = true, -- space
+    [0xA0] = true, -- no-break space
+    [0x1680] = true, -- ogham space mark
+    [0x2000] = true, -- en quad
+    [0x2001] = true, -- em quad
+    [0x2002] = true, -- en space
+    [0x2003] = true, -- em space
+    [0x2004] = true, -- three-per-em-space
+    [0x2005] = true, -- four-per-em space
+    [0x2006] = true, -- six-per-em space
+    [0x2007] = true, -- figure space
+    [0x2008] = true, -- punctuation space
+    [0x2009] = true, -- thin space
+    [0x200A] = true, -- hair space
+    [0x202F] = true, -- narrow no-break space
+    [0x205F] = true, -- medium mathematical space
+    [0x3000] = true -- ideographic space
+}
+
+-- all left bracket characters, referenced by their Unicode slot
+local left_bracket_chars = {
+    [0x28] = true, -- left parenthesis
+    [0x5B] = true, -- left square bracket
+    [0x7B] = true, -- left curly bracket
+    [0x27E8] = true -- mathematical left angle bracket
+}
+
+-- all right bracket characters, referenced by their Unicode slot
+local right_bracket_chars = {
+    [0x29] = true,  -- right parenthesis
+    [0x5D] = true,  -- right square bracket
+    [0x7D] = true,  -- right curly bracket
+    [0x27E9] = true -- mathematical right angle bracket
+}
+
+-- question and exclamation marks, referenced by their Unicode slot
+local question_exclamation_chars = {
+    [0x21] = true,   -- exclamation mark !
+    [0x3F] = true,   -- question mark ?
+    [0x203C] = true, -- double exclamation mark ‼
+    [0x203D] = true, -- interrobang ‽
+    [0x2047] = true, -- double question mark ⁇
+    [0x2048] = true, -- question exclamation mark ⁈
+    [0x2049] = true  -- exclamation question mark ⁉
+}
+
+-- from nodes-tst.lua, adapted
+local function somespace(n)
+    if n then
+        local id, subtype = n.id, n.subtype
+        if id == glue_code then
+            -- it is dangerous to remove all the type of glue
+            return removable_skip[subtype]
+        elseif id == kern_code then
+            -- remove only user's kern
+            return subtype == userkern
+        elseif id == glyph_code then
+            return space_chars[n.char]
+        end
+    end
+end
+
+local function someleftbracket(n)
+    if n then
+        local id = n.id
+        if id == glyph_code then
+            return left_bracket_chars[n.char]
+        end
+    end
+end
+
+local function somerightbracket(n)
+    if n then
+        local id = n.id
+        if id == glyph_code then
+            return right_bracket_chars[n.char]
+        end
+    end
+end
+
+local function question_exclamation_sequence(n1, n2)
+    if n1 and n2 then
+        local id1 = n1.id
+        local id2 = n2.id
+        if id1 == glyph_code and id2 == glyph_code then
+            return question_exclamation_chars[n1.char] and question_exclamation_chars[n2.char]
+        end
+    end
+end
+
+-- idem
+local function somepenalty(n, value)
+    if n then
+        local id = n.id
+        if id == penalty_code then
+            if value then
+                return n.penalty == value
+            else
+                return true
+            end
+        end
+    end
+end
+
+local punct_attr = new_attribute("polyglossia_punct")
+
+local lang_id      = {}
+local lang_counter = 0
+local left_space   = {}
+local right_space  = {}
+
+local function ensure_lang_id(lang)
+    if not lang_id[lang] then
+        lang_counter = lang_counter + 1
+        lang_id[lang] = lang_counter
+    end
+    return lang_id[lang]
+end
+
+local function clear_spaced_characters(lang)
+    local id = ensure_lang_id(lang)
+    left_space[id]  = {}
+    right_space[id] = {}
+end
+
+local function illegal_unit(unit)
+    if unit then
+        texio.write_nl('Illegal spacing unit "'..unit..'".')
+    else
+        texio.write_nl('Spacing unit is a nil value.')
+    end
+end
+
+local function add_left_spaced_character(lang, char, kern, unit, rubber)
+-- The parameter kern is a number meant as a fraction of the unit.
+-- The unit can be "quad" (1em) or "space" (interword space).
+-- The parameter rubber is a Boolean value indicating if the inserted space is
+-- stretchable and shrinkable (only relevant if the unit is "space").
+    local id = ensure_lang_id(lang)
+    if unit == "quad" or unit == "space" then
+        left_space[id][char] = {}
+        left_space[id][char]["kern"] = kern
+        left_space[id][char]["unit"] = unit
+        left_space[id][char]["rubber"] = rubber
+    else
+        illegal_unit(unit)
+    end
+end
+
+local function add_right_spaced_character(lang, char, kern, unit, rubber)
+    local id = ensure_lang_id(lang)
+    if unit == "quad" or unit == "space" then
+        right_space[id][char] = {}
+        right_space[id][char]["kern"] = kern
+        right_space[id][char]["unit"] = unit
+        right_space[id][char]["rubber"] = rubber
+    else
+        illegal_unit(unit)
+    end
+end
+
+-- from typo-spa.lua, adapted
+local function process(head)
+    local current = head
+    while current do
+        local id = current.id
+        if id == glyph_code then
+            local attr = has_attribute(current, punct_attr)
+            if attr then
+                local char, leftspace, rightspace
+                if current.char <= 0x10FFFF then -- greater values may cause problems with utf8.char
+                    char = utf8.char(current.char)
+                    leftspace  = left_space[attr][char]
+                    rightspace = right_space[attr][char]
+                end
+                if leftspace or rightspace then
+                    local fontparameters = fonts.hashes.parameters[current.font]
+                    local unit, stretch, shrink, spacing_node
+                    if leftspace and fontparameters then
+                        local prev = getprev(current)
+                        local space_exception = false
+                        if prev then
+                            -- do not add space after left (opening) bracket and between question/exclamation marks
+                            space_exception = someleftbracket(prev) or question_exclamation_sequence(prev, current)
+                            -- TODO: there is a question here: do we override a preceding space or not?...
+                            while somespace(prev) do
+                                head = remove_node(head, prev)
+                                prev = getprev(current)
+                            end
+                            if somepenalty(prev, 10000) then
+                                head = remove_node(head, prev)
+                            end
+                        end
+                        if leftspace.unit == "quad" then
+                            unit = fontparameters.quad
+                            spacing_node = get_kern_node(leftspace.kern*unit)
+                        elseif leftspace.unit == "space" then
+                            unit = fontparameters.space
+                            if leftspace.rubber then
+                                stretch = leftspace.kern*fontparameters.space_stretch
+                                shrink  = leftspace.kern*fontparameters.space_shrink
+                                spacing_node = get_glue_node(leftspace.kern*unit, stretch, shrink)
+                                head = insert_node_before(head, current, get_penalty_node())
+                            else
+                                spacing_node = get_kern_node(leftspace.kern*unit)
+                            end
+                        end
+                        if not space_exception then
+                            head = insert_node_before(head, current, spacing_node)
+                        end
+                    end
+                    if rightspace and fontparameters then
+                        local next = getnext(current)
+                        local space_exception = false
+                        if next then
+                            -- do not add space before right (closing) bracket
+                            space_exception = somerightbracket(next)
+                            local nextnext = getnext(next)
+                            if somepenalty(next, 10000) and somespace(nextnext) then
+                                head, next = remove_node(head, next)
+                            end
+                            while somespace(next) do
+                                head, next = remove_node(head, next)
+                            end
+                        end
+                        if rightspace.unit == "quad" then
+                            unit = fontparameters.quad
+                            spacing_node = get_kern_node(rightspace.kern*unit)
+                        elseif rightspace.unit == "space" then
+                            unit = fontparameters.space
+                            if rightspace.rubber then
+                                stretch = rightspace.kern*fontparameters.space_stretch
+                                shrink  = rightspace.kern*fontparameters.space_shrink
+                                spacing_node = get_glue_node(rightspace.kern*unit, stretch, shrink)
+                                if not space_exception then
+                                    head, current = insert_node_after(head, current, get_penalty_node())
+                                end
+                            else
+                                spacing_node = get_kern_node(rightspace.kern*unit)
+                            end
+                        end
+                        if not space_exception then
+                            head, current = insert_node_after(head, current, spacing_node)
+                        end
+                    end
+                end
+            end
+        elseif id == math_code then
+            -- warning: this is a feature of luatex > 0.76
+            current = end_of_math(current) -- weird, can return nil .. no math end?
+        end
+        current = getnext(current) -- no error even if current is nil
+    end
+    return head
+end
+
+local function activate(lang)
+    local id = ensure_lang_id(lang)
+    -- We set the punctuation attribute to a language id here. This is
+    -- important to be able to intermix languages with different spacings
+    -- in one paragraph.
+    tex.setattribute(punct_attr, id)
+    for _, callback_name in ipairs{ "pre_linebreak_filter", "hpack_filter" } do
+        if not priority_in_callback(callback_name, "polyglossia-punct.process") then
+            add_to_callback(callback_name, process, "polyglossia-punct.process", 1)
+        end
+    end
+end
+
+local function deactivate()
+    tex.setattribute(punct_attr, -0x7FFFFFFF) -- this value means "unset"
+    -- Though it would make compilation slightly faster, it is not possible to
+    -- safely uncomment the following lines. Imagine the following case: you
+    -- start a paragraph by some spaced punctuation text, then, in the same
+    -- paragraph, you change the language to something else, and thus call the
+    -- following lines. This means that, at the end of the paragraph, the
+    -- function won't be in the callback, so the beginning of the paragraph
+    -- won't be processed by it.
+    -- if priority_in_callback(callback_name, "polyglossia-punct.process") then
+    --     remove_from_callback(callback_name, "polyglossia-punct.process")
+    -- end
+end
+
+polyglossia.activate_punct             = activate
+polyglossia.deactivate_punct           = deactivate
+polyglossia.add_left_spaced_character  = add_left_spaced_character
+polyglossia.add_right_spaced_character = add_right_spaced_character
+polyglossia.clear_spaced_characters    = clear_spaced_characters
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-punct.lua>
+%<*polyglossia-sanskrit.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-sanskrit.lua}
+%    \begin{macrocode}
+require('polyglossia-punct')
+
+-- How do we now, in Lua, what a \thinspace is? In the LaTeX source (latex.ltx)
+-- it is defined as:
+-- \def\thinspace{\leavevmode at ifvmode\kern .16667em }
+-- I see no way of seeing if it has been overriden or not. So we stick to this
+-- value.
+local thinspace = 0.16667 -- 1/6
+
+local function space_left(char)
+    polyglossia.add_left_spaced_character('sanskrit', char, thinspace, 'quad')
+end
+
+polyglossia.clear_spaced_characters('sanskrit')
+space_left('!')
+space_left('?')
+space_left('‼')
+space_left('⁇')
+space_left('⁈')
+space_left('⁉')
+space_left('‽') -- U+203D (interrobang)
+space_left(':')
+space_left(';')
+space_left('।') -- danda, U+0964
+space_left('॥') -- double danda, U+0965
+
+local function activate_sanskrit_punct()
+    polyglossia.activate_punct('sanskrit')
+end
+
+local function deactivate_sanskrit_punct()
+    polyglossia.deactivate_punct()
+end
+
+polyglossia.activate_sanskrit_punct   = activate_sanskrit_punct
+polyglossia.deactivate_sanskrit_punct = deactivate_sanskrit_punct
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-sanskrit.lua>
+%<*polyglossia-tibt.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia-tibt.lua}
+%    \begin{macrocode}
+require('polyglossia') -- just in case...
+
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+local priority_in_callback = luatexbase.priority_in_callback
+
+local next, type = next, type
+
+local nodes, fonts, node = nodes, fonts, node
+
+local nodecodes          = nodes.nodecodes --- <= preloaded node.types()
+
+local insert_node_before = node.insert_before
+local insert_node_after  = node.insert_after
+local remove_node        = nodes.remove
+local copy_node          = node.copy
+local has_attribute      = node.has_attribute
+
+local end_of_math        = node.end_of_math
+if not end_of_math then -- luatex < .76
+  local traverse_nodes = node.traverse_id
+  local math_code      = nodecodes.math
+  local end_of_math = function (n)
+    for n in traverse_nodes(math_code, n.next) do
+      return n
+    end
+  end
+end
+
+-- node types as of April 2013
+local glyph_code         = nodecodes.glyph
+local penalty_code       = nodecodes.penalty
+local kern_code          = nodecodes.kern
+
+-- we make a new node, so that we can copy it later on
+local penalty_node  = node.new(penalty_code)
+penalty_node.penalty = 50 -- corresponds to the penalty LaTeX sets at explicit hyphens
+
+local function get_penalty_node()
+  return copy_node(penalty_node)
+end
+
+local xpgtibtattr = luatexbase.attributes['xpg at tibteol']
+
+local tsheg = unicode.utf8.byte('་')
+
+-- from typo-spa.lua
+local function process(head)
+    local start = head
+    -- head is always begin of par (whatsit), so we have at least two prev nodes
+    -- penalty followed by glue
+    while start do
+        local id = start.id
+        if id == glyph_code then 
+            local attr = has_attribute(start, xpgtibtattr)
+            if attr and attr > 0 then
+                if start.char == tsheg then
+                    if start.next then
+                        insert_node_after(head,start,get_penalty_node())
+                    end
+                end
+            end
+        elseif id == math_code then
+            -- warning: this is a feature of luatex > 0.76
+            start = end_of_math(start) -- weird, can return nil .. no math end?
+        end
+        if start then
+            start = start.next
+        end
+    end
+    return head
+end
+
+local callback_name = "pre_linebreak_filter"
+
+local function activate()
+  if not priority_in_callback (callback_name, "polyglossia-tibt.process") then
+    add_to_callback(callback_name, process, "polyglossia-tibt.process", 1)
+  end
+end
+
+local function desactivate()
+  if priority_in_callback (callback_name, "polyglossia-tibt.process") then
+    remove_from_callback(callback_name, "polyglossia-tibt.process")
+  end
+end
+
+polyglossia.activate_tibt_eol    = activate
+polyglossia.desactivate_tibt_eol = desactivate
+%    \end{macrocode}
+% \iffalse
+%</polyglossia-tibt.lua>
+%<*polyglossia.lua>
+% \fi
+% \clearpage
+% 
+% \subsection{polyglossia.lua}
+%    \begin{macrocode}
+
+local module_name = "polyglossia"
+local polyglossia_module = {
+    name          = module_name,
+    version       = 1.3,
+    date          = "2013/05/11",
+    description   = "Polyglossia",
+    author        = "Elie Roux",
+    copyright     = "Elie Roux",
+    license       = "CC0"
+}
+
+luatexbase.provides_module(polyglossia_module)
+
+local log_info = function(message, ...)
+    luatexbase.module_info(module_name, message:format(...))
+end
+local log_warn = function(message, ...)
+    luatexbase.module_warning(module_name, message:format(...))
+end
+
+polyglossia = polyglossia or {}
+local polyglossia = polyglossia
+
+local function select_language(lang, id)
+    polyglossia.current_language = lang
+end
+
+local function set_default_language(lang, id)
+    polyglossia.default_language = lang
+end
+
+local byte = utf8.codepoint -- use standard module of lua 5.3
+
+local check_char
+
+if luaotfload and luaotfload.aux and luaotfload.aux.font_has_glyph then
+    local font_has_glyph = luaotfload.aux.font_has_glyph
+    function check_char(chr)
+        local codepoint = tonumber(chr) or byte(chr)
+        if font_has_glyph(font.current(), codepoint) then
+            tex.sprint('1')
+        else
+            tex.sprint('0')
+        end
+    end
+else
+    function check_char(chr) -- always in current font
+        local fontid    = font.current()
+        local fontdata  = font.getfont(fontid) or font.fonts[fontid]
+        local chardata  = fontdata.characters
+        local codepoint = tonumber(chr) or byte(chr)
+        if chardata and chardata[codepoint] then
+            tex.sprint('1')
+        else
+            tex.sprint('0')
+        end
+    end
+end
+
+local function load_tibt_eol()
+    require('polyglossia-tibt')
+end
+
+-- predefined l at nohyphenation or LuaTeX's maximum value for \language
+local nohyphid = luatexbase.registernumber'l at nohyphenation' or 16383
+
+-- key `nohyphenation` is for .sty file when possibly undefined l at 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 at 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 at xyz.
+            --
+            -- Threfore here we will compare LaTeX's \newlanguage number with
+            -- LuaTeX's lang.new() id and select the bigger one for our new
+            -- language object. Also we will update LaTeX's language register
+            -- by this new id, so that another possible \newlanguage should not
+            -- overwrite our language object.
+            --
+            -- get next \newlanguage allocation number
+            local langcnt = tex.count[lang_register] + 1
+            -- get new lang object
+            local langobject = lang.new()
+            local langid = lang.id(langobject)
+            -- get bigger one between \newlanguage and new lang obj id
+            local newlangid = math.max(langcnt, langid)
+            -- set language register for possible \newlanguage
+            tex.setcount('global', lang_register, newlangid)
+            -- get new lang object if needeed
+            if langid ~= newlangid then
+                langobject = lang.new(newlangid)
+            end
+
+            -- load hyphenation patterns and exceptions
+            for _,v in ipairs{ 'patterns', 'hyphenation' } do
+                local data = langdata[v]
+                if data and data ~= '' then
+                    -- cope with comma separated list, such as serbian
+                    for _,vv in ipairs(data:explode',+') do
+                        local filepath = kpse.find_file(vv)
+                        if filepath then
+                            local fh = io.open(filepath)
+                            lang[v](langobject, fh:read'a')
+                            fh:close()
+                        else
+                            log_warn('Hyphenation file %s not found', vv)
+                        end
+                    end
+                end
+            end
+
+            newloader_loaded_languages[langentry] = langobject
+
+            log_info('Language %s was not yet loaded; created with id %i',
+                     langentry, newlangid)
+            return newlangid
+        else
+            log_warn('Language %s not found in language.dat.lua', langentry)
+            return nohyphid
+        end
+    end
+end
+
+polyglossia.select_language = select_language
+polyglossia.set_default_language = set_default_language
+polyglossia.check_char = check_char
+polyglossia.load_tibt_eol = load_tibt_eol
+polyglossia.newloader = newloader
+polyglossia.newloader_loaded_languages = newloader_loaded_languages
+-- global variables:
+-- polyglossia.default_language
+-- polyglossia.current_language
+%    \end{macrocode}
+% \iffalse
+%</polyglossia.lua>
+%<*babel-hebrewalph.def>
+% \fi
+% \clearpage
+% 
+% \subsection{babel-hebrewalph.def}
+%    \begin{macrocode}
+\ProvidesFile{babel-hebrewalph.def}
+         [2010/03/02 %
+         Babel definitions for Hebrew numerals^^J
+         Adapted from hebrew.ldf (2005/03/30 v2.3h)]
+\newif\if at gim@apost  % whether we print apostrophes (gereshayim)
+\newif\if at gim@final  % whether we use final or initial letters
+\newcommand*\hebrewnumeral[1]{%
+  \expandafter\@hebrew at numeral\expandafter{\the\numexpr#1}%
+}
+\newcommand*\Hebrewnumeral[1]{%
+  \expandafter\@Hebrew at numeral\expandafter{\the\numexpr#1}%
+}
+\newcommand*\Hebrewnumeralfinal[1]{%
+  \expandafter\@Hebrew at numeralfinal\expandafter{\the\numexpr#1}%
+}
+\newrobustcmd*{\@hebrew at numeral}[1]      % no apostrophe, no final letters
+ {{\@gim at finalfalse\@gim at apostfalse\@hebrew@@numeral{#1}}}
+\newrobustcmd*{\@Hebrew at numeral}[1]      % apostrophe, no final letters
+ {{\@gim at finalfalse\@gim at aposttrue\@hebrew@@numeral{#1}}}
+\newrobustcmd*{\@Hebrew at numeralfinal}[1] % apostrophe, final letters
+ {{\@gim at finaltrue\@gim at aposttrue\@hebrew@@numeral{#1}}}
+\newcommand*{\@hebrew@@numeral}[1]{%
+  \ifnum#1<\z@\space\xpg at warning{Illegal value (#1) for Hebrew numeral}%
+  \else
+    \@tempcnta=#1\@tempcntb=#1\relax
+    \divide\@tempcntb by 1000
+    \ifnum\@tempcntb=0\gim at nomil\@tempcnta\relax
+    \else{\@gim at apostfalse\@gim at finalfalse\@hebrew at numeral\@tempcntb}׳%
+          \multiply\@tempcntb by 1000\relax
+          \advance\@tempcnta by -\@tempcntb\relax
+          \gim at nomil\@tempcnta\relax
+    \fi
+  \fi
+}
+\def\hebrew at alph@zero{}
+\newcommand*{\gim at nomil}[1]{\@tempcnta=#1\@gim at prevfalse
+  \@tempcntb=\@tempcnta\divide\@tempcntb by 100\relax % hundreds digit
+  \ifcase\@tempcntb                     % print nothing if no hundreds
+     \or\gim at print{100}{ק}%
+     \or\gim at print{200}{ר}%
+     \or\gim at print{300}{ש}%
+     \or\gim at print{400}{ת}%
+     \or ת\@gim at prevtrue\gim at print{500}{ק}%
+     \or ת\@gim at prevtrue\gim at print{600}{ר}%
+     \or ת\@gim at prevtrue\gim at print{700}{ש}%
+     \or ת\@gim at prevtrue\gim at print{800}{ת}%
+     \or ת\@gim at prevtrue ת\gim at 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 at print {9}{ט}% tet-zayin
+         \else\ifnum\@tempcnta = 15 \gim at print {9}{ט}% tet-vav
+         \else                      \gim at print{10}{י}%
+              \fi % \@tempcnta = 15
+              \fi % \@tempcnta = 16
+      \or\gim at print{20}{\if at gim@final ך\else כ\fi}%
+      \or\gim at print{30}{ל}%
+      \or\gim at print{40}{\if at gim@final ם\else מ\fi}%
+      \or\gim at print{50}{\if at gim@final ן\else נ\fi}%
+      \or\gim at print{60}{ס}%
+      \or\gim at print{70}{ע}%
+      \or\gim at print{80}{\if at gim@final ף\else פ\fi}%
+      \or\gim at print{90}{\if at gim@final ץ\else צ\fi}%
+  \fi
+  \ifcase\@tempcnta
+      \hebrew at alph@zero%  empty but can be defined if desired
+      \or\gim at print{1}{א}%
+      \or\gim at print{2}{ב}%
+      \or\gim at print{3}{ג}%
+      \or\gim at print{4}{ד}%
+      \or\gim at print{5}{ה}%
+      \or\gim at print{6}{ו}%
+      \or\gim at print{7}{ז}%
+      \or\gim at print{8}{ח}%
+      \or\gim at print{9}{ט}%
+  \fi
+}
+\newif\if at gim@prev % flag if a previous letter has been typeset
+\newcommand*{\gim at 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 at gim@prev\if at gim@apost ״\fi#2%
+     \else#2\if at gim@apost ׳\fi\fi%
+  \else{\@gim at finalfalse#2}\@gim at prevtrue\fi}
+\def\Alphfinal#1{\expandafter\@Alphfinal\csname c@#1\endcsname}%
+\providecommand*{\@Alphfinal}[1]{\Hebrewnumeralfinal{#1}}
+%    \end{macrocode}
+% \iffalse
+%</babel-hebrewalph.def>
+%<*babelsh.def>
+% \fi
+% \clearpage
+% 
+% \subsection{babelsh.def}
+%    \begin{macrocode}
+\ifx\initiate at active@char\@undefined
+\else
+  \bbl at 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 at stripslash{\expandafter\@gobble\string}
+\def\bbl at add#1#2{%
+  \bbl at ifunset{\bbl at stripslash#1}%
+    {\def#1{#2}}%
+    {\expandafter\def\expandafter#1\expandafter{#1#2}}}
+%
+% ------------------------------------------------------------------------------
+%
+% line 73 to 74 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\long\def\bbl at afterelse#1\else#2\fi{\fi#1}
+\long\def\bbl at afterfi#1\fi{\fi#1}
+%
+% ------------------------------------------------------------------------------
+%
+% line 399 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\let\bbl at opt@shorthands\@nnil
+%
+% ------------------------------------------------------------------------------
+%
+% lines 432 to 445 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\bbl at opt@shorthands\@nnil
+  \def\bbl at ifshorthand#1#2#3{#2}%
+\else\ifx\bbl at opt@shorthands\@empty
+  \def\bbl at ifshorthand#1#2#3{#3}%
+\else
+  \def\bbl at ifshorthand#1{%
+    \bbl at xin@{\string#1}{\bbl at opt@shorthands}%
+    \ifin@
+      \expandafter\@firstoftwo
+    \else
+      \expandafter\@secondoftwo
+    \fi}
+  \edef\bbl at opt@shorthands{%
+    \expandafter\bbl at sh@string\bbl at opt@shorthands\@empty}%
+%
+% ------------------------------------------------------------------------------
+%
+% line 450 from babel.sty
+%
+% ------------------------------------------------------------------------------
+%
+\fi\fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 389 to 424 from switch.def
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\PackageError\@undefined
+  \def\bbl at error#1#2{%
+    \begingroup
+      \newlinechar=`\^^J
+      \def\\{^^J(babel) }%
+      \errhelp{#2}\errmessage{\\#1}%
+    \endgroup}
+  \def\bbl at warning#1{%
+    \begingroup
+      \newlinechar=`\^^J
+      \def\\{^^J(polyglossia) }%
+      \message{\\#1}%
+    \endgroup}
+  \def\bbl at info#1{%
+    \begingroup
+      \newlinechar=`\^^J
+      \def\\{^^J}%
+      \wlog{#1}%
+    \endgroup}
+\else
+  \def\bbl at error#1#2{%
+    \begingroup
+      \def\\{\MessageBreak}%
+      \PackageError{polyglossia}{#1}{#2}%
+    \endgroup}
+  \def\bbl at warning#1{%
+    \begingroup
+      \def\\{\MessageBreak}%
+      \PackageWarning{polyglossia}{#1}%
+    \endgroup}
+  \def\bbl at info#1{%
+    \begingroup
+      \def\\{\MessageBreak}%
+      \PackageInfo{polyglossia}{#1}%
+    \endgroup}
+\fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 48 to 69 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\ifx\bbl at ifshorthand\@undefined
+  \let\bbl at opt@shorthands\@nnil
+  \def\bbl at ifshorthand#1#2#3{#2}%
+  \let\bbl at language@opts\@empty
+  \ifx\babeloptionstrings\@undefined
+    \let\bbl at opt@strings\@nnil
+  \else
+    \let\bbl at opt@strings\babeloptionstrings
+  \fi
+  \def\BabelStringsDefault{generic}
+  \def\bbl at tempa{normal}
+  \ifx\babeloptionmath\bbl at tempa
+    \def\bbl at mathnormal{\noexpand\textormath}
+  \fi
+  \def\AfterBabelLanguage#1#2{}
+  \ifx\BabelModifiers\@undefined\let\BabelModifiers\relax\fi
+  \let\bbl at afterlang\relax
+  \def\bbl at opt@safe{BR}
+  \ifx\@uclclist\@undefined\let\@uclclist\@empty\fi
+  \ifx\bbl at trace\@undefined\def\bbl at trace#1{}\fi
+  \expandafter\newif\csname ifbbl at single\endcsname
+\fi
+%
+% ------------------------------------------------------------------------------
+%
+% line 108 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at csarg#1#2{\expandafter#1\csname bbl@#2\endcsname}%
+
+% ------------------------------------------------------------------------------
+%
+% lines 110 to 116 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+
+\def\bbl at loop#1#2#3{\bbl@@loop#1{#3}#2,\@nnil,}
+\def\bbl at loopx#1#2{\expandafter\bbl at loop\expandafter#1\expandafter{#2}}
+\def\bbl@@loop#1#2#3,{%
+  \ifx\@nnil#3\relax\else
+    \def#1{#3}#2\bbl at afterfi\bbl@@loop#1{#2}%
+  \fi}
+\def\bbl at for#1#2#3{\bbl at loopx#1{#2}{\ifx#1\@empty\else#3\fi}}
+
+% ------------------------------------------------------------------------------
+%
+% lines 125 to 130 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at exp#1{%
+  \begingroup
+    \let\\\noexpand
+    \def\<##1>{\expandafter\noexpand\csname##1\endcsname}%
+    \edef\bbl at exp@aux{\endgroup#1}%
+  \bbl at exp@aux}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 144 to 149 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at ifunset#1{%
+  \expandafter\ifx\csname#1\endcsname\relax
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 234 to 243 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\chardef\bbl at engine=%
+  \ifx\directlua\@undefined
+    \ifx\XeTeXinputencoding\@undefined
+      \z@
+    \else
+      \tw@
+    \fi
+  \else
+    \@ne
+  \fi
+%
+% ------------------------------------------------------------------------------
+%
+% lines 255 to 258 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at 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 at usehooks#1#2{}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 443 to 558 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at add@special#1{% 1:a macro like \", \?, etc.
+  \bbl at add\dospecials{\do#1}% test @sanitize = \relax, for back. compat.
+  \bbl at ifunset{@sanitize}{}{\bbl at add\@sanitize{\@makeother#1}}%
+  \ifx\nfss at catcodes\@undefined\else % TODO - same for above
+    \begingroup
+      \catcode`#1\active
+      \nfss at catcodes
+      \ifnum\catcode`#1=\active
+        \endgroup
+        \bbl at add\nfss at catcodes{\@makeother#1}%
+      \else
+        \endgroup
+      \fi
+  \fi}
+\def\bbl at 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 at active@def#1#2#3#4{%
+  \@namedef{#3#1}{%
+    \expandafter\ifx\csname#2 at sh@#1@\endcsname\relax
+      \bbl at afterelse\bbl at sh@select#2#1{#3 at arg#1}{#4#1}%
+    \else
+      \bbl at afterfi\csname#2 at sh@#1@\endcsname
+    \fi}%
+  \long\@namedef{#3 at arg#1}##1{%
+    \expandafter\ifx\csname#2 at sh@#1@\string##1@\endcsname\relax
+      \bbl at afterelse\csname#4#1\endcsname##1%
+    \else
+      \bbl at afterfi\csname#2 at sh@#1@\string##1@\endcsname
+    \fi}}%
+\def\initiate at active@char#1{%
+  \bbl at ifunset{active at char\string#1}%
+    {\bbl at withactive
+      {\expandafter\@initiate at active@char\expandafter}#1\string#1#1}%
+    {}}
+\def\@initiate at active@char#1#2#3{%
+  \bbl at csarg\edef{oricat@#2}{\catcode`#2=\the\catcode`#2\relax}%
+  \ifx#1\@undefined
+    \bbl at csarg\edef{oridef@#2}{\let\noexpand#1\noexpand\@undefined}%
+  \else
+    \bbl at csarg\let{oridef@@#2}#1%
+    \bbl at csarg\edef{oridef@#2}{%
+      \let\noexpand#1%
+      \expandafter\noexpand\csname bbl at oridef@@#2\endcsname}%
+  \fi
+  \ifx#1#3\relax
+    \expandafter\let\csname normal at char#2\endcsname#3%
+  \else
+    \bbl at info{Making #2 an active character}%
+    \ifnum\mathcode`#2=\ifodd\bbl at engine"1000000 \else"8000 \fi
+      \@namedef{normal at char#2}{%
+        \textormath{#3}{\csname bbl at oridef@@#2\endcsname}}%
+    \else
+      \@namedef{normal at char#2}{#3}%
+    \fi
+    \bbl at restoreactive{#2}%
+    \AtBeginDocument{%
+      \catcode`#2\active
+      \if at filesw
+        \immediate\write\@mainaux{\catcode`\string#2\active}%
+      \fi}%
+    \expandafter\bbl at add@special\csname#2\endcsname
+    \catcode`#2\active
+  \fi
+  \let\bbl at tempa\@firstoftwo
+  \if\string^#2%
+    \def\bbl at tempa{\noexpand\textormath}%
+  \else
+    \ifx\bbl at mathnormal\@undefined\else
+      \let\bbl at tempa\bbl at mathnormal
+    \fi
+  \fi
+  \expandafter\edef\csname active at char#2\endcsname{%
+    \bbl at tempa
+      {\noexpand\if at safe@actives
+         \noexpand\expandafter
+         \expandafter\noexpand\csname normal at char#2\endcsname
+       \noexpand\else
+         \noexpand\expandafter
+         \expandafter\noexpand\csname bbl at doactive#2\endcsname
+       \noexpand\fi}%
+     {\expandafter\noexpand\csname normal at char#2\endcsname}}%
+  \bbl at csarg\edef{doactive#2}{%
+    \expandafter\noexpand\csname user at active#2\endcsname}%
+  \bbl at csarg\edef{active@#2}{%
+    \noexpand\active at prefix\noexpand#1%
+    \expandafter\noexpand\csname active at char#2\endcsname}%
+  \bbl at csarg\edef{normal@#2}{%
+    \noexpand\active at prefix\noexpand#1%
+    \expandafter\noexpand\csname normal at char#2\endcsname}%
+  \expandafter\let\expandafter#1\csname bbl at normal@#2\endcsname
+  \bbl at active@def#2\user at group{user at active}{language at active}%
+  \bbl at active@def#2\language at group{language at active}{system at active}%
+  \bbl at active@def#2\system at group{system at active}{normal at char}%
+  \expandafter\edef\csname\user at group @sh@#2@@\endcsname
+    {\expandafter\noexpand\csname normal at char#2\endcsname}%
+  \expandafter\edef\csname\user at group @sh@#2@\string\protect@\endcsname
+    {\expandafter\noexpand\csname user at active#2\endcsname}%
+  \if\string'#2%
+    \let\prim at s\bbl at prim@s
+    \let\active at math@prime#1%
+  \fi
+  \bbl at usehooks{initiateactive}{{#1}{#2}{#3}}}
+\@ifpackagewith{babel}{KeepShorthandsActive}%
+  {\let\bbl at restoreactive\@gobble}%
+  {\def\bbl at restoreactive#1{%
+     \bbl at exp{%
+%
+% ------------------------------------------------------------------------------
+%
+% lines 561 to 755 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+       \\\AtEndOfPackage
+         {\catcode`#1=\the\catcode`#1\relax}}}%
+   \AtEndOfPackage{\let\bbl at restoreactive\@gobble}}
+\def\bbl at sh@select#1#2{%
+  \expandafter\ifx\csname#1 at sh@#2 at sel\endcsname\relax
+    \bbl at afterelse\bbl at scndcs
+  \else
+    \bbl at afterfi\csname#1 at sh@#2 at sel\endcsname
+  \fi}
+\def\active at prefix#1{%
+  \ifx\protect\@typeset at protect
+  \else
+    \ifx\protect\@unexpandable at protect
+      \noexpand#1%
+    \else
+      \protect#1%
+    \fi
+    \expandafter\@gobble
+  \fi}
+\newif\if at safe@actives
+\@safe at activesfalse
+\def\bbl at restore@actives{\if at safe@actives\@safe at activesfalse\fi}
+\def\bbl at activate#1{%
+  \bbl at withactive{\expandafter\let\expandafter}#1%
+    \csname bbl at active@\string#1\endcsname}
+\def\bbl at deactivate#1{%
+  \bbl at withactive{\expandafter\let\expandafter}#1%
+    \csname bbl at normal@\string#1\endcsname}
+\def\bbl at firstcs#1#2{\csname#1\endcsname}
+\def\bbl at scndcs#1#2{\csname#2\endcsname}
+\def\declare at shorthand#1#2{\@decl at short{#1}#2\@nil}
+\def\@decl at short#1#2#3\@nil#4{%
+  \def\bbl at tempa{#3}%
+  \ifx\bbl at tempa\@empty
+    \expandafter\let\csname #1 at sh@\string#2 at sel\endcsname\bbl at scndcs
+    \bbl at ifunset{#1 at sh@\string#2@}{}%
+      {\def\bbl at tempa{#4}%
+       \expandafter\ifx\csname#1 at sh@\string#2@\endcsname\bbl at tempa
+       \else
+         \bbl at info
+           {Redefining #1 shorthand \string#2\\%
+            in language \CurrentOption}%
+       \fi}%
+    \@namedef{#1 at sh@\string#2@}{#4}%
+  \else
+    \expandafter\let\csname #1 at sh@\string#2 at sel\endcsname\bbl at firstcs
+    \bbl at ifunset{#1 at sh@\string#2@\string#3@}{}%
+      {\def\bbl at tempa{#4}%
+       \expandafter\ifx\csname#1 at sh@\string#2@\string#3@\endcsname\bbl at tempa
+       \else
+         \bbl at info
+           {Redefining #1 shorthand \string#2\string#3\\%
+            in language \CurrentOption}%
+       \fi}%
+    \@namedef{#1 at sh@\string#2@\string#3@}{#4}%
+  \fi}
+\def\textormath{%
+  \ifmmode
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi}
+\def\user at group{user}
+\def\language at group{english}
+\def\system at group{system}
+\def\useshorthands{%
+  \@ifstar\bbl at usesh@s{\bbl at usesh@x{}}}
+\def\bbl at usesh@s#1{%
+  \bbl at usesh@x
+    {\AddBabelHook{babel-sh-\string#1}{afterextras}{\bbl at activate{#1}}}%
+    {#1}}
+\def\bbl at usesh@x#1#2{%
+  \bbl at ifshorthand{#2}%
+    {\def\user at group{user}%
+     \initiate at active@char{#2}%
+     #1%
+     \bbl at activate{#2}}%
+    {\bbl at 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 at language@group{user@\language at group}
+\def\bbl at set@user at generic#1#2{%
+  \bbl at ifunset{user at generic@active#1}%
+    {\bbl at active@def#1\user at language@group{user at active}{user at generic@active}%
+     \bbl at active@def#1\user at group{user at generic@active}{language at active}%
+     \expandafter\edef\csname#2 at sh@#1@@\endcsname{%
+       \expandafter\noexpand\csname normal at char#1\endcsname}%
+     \expandafter\edef\csname#2 at sh@#1@\string\protect@\endcsname{%
+       \expandafter\noexpand\csname user at active#1\endcsname}}%
+  \@empty}
+\newcommand\defineshorthand[3][user]{%
+  \edef\bbl at tempa{\zap at space#1 \@empty}%
+  \bbl at for\bbl at tempb\bbl at tempa{%
+    \if*\expandafter\@car\bbl at tempb\@nil
+      \edef\bbl at tempb{user@\expandafter\@gobble\bbl at tempb}%
+      \@expandtwoargs
+        \bbl at set@user at generic{\expandafter\string\@car#2\@nil}\bbl at tempb
+    \fi
+    \declare at shorthand{\bbl at tempb}{#2}{#3}}}
+\def\languageshorthands#1{\def\language at group{#1}}
+\def\aliasshorthand#1#2{%
+  \bbl at ifshorthand{#2}%
+    {\expandafter\ifx\csname active at char\string#2\endcsname\relax
+       \ifx\document\@notprerr
+         \@notshorthand{#2}%
+       \else
+         \initiate at active@char{#2}%
+         \expandafter\let\csname active at char\string#2\expandafter\endcsname
+           \csname active at char\string#1\endcsname
+         \expandafter\let\csname normal at char\string#2\expandafter\endcsname
+           \csname normal at char\string#1\endcsname
+         \bbl at activate{#2}%
+       \fi
+     \fi}%
+    {\bbl at 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 at 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 at switch@sh\@ne#1\@nnil}
+\DeclareRobustCommand*\shorthandoff{%
+  \@ifstar{\bbl at shorthandoff\tw@}{\bbl at shorthandoff\z@}}
+\def\bbl at shorthandoff#1#2{\bbl at switch@sh#1#2\@nnil}
+\def\bbl at switch@sh#1#2{%
+  \ifx#2\@nnil\else
+    \bbl at ifunset{bbl at active@\string#2}%
+      {\bbl at 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 at oricat@\string#2\endcsname
+         \csname bbl at oridef@\string#2\endcsname
+       \fi}%
+    \bbl at afterfi\bbl at switch@sh#1%
+  \fi}
+\def\babelshorthand{\active at prefix\babelshorthand\bbl at putsh}
+\def\bbl at putsh#1{%
+  \bbl at ifunset{bbl at active@\string#1}%
+     {\bbl at putsh@i#1\@empty\@nnil}%
+     {\csname bbl at active@\string#1\endcsname}}
+\def\bbl at putsh@i#1#2\@nnil{%
+  \csname\languagename @sh@\string#1@%
+    \ifx\@empty#2\else\string#2@\fi\endcsname}
+\ifx\bbl at opt@shorthands\@nnil\else
+  \let\bbl at s@initiate at active@char\initiate at active@char
+  \def\initiate at active@char#1{%
+    \bbl at ifshorthand{#1}{\bbl at s@initiate at active@char{#1}}{}}
+  \let\bbl at s@switch at sh\bbl at switch@sh
+  \def\bbl at switch@sh#1#2{%
+    \ifx#2\@nnil\else
+      \bbl at afterfi
+      \bbl at ifshorthand{#2}{\bbl at s@switch at sh#1{#2}}{\bbl at switch@sh#1}%
+    \fi}
+  \let\bbl at s@activate\bbl at activate
+  \def\bbl at activate#1{%
+    \bbl at ifshorthand{#1}{\bbl at s@activate{#1}}{}}
+  \let\bbl at s@deactivate\bbl at deactivate
+  \def\bbl at deactivate#1{%
+    \bbl at ifshorthand{#1}{\bbl at s@deactivate{#1}}{}}
+\fi
+\newcommand\ifbabelshorthand[3]{\bbl at ifunset{bbl at active@\string#1}{#3}{#2}}
+\def\bbl at prim@s{%
+  \prime\futurelet\@let at token\bbl at pr@m at s}
+\def\bbl at if@primes#1#2{%
+  \ifx#1\@let at token
+    \expandafter\@firstoftwo
+  \else\ifx#2\@let at token
+    \bbl at afterelse\expandafter\@firstoftwo
+  \else
+    \bbl at afterfi\expandafter\@secondoftwo
+  \fi\fi}
+\begingroup
+  \catcode`\^=7  \catcode`\*=\active  \lccode`\*=`\^
+  \catcode`\'=12 \catcode`\"=\active  \lccode`\"=`\'
+  \lowercase{%
+    \gdef\bbl at pr@m at s{%
+      \bbl at if@primes"'%
+        \pr@@@s
+        {\bbl at if@primes*^\pr@@@t\egroup}}}
+\endgroup
+\initiate at active@char{~}
+\declare at shorthand{system}{~}{\leavevmode\nobreak\ }
+\bbl at activate{~}
+%
+% ------------------------------------------------------------------------------
+%
+% lines 890 to 927 from babel.def
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at allowhyphens{\ifvmode\else\nobreak\hskip\z at skip\fi}
+\def\bbl at t@one{T1}
+\def\allowhyphens{\ifx\cf at encoding\bbl at t@one\else\bbl at allowhyphens\fi}
+\newcommand\babelnullhyphen{\char\hyphenchar\font}
+\def\babelhyphen{\active at prefix\babelhyphen\bbl at hyphen}
+\def\bbl at hyphen{%
+  \@ifstar{\bbl at hyphen@i @}{\bbl at hyphen@i\@empty}}
+\def\bbl at hyphen@i#1#2{%
+  \bbl at ifunset{bbl at hy@#1#2\@empty}%
+    {\csname bbl@#1usehyphen\endcsname{\discretionary{#2}{}{#2}}}%
+    {\csname bbl at hy@#1#2\@empty\endcsname}}
+\def\bbl at usehyphen#1{%
+  \leavevmode
+  \ifdim\lastskip>\z@\mbox{#1}\else\nobreak#1\fi
+  \nobreak\hskip\z at skip}
+\def\bbl@@usehyphen#1{%
+  \leavevmode\ifdim\lastskip>\z@\mbox{#1}\else#1\fi}
+\def\bbl at hyphenchar{%
+  \ifnum\hyphenchar\font=\m at ne
+    \babelnullhyphen
+  \else
+    \char\hyphenchar\font
+  \fi}
+\def\bbl at hy@soft{\bbl at usehyphen{\discretionary{\bbl at hyphenchar}{}{}}}
+\def\bbl at hy@@soft{\bbl@@usehyphen{\discretionary{\bbl at hyphenchar}{}{}}}
+\def\bbl at hy@hard{\bbl at usehyphen\bbl at hyphenchar}
+\def\bbl at hy@@hard{\bbl@@usehyphen\bbl at hyphenchar}
+\def\bbl at hy@nobreak{\bbl at usehyphen{\mbox{\bbl at hyphenchar}}}
+\def\bbl at hy@@nobreak{\mbox{\bbl at hyphenchar}}
+\def\bbl at hy@repeat{%
+  \bbl at usehyphen{%
+    \discretionary{\bbl at hyphenchar}{\bbl at hyphenchar}{\bbl at hyphenchar}}}
+\def\bbl at hy@@repeat{%
+  \bbl@@usehyphen{%
+    \discretionary{\bbl at hyphenchar}{\bbl at hyphenchar}{\bbl at hyphenchar}}}
+\def\bbl at hy@empty{\hskip\z at skip}
+\def\bbl at hy@@empty{\discretionary{}{}{}}
+\def\bbl at disc#1#2{\nobreak\discretionary{#2-}{}{#1}\bbl at allowhyphens}
+%
+% ------------------------------------------------------------------------------
+%
+% end of the code copied from babel files
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at disc@german#1#2{%
+  \nobreak\discretionary{#2-}{}{#1}}
+%    \end{macrocode}
+% \iffalse
+%</babelsh.def>
+%<*cal-util.def>
+% \fi
+% \clearpage
+% 
+% \subsection{cal-util.def}
+%    \begin{macrocode}
+%%%%%%%%%%%%% cal-util.def %%%%%%%%%%%%%%%%
+% Macros shared by hijrical and hebrewcal %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% the following is adapted from hebcal.sty in babel
+\def\@Remainder#1#2#3{%
+    #3 = #1%                   %  c = a
+    \divide #3 by #2%          %  c = a/b
+    \multiply #3 by -#2%       %  c = -b(a/b)
+    \advance #3 by #1}%        %  c = a - b(a/b)
+\newif\if at 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 at GregorianLeap
+\def\@CheckIfGregorianLeap#1{%
+   {%
+   \@CheckIfDivisible{#1}{4}%
+    \if at Divisible%
+        \@CheckIfDivisible{#1}{100}%
+        \if at Divisible%
+            \@CheckIfDivisible{#1}{400}%
+            \if at 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 at GregorianLeap%
+        \setcounter{tmpF}{-1}%
+      \else%
+        \setcounter{tmpF}{-2}%
+      \fi%
+ \fi%
+ \@ifundefined{c@#4}{\global\newcounter{#4}}{}%
+ \setcounter{#4}{\value{tmpA}+\value{tmpB}-\value{tmpC}+\value{tmpD}+\value{tmpE}+\value{tmpF}+#3}%
+}
+%    \end{macrocode}
+% \iffalse
+%</cal-util.def>
+%<*xgreek-fixes.def>
+% \fi
+% \clearpage
+% 
+% \subsection{xgreek-fixes.def}
+%    \begin{macrocode}
+% the following fixes are taken verbatim from xgreek.sty:
+% \message{Package `xgreek' version 3.0.1 by Apostolos Syropoulos}
+\global\lccode"0370="0371 \global\uccode"0370="0370
+\global\lccode"0371="0371 \global\uccode"0371="0370
+\global\lccode"0372="0373 \global\uccode"0372="0372
+\global\lccode"0373="0373 \global\uccode"0373="0372
+\global\lccode"0376="0377 \global\uccode"0376="0376
+\global\lccode"0377="0377 \global\uccode"0377="0376
+\global\lccode"03FD="037B \global\uccode"03FD="03FD
+\global\lccode"037B="037B \global\uccode"037B="03FD
+\global\lccode"03FE="037C \global\uccode"03FE="03FE
+\global\lccode"037C="037C \global\uccode"037C="03FE
+\global\lccode"03FF="037D \global\uccode"03FF="03FF
+\global\lccode"037D="037D \global\uccode"037D="03FF
+\global\lccode"0386="03AC \global\uccode"0386="0391
+\global\lccode"0388="03AD \global\uccode"0388="0395
+\global\lccode"0389="03AC \global\uccode"0389="0397
+\global\lccode"038A="03AF \global\uccode"038A="0399
+\global\lccode"038C="03CC \global\uccode"038C="039F
+\global\lccode"038E="03CD \global\uccode"038E="03A5
+\global\lccode"038F="03CE \global\uccode"038F="03A9
+\global\lccode"0390="0390 \global\uccode"0390="03AA
+\global\lccode"0391="03B1 \global\uccode"0391="0391
+\global\lccode"0392="03B2 \global\uccode"0392="0392
+\global\lccode"0393="03B3 \global\uccode"0393="0393
+\global\lccode"0394="03B4 \global\uccode"0394="0394
+\global\lccode"0395="03B5 \global\uccode"0395="0395
+\global\lccode"0396="03B6 \global\uccode"0396="0396
+\global\lccode"0397="03B7 \global\uccode"0397="0397
+\global\lccode"0398="03B8 \global\uccode"0398="0398
+\global\lccode"0399="03B9 \global\uccode"0399="0399
+\global\lccode"039A="03BA \global\uccode"039A="039A
+\global\lccode"039B="03BB \global\uccode"039B="039B
+\global\lccode"039C="03BC \global\uccode"039C="039C
+\global\lccode"039D="03BD \global\uccode"039D="039D
+\global\lccode"039E="03BE \global\uccode"039E="039E
+\global\lccode"039F="03BF \global\uccode"039F="039F
+\global\lccode"03A0="03C0 \global\uccode"03A0="03A0
+\global\lccode"03A1="03C1 \global\uccode"03A1="03A1
+\global\lccode"03A3="03C3 \global\uccode"03A3="03A3
+\global\lccode"03A4="03C4 \global\uccode"03A4="03A4
+\global\lccode"03A5="03C5 \global\uccode"03A5="03A5
+\global\lccode"03A6="03C6 \global\uccode"03A6="03A6
+\global\lccode"03A7="03C7 \global\uccode"03A7="03A7
+\global\lccode"03A8="03C8 \global\uccode"03A8="03A8
+\global\lccode"03A9="03C9 \global\uccode"03A9="03A9
+\global\lccode"03AA="03CA \global\uccode"03AA="03AA
+\global\lccode"03AB="03CB \global\uccode"03AB="03AB
+\global\lccode"03AC="03AC \global\uccode"03AC="0391
+\global\lccode"03AD="03AD \global\uccode"03AD="0395
+\global\lccode"03AE="03AE \global\uccode"03AE="0397
+\global\lccode"03AF="03AF \global\uccode"03AF="0399
+\global\lccode"03B0="03B0 \global\uccode"03B0="03AB
+\global\lccode"03B1="03B1 \global\uccode"03B1="0391
+\global\lccode"03B2="03B2 \global\uccode"03B2="0392
+\global\lccode"03B3="03B3 \global\uccode"03B3="0393
+\global\lccode"03B4="03B4 \global\uccode"03B4="0394
+\global\lccode"03B5="03B5 \global\uccode"03B5="0395
+\global\lccode"03B6="03B6 \global\uccode"03B6="0396
+\global\lccode"03B7="03B7 \global\uccode"03B7="0397
+\global\lccode"03B8="03B8 \global\uccode"03B8="0398
+\global\lccode"03B9="03B9 \global\uccode"03B9="0399
+\global\lccode"03BA="03BA \global\uccode"03BA="039A
+\global\lccode"03BB="03BB \global\uccode"03BB="039B
+\global\lccode"03BC="03BC \global\uccode"03BC="039C
+\global\lccode"03BD="03BD \global\uccode"03BD="039D
+\global\lccode"03BE="03BE \global\uccode"03BE="039E
+\global\lccode"03BF="03BF \global\uccode"03BF="039F
+\global\lccode"03C0="03C0 \global\uccode"03C0="03A0
+\global\lccode"03C1="03C1 \global\uccode"03C1="03A1
+\global\lccode"03C2="03C2 \global\uccode"03C2="03A3
+\global\lccode"03C3="03C3 \global\uccode"03C3="03A3
+\global\lccode"03C4="03C4 \global\uccode"03C4="03A4
+\global\lccode"03C5="03C5 \global\uccode"03C5="03A5
+\global\lccode"03C6="03C6 \global\uccode"03C6="03A6
+\global\lccode"03C7="03C7 \global\uccode"03C7="03A7
+\global\lccode"03C8="03C8 \global\uccode"03C8="03A8
+\global\lccode"03C9="03C9 \global\uccode"03C9="03A9
+\global\lccode"03CA="03CA \global\uccode"03CA="03AA
+\global\lccode"03CB="03CB \global\uccode"03CB="03AB
+\global\lccode"03CC="03CC \global\uccode"03CC="039F
+\global\lccode"03CD="03CD \global\uccode"03CD="03A5
+\global\lccode"03CE="03CE \global\uccode"03CE="03A9
+\global\lccode"03D0="03D0 \global\uccode"03D0="0392
+\global\lccode"03D1="03D1 \global\uccode"03D1="0398
+\global\lccode"03D2="03C5 \global\uccode"03D2="03A5
+\global\lccode"03D3="03CD \global\uccode"03D3="03A5
+\global\lccode"03D4="03CB \global\uccode"03D4="03AB
+\global\lccode"03D5="03C6 \global\uccode"03D5="03A6
+\global\lccode"03D6="03C0 \global\uccode"03D6="03A0
+\global\lccode"03DA="03DB \global\uccode"03DA="03DA
+\global\lccode"03DB="03DB \global\uccode"03DB="03DA
+\global\lccode"03DC="03DD \global\uccode"03DC="03DC
+\global\lccode"03DD="03DD \global\uccode"03DD="03DC
+\global\lccode"03DE="03DF \global\uccode"03DE="03DE
+\global\lccode"03DF="03DF \global\uccode"03DF="03DE
+\global\lccode"03E0="03E1 \global\uccode"03E0="03E0
+\global\lccode"03E1="03E1 \global\uccode"03E1="03E0
+\global\lccode"03F0="03BA \global\uccode"03F0="039A
+\global\lccode"03F1="03C1 \global\uccode"03F1="03A1
+\global\lccode"03F2="03F2 \global\uccode"03F2="03F9
+\global\lccode"03F9="03F2 \global\uccode"03F9="03F9
+\global\lccode"1F00="1F00 \global\uccode"1F00="0391
+\global\lccode"1F01="1F01 \global\uccode"1F01="0391
+\global\lccode"1F02="1F02 \global\uccode"1F02="0391
+\global\lccode"1F03="1F03 \global\uccode"1F03="0391
+\global\lccode"1F04="1F04 \global\uccode"1F04="0391
+\global\lccode"1F05="1F05 \global\uccode"1F05="0391
+\global\lccode"1F06="1F06 \global\uccode"1F06="0391
+\global\lccode"1F07="1F07 \global\uccode"1F07="0391
+\global\lccode"1F08="1F00 \global\uccode"1F08="0391
+\global\lccode"1F09="1F01 \global\uccode"1F09="0391
+\global\lccode"1F0A="1F02 \global\uccode"1F0A="0391
+\global\lccode"1F0B="1F03 \global\uccode"1F0B="0391
+\global\lccode"1F0C="1F04 \global\uccode"1F0C="0391
+\global\lccode"1F0D="1F05 \global\uccode"1F0D="0391
+\global\lccode"1F0E="1F06 \global\uccode"1F0E="0391
+\global\lccode"1F0F="1F07 \global\uccode"1F0F="0391
+\global\lccode"1F10="1F10 \global\uccode"1F10="0395
+\global\lccode"1F11="1F11 \global\uccode"1F11="0395
+\global\lccode"1F12="1F12 \global\uccode"1F12="0395
+\global\lccode"1F13="1F13 \global\uccode"1F13="0395
+\global\lccode"1F14="1F14 \global\uccode"1F14="0395
+\global\lccode"1F15="1F15 \global\uccode"1F15="0395
+\global\lccode"1F18="1F10 \global\uccode"1F18="0395
+\global\lccode"1F19="1F11 \global\uccode"1F19="0395
+\global\lccode"1F1A="1F12 \global\uccode"1F1A="0395
+\global\lccode"1F1B="1F13 \global\uccode"1F1B="0395
+\global\lccode"1F1C="1F14 \global\uccode"1F1C="0395
+\global\lccode"1F1D="1F15 \global\uccode"1F1D="0395
+\global\lccode"1F20="1F20 \global\uccode"1F20="0397
+\global\lccode"1F21="1F21 \global\uccode"1F21="0397
+\global\lccode"1F22="1F22 \global\uccode"1F22="0397
+\global\lccode"1F23="1F23 \global\uccode"1F23="0397
+\global\lccode"1F24="1F24 \global\uccode"1F24="0397
+\global\lccode"1F25="1F25 \global\uccode"1F25="0397
+\global\lccode"1F26="1F26 \global\uccode"1F26="0397
+\global\lccode"1F27="1F27 \global\uccode"1F27="0397
+\global\lccode"1F28="1F20 \global\uccode"1F28="0397
+\global\lccode"1F29="1F21 \global\uccode"1F29="0397
+\global\lccode"1F2A="1F22 \global\uccode"1F2A="0397
+\global\lccode"1F2B="1F23 \global\uccode"1F2B="0397
+\global\lccode"1F2C="1F24 \global\uccode"1F2C="0397
+\global\lccode"1F2D="1F25 \global\uccode"1F2D="0397
+\global\lccode"1F2E="1F26 \global\uccode"1F2E="0397
+\global\lccode"1F2F="1F27 \global\uccode"1F2F="0397
+\global\lccode"1F30="1F30 \global\uccode"1F30="0399
+\global\lccode"1F31="1F31 \global\uccode"1F31="0399
+\global\lccode"1F32="1F32 \global\uccode"1F32="0399
+\global\lccode"1F33="1F33 \global\uccode"1F33="0399
+\global\lccode"1F34="1F34 \global\uccode"1F34="0399
+\global\lccode"1F35="1F35 \global\uccode"1F35="0399
+\global\lccode"1F36="1F36 \global\uccode"1F36="0399
+\global\lccode"1F37="1F37 \global\uccode"1F37="0399
+\global\lccode"1F38="1F30 \global\uccode"1F38="0399
+\global\lccode"1F39="1F31 \global\uccode"1F39="0399
+\global\lccode"1F3A="1F32 \global\uccode"1F3A="0399
+\global\lccode"1F3B="1F33 \global\uccode"1F3B="0399
+\global\lccode"1F3C="1F34 \global\uccode"1F3C="0399
+\global\lccode"1F3D="1F35 \global\uccode"1F3D="0399
+\global\lccode"1F3E="1F36 \global\uccode"1F3E="0399
+\global\lccode"1F3F="1F37 \global\uccode"1F3F="0399
+\global\lccode"1F40="1F40 \global\uccode"1F40="039F
+\global\lccode"1F41="1F41 \global\uccode"1F41="039F
+\global\lccode"1F42="1F42 \global\uccode"1F42="039F
+\global\lccode"1F43="1F43 \global\uccode"1F43="039F
+\global\lccode"1F44="1F44 \global\uccode"1F44="039F
+\global\lccode"1F45="1F45 \global\uccode"1F45="039F
+\global\lccode"1F48="1F40 \global\uccode"1F48="039F
+\global\lccode"1F49="1F41 \global\uccode"1F49="039F
+\global\lccode"1F4A="1F42 \global\uccode"1F4A="039F
+\global\lccode"1F4B="1F43 \global\uccode"1F4B="039F
+\global\lccode"1F4C="1F44 \global\uccode"1F4C="039F
+\global\lccode"1F4D="1F45 \global\uccode"1F4D="039F
+\global\lccode"1F50="1F50 \global\uccode"1F50="03A5
+\global\lccode"1F51="1F51 \global\uccode"1F51="03A5
+\global\lccode"1F52="1F52 \global\uccode"1F52="03A5
+\global\lccode"1F53="1F53 \global\uccode"1F53="03A5
+\global\lccode"1F54="1F54 \global\uccode"1F54="03A5
+\global\lccode"1F55="1F55 \global\uccode"1F55="03A5
+\global\lccode"1F56="1F56 \global\uccode"1F56="03A5
+\global\lccode"1F57="1F57 \global\uccode"1F57="03A5
+\global\lccode"1F59="1F51 \global\uccode"1F59="03A5
+\global\lccode"1F5B="1F53 \global\uccode"1F5B="03A5
+\global\lccode"1F5D="1F55 \global\uccode"1F5D="03A5
+\global\lccode"1F5F="1F57 \global\uccode"1F5F="03A5
+\global\lccode"1F60="1F60 \global\uccode"1F60="03A9
+\global\lccode"1F61="1F61 \global\uccode"1F61="03A9
+\global\lccode"1F62="1F62 \global\uccode"1F62="03A9
+\global\lccode"1F63="1F63 \global\uccode"1F63="03A9
+\global\lccode"1F64="1F64 \global\uccode"1F64="03A9
+\global\lccode"1F65="1F65 \global\uccode"1F65="03A9
+\global\lccode"1F66="1F66 \global\uccode"1F66="03A9
+\global\lccode"1F67="1F67 \global\uccode"1F67="03A9
+\global\lccode"1F68="1F60 \global\uccode"1F68="03A9
+\global\lccode"1F69="1F61 \global\uccode"1F69="03A9
+\global\lccode"1F6A="1F62 \global\uccode"1F6A="03A9
+\global\lccode"1F6B="1F63 \global\uccode"1F6B="03A9
+\global\lccode"1F6C="1F64 \global\uccode"1F6C="03A9
+\global\lccode"1F6D="1F65 \global\uccode"1F6D="03A9
+\global\lccode"1F6E="1F66 \global\uccode"1F6E="03A9
+\global\lccode"1F6F="1F67 \global\uccode"1F6F="03A9
+\global\lccode"1F70="1F70 \global\uccode"1F70="0391
+\global\lccode"1F71="1F71 \global\uccode"1F71="0391
+\global\lccode"1F72="1F72 \global\uccode"1F72="0395
+\global\lccode"1F73="1F73 \global\uccode"1F73="0395
+\global\lccode"1F74="1F74 \global\uccode"1F74="0397
+\global\lccode"1F75="1F75 \global\uccode"1F75="0397
+\global\lccode"1F76="1F76 \global\uccode"1F76="0399
+\global\lccode"1F77="1F77 \global\uccode"1F77="0399
+\global\lccode"1F78="1F78 \global\uccode"1F78="039F
+\global\lccode"1F79="1F79 \global\uccode"1F79="039F
+\global\lccode"1F7A="1F7A \global\uccode"1F7A="03A5
+\global\lccode"1F7B="1F7B \global\uccode"1F7B="03A5
+\global\lccode"1F7C="1F7C \global\uccode"1F7C="03A9
+\global\lccode"1F7D="1F7D \global\uccode"1F7D="03A9
+\global\lccode"1F80="1F80 \global\uccode"1F80="1FBC
+\global\lccode"1F81="1F81 \global\uccode"1F81="1FBC
+\global\lccode"1F82="1F82 \global\uccode"1F82="1FBC
+\global\lccode"1F83="1F83 \global\uccode"1F83="1FBC
+\global\lccode"1F84="1F84 \global\uccode"1F84="1FBC
+\global\lccode"1F85="1F85 \global\uccode"1F85="1FBC
+\global\lccode"1F86="1F86 \global\uccode"1F86="1FBC
+\global\lccode"1F87="1F87 \global\uccode"1F87="1FBC
+\global\lccode"1F88="1F80 \global\uccode"1F88="1FBC
+\global\lccode"1F89="1F81 \global\uccode"1F89="1FBC
+\global\lccode"1F8A="1F82 \global\uccode"1F8A="1FBC
+\global\lccode"1F8B="1F83 \global\uccode"1F8B="1FBC
+\global\lccode"1F8C="1F84 \global\uccode"1F8C="1FBC
+\global\lccode"1F8D="1F85 \global\uccode"1F8D="1FBC
+\global\lccode"1F8E="1F86 \global\uccode"1F8E="1FBC
+\global\lccode"1F8F="1F87 \global\uccode"1F8F="1FBC
+\global\lccode"1F90="1F90 \global\uccode"1F90="1FCC
+\global\lccode"1F91="1F91 \global\uccode"1F91="1FCC
+\global\lccode"1F92="1F92 \global\uccode"1F92="1FCC
+\global\lccode"1F93="1F93 \global\uccode"1F93="1FCC
+\global\lccode"1F94="1F94 \global\uccode"1F94="1FCC
+\global\lccode"1F95="1F95 \global\uccode"1F95="1FCC
+\global\lccode"1F96="1F96 \global\uccode"1F96="1FCC
+\global\lccode"1F97="1F97 \global\uccode"1F97="1FCC
+\global\lccode"1F98="1F90 \global\uccode"1F98="1FCC
+\global\lccode"1F99="1F91 \global\uccode"1F99="1FCC
+\global\lccode"1F9A="1F92 \global\uccode"1F9A="1FCC
+\global\lccode"1F9B="1F93 \global\uccode"1F9B="1FCC
+\global\lccode"1F9C="1F94 \global\uccode"1F9C="1FCC
+\global\lccode"1F9D="1F95 \global\uccode"1F9D="1FCC
+\global\lccode"1F9E="1F96 \global\uccode"1F9E="1FCC
+\global\lccode"1F9F="1F97 \global\uccode"1F9F="1FCC
+\global\lccode"1FA0="1FA0 \global\uccode"1FA0="1FFC
+\global\lccode"1FA1="1FA1 \global\uccode"1FA1="1FFC
+\global\lccode"1FA2="1FA2 \global\uccode"1FA2="1FFC
+\global\lccode"1FA3="1FA3 \global\uccode"1FA3="1FFC
+\global\lccode"1FA4="1FA4 \global\uccode"1FA4="1FFC
+\global\lccode"1FA5="1FA5 \global\uccode"1FA5="1FFC
+\global\lccode"1FA6="1FA6 \global\uccode"1FA6="1FFC
+\global\lccode"1FA7="1FA7 \global\uccode"1FA7="1FFC
+\global\lccode"1FA8="1FA0 \global\uccode"1FA8="1FFC
+\global\lccode"1FA9="1FA1 \global\uccode"1FA9="1FFC
+\global\lccode"1FAA="1FA2 \global\uccode"1FAA="1FFC
+\global\lccode"1FAB="1FA3 \global\uccode"1FAB="1FFC
+\global\lccode"1FAC="1FA4 \global\uccode"1FAC="1FFC
+\global\lccode"1FAD="1FA5 \global\uccode"1FAD="1FFC
+\global\lccode"1FAE="1FA6 \global\uccode"1FAE="1FFC
+\global\lccode"1FAF="1FA7 \global\uccode"1FAF="1FFC
+\global\lccode"1FB0="1FB0 \global\uccode"1FB0="1FB8
+\global\lccode"1FB1="1FB1 \global\uccode"1FB1="1FB9
+\global\lccode"1FB2="1FB2 \global\uccode"1FB2="1FBC
+\global\lccode"1FB3="1FB3 \global\uccode"1FB3="1FBC
+\global\lccode"1FB4="1FB4 \global\uccode"1FB4="1FBC
+\global\lccode"1FB6="1FB6 \global\uccode"1FB6="0391
+\global\lccode"1FB7="1FB7 \global\uccode"1FB7="1FBC
+\global\lccode"1FB8="1FB0 \global\uccode"1FB8="1FB8
+\global\lccode"1FB9="1FB1 \global\uccode"1FB9="1FB9
+\global\lccode"1FBA="1F70 \global\uccode"1FBA="0391
+\global\lccode"1FBB="1F71 \global\uccode"1FBB="0391
+\global\lccode"1FBC="1FB3 \global\uccode"1FBC="1FBC
+\global\lccode"1FBD="1FBD \global\uccode"1FBD="1FBD
+\global\lccode"1FC2="1FC2 \global\uccode"1FC2="1FCC
+\global\lccode"1FC3="1FC3 \global\uccode"1FC3="1FCC
+\global\lccode"1FC4="1FC4 \global\uccode"1FC4="1FCC
+\global\lccode"1FC6="1FC6 \global\uccode"1FC6="0397
+\global\lccode"1FC7="1FC7 \global\uccode"1FC7="1FCC
+\global\lccode"1FC8="1F72 \global\uccode"1FC8="0395
+\global\lccode"1FC9="1F73 \global\uccode"1FC9="0395
+\global\lccode"1FCA="1F74 \global\uccode"1FCA="0397
+\global\lccode"1FCB="1F75 \global\uccode"1FCB="0397
+\global\lccode"1FCC="1FC3 \global\uccode"1FCC="1FCC
+\global\lccode"1FD0="1FD0 \global\uccode"1FD0="1FD8
+\global\lccode"1FD1="1FD1 \global\uccode"1FD1="1FD9
+\global\lccode"1FD2="1FD2 \global\uccode"1FD2="03AA
+\global\lccode"1FD3="1FD3 \global\uccode"1FD3="03AA
+\global\lccode"1FD6="1FD6 \global\uccode"1FD6="0399
+\global\lccode"1FD7="1FD7 \global\uccode"1FD7="03AA
+\global\lccode"1FD8="1FD0 \global\uccode"1FD8="1FD8
+\global\lccode"1FD9="1FD1 \global\uccode"1FD9="1FD9
+\global\lccode"1FDA="1F76 \global\uccode"1FDA="0399
+\global\lccode"1FDB="1F77 \global\uccode"1FDB="0399
+\global\lccode"1FE0="1FE0 \global\uccode"1FE0="1FE8
+\global\lccode"1FE1="1FE1 \global\uccode"1FE1="1FE9
+\global\lccode"1FE2="1FE2 \global\uccode"1FE2="03AB
+\global\lccode"1FE3="1FE3 \global\uccode"1FE3="03AB
+\global\lccode"1FE4="1FE4 \global\uccode"1FE4="03A1
+\global\lccode"1FE5="1FE5 \global\uccode"1FE5="03A1
+\global\lccode"1FE6="1FE6 \global\uccode"1FE6="03A5
+\global\lccode"1FE7="1FE7 \global\uccode"1FE7="03AB
+\global\lccode"1FE8="1FE0 \global\uccode"1FE8="1FE8
+\global\lccode"1FE9="1FE1 \global\uccode"1FE9="1FE9
+\global\lccode"1FEA="1F7A \global\uccode"1FEA="03A5
+\global\lccode"1FEB="1F7B \global\uccode"1FEB="03A5
+\global\lccode"1FEC="1FE5 \global\uccode"1FEC="1FEC
+\global\lccode"1FF2="1FF2 \global\uccode"1FF2="1FFC
+\global\lccode"1FF3="1FF3 \global\uccode"1FF3="1FFC
+\global\lccode"1FF4="1FF4 \global\uccode"1FF4="1FFC
+\global\lccode"1FF6="1FF6 \global\uccode"1FF6="03A9
+\global\lccode"1FF7="1FF7 \global\uccode"1FF7="1FFC
+\global\lccode"1FF8="1F78 \global\uccode"1FF8="039F
+\global\lccode"1FF9="1F79 \global\uccode"1FF9="039F
+\global\lccode"1FFA="1F7C \global\uccode"1FFA="03A9
+\global\lccode"1FFB="1F7D \global\uccode"1FFB="03A9
+\global\lccode"1FFC="1FF3 \global\uccode"1FFC="1FFC
+%    \end{macrocode}
+% \iffalse
+%</xgreek-fixes.def>
 %<*gloss-acadien.ldf>
 % \fi
 % \clearpage
@@ -2697,7 +8367,7 @@
 }
 
 \def\noextras at afrikaans{%
-  \noafrikaans at shorthands%
+  \ifafrikaans at babelshorthands\noafrikaans at shorthands\fi%
 }
 
 \def\blockextras at afrikaans{%
@@ -3152,12 +8822,6 @@
 % \subsection{gloss-arabic.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-arabic.ldf}[polyglossia: module for arabic]
-\ifluatex
-  \xpg at 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 @@
 \setlanguagealias*[locale=default]{arabic}{apd}
 \setlanguagealias*[locale=mashriq]{arabic}{ar-PS}
 
+\define at boolkey{arabic}[arabic@]{abjadalph}[true]{}
+
 \newif\ifeastern at numerals
 \def\tmp at mashriq{mashriq}
 \def\tmp at maghrib{maghrib}
@@ -3326,6 +8992,19 @@
 \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 at abjad@alph{\number#1}}
+
+% This is a poor man's Arabic alphanumeric. It just uses the alphabet and
+% thus ends at 28.
+\def\arabic at abjad@alph#1{\ifcase#1%
+   \or ا\or ب\or\abjad at 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 at ill@value{#1}{arabic at abjad@alph}\fi%
+}
+
+
 \def\abjadmaghribi#1{%
 \ifnum#1>1999\xpg at ill@value{#1}{abjad}%
 \else
@@ -3360,8 +9039,13 @@
   \ifnum#1=\z@\fi\abj at maghribi@num at iii}
 
 \def\arabic at numbers{%
+ \ifarabic at abjadalph
+   \let\@alph\abjadalph%
+   \let\@Alph\abjadalph%
+ \else
    \let\@alph\abjad%
    \let\@Alph\abjad%
+ \fi
 }
 
 \def\noarabic at numbers{%
@@ -3994,7 +9678,7 @@
   \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 at shorthand{belarusian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -4179,7 +9863,7 @@
 
 \def\noextras at belarusian{%
    \ifcyrillic at numerals\nobelarusian at numbers\fi%
-   \nobelarusian at shorthands%
+   \ifbelarusian at babelshorthands\nobelarusian at shorthands\fi%
 }
 
 \def\blockextras at belarusian{%
@@ -4205,13 +9889,6 @@
 
 \ProvidesFile{gloss-bengali.ldf}[polyglossia: module for bengali]
 
-\ifluatex
-  \xpg at 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 @@
     \csname normal at char\string"\endcsname l%
   \else
     \leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
-    \setbox0\hbox{l}\setbox1\hbox{l\/}%
+    \setbox0\hbox{l}%
     \xpg at if@char at 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 at raiseddot%
       \kern\rightllkern\hbox{l}}\allowhyphens
@@ -4819,19 +10501,24 @@
     \csname normal at char\string"\endcsname L%
   \else
     \leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
-    \setbox0\hbox{L}\setbox1\hbox{L\/}%
+    \setbox0\hbox{L}%
     \xpg at if@char at 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 at raiseddot%
       \kern\rightllkern\hbox{L}}\allowhyphens
@@ -4889,7 +10576,7 @@
     \space de~\number\year}}
 
 \def\noextras at catalan{%
-   \nocatalan at shorthands%
+   \ifcatalan at babelshorthands\nocatalan at shorthands\fi%
 }
 
 \def\blockextras at catalan{%
@@ -5184,7 +10871,7 @@
 }
 
 \def\noextras at croatian{%
-  \nocroatian at shorthands%
+  \ifcroatian at babelshorthands\nocroatian at shorthands\fi%
 }
 
 \def\blockextras at croatian{%
@@ -5313,7 +11000,7 @@
       \chardef\czech at boundary=4095 %
       \def\newXeTeXintercharclass{%
         \e at alloc\XeTeXcharclass\chardef
-              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}
+              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}%
     \else
       \chardef\czech at boundary=255
     \fi
@@ -5342,6 +11029,24 @@
 
 % 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 at nointerchartoks{\let\czech at interchartoks\czech at PreCSpreposition}%
+    \def\czech at PreCSpreposition{%
+       \def\next{}%
+       \ifnum\catcode`\ =10 % nothing will be done in verbatim
+       \ifmmode % nothing in math
+       \else
+          \let\czech at interchartoks\czech at nointerchartoks
+          \let\next\czech at ExamineCSpreposition
+       \fi\fi
+       \next%
+    }%
+    \def\czech at ExamineCSpreposition #1{#1\futurelet\next\czech at ProcessCSpreposition}%
+    \def\czech at ProcessCSpreposition{\ifx\next\czech at XeTeXspace\nobreak\fi}%
+    \futurelet\czech at XeTeXspace{ }\czech at nointerchartoks
+\fi
+
 \def\czech at vlna{%
     \ifluatex
        \preventsingleon
@@ -5368,21 +11073,8 @@
         \XeTeXcharclass `\a \czech at nonsyllabicpreposition
         \XeTeXcharclass `\I \czech at nonsyllabicpreposition
         \XeTeXcharclass `\i \czech at nonsyllabicpreposition
-        \XeTeXinterchartoks \czech at boundary \czech at nonsyllabicpreposition {\czech at interchartoks}
-        \XeTeXinterchartoks \czech at openpunctuation \czech at nonsyllabicpreposition {\czech at interchartoks}
-        \def\czech at nointerchartoks{\let\czech at interchartoks\czech at PreCSpreposition}
-        \def\czech at PreCSpreposition{\def\next{}%
-           \ifnum\catcode`\ =10 % nothing will be done in verbatim
-           \ifmmode % nothing in math
-           \else
-              \let\czech at interchartoks\czech at nointerchartoks
-              \let\next\czech at ExamineCSpreposition
-           \fi \fi
-          \next%
-        }
-        \def\czech at ExamineCSpreposition ##1{##1\futurelet\next\czech at ProcessCSpreposition}
-        \def\czech at ProcessCSpreposition{\ifx\next\czech at XeTeXspace\nobreak\fi}
-        \futurelet\czech at XeTeXspace{ }\czech at nointerchartoks
+        \XeTeXinterchartoks \czech at boundary \czech at nonsyllabicpreposition {\czech at interchartoks}%
+        \XeTeXinterchartoks \czech at openpunctuation \czech at nonsyllabicpreposition {\czech at interchartoks}%
     \fi
 }
 
@@ -5448,7 +11140,7 @@
 }
 
 \def\noextras at czech{%
-  \noczech at shorthands%
+  \ifczech at babelshorthands\noczech at shorthands\fi%
   \noczech at hyphens%
   \noczech at vlna%
   \ifxetex\XeTeXinterchartokenstate=0\fi%
@@ -5526,11 +11218,12 @@
   \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 @@
 % \subsection{gloss-divehi.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-divehi.ldf}[polyglossia: module for divehi]
-\ifluatex
-  \xpg at 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 @@
 }
 
 \def\noextras at dutch{%
-  \nodutch at shorthands%
+  \ifdutch at babelshorthands\nodutch at shorthands\fi%
 }
 
 \def\blockextras at dutch{%
@@ -6721,7 +12409,7 @@
     \space\number\year}}
 
 \def\noextras at finnish{%
-  \nofinnish at shorthands%
+  \iffinnish at babelshorthands\nofinnish at shorthands\fi%
 }
 
 \def\blockextras at finnish{%
@@ -7604,7 +13292,7 @@
   \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 at shorthand{georgian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -7749,7 +13437,7 @@
 
 \def\noextras at georgian{%
    \ifgeorgian at numerals\nogeorgian at numbers\fi%
-   \nogeorgian at shorthands%
+   \ifgeorgian at babelshorthands\nogeorgian at shorthands\fi%
 }
 
 \def\blockextras at georgian{%
@@ -7970,14 +13658,14 @@
   \declare at shorthand{german}{"R}{\textormath{\bbl at disc@german R{RR}}{R}}%
   \declare at shorthand{german}{"t}{\textormath{\bbl at disc@german t{tt}}{t}}%
   \declare at shorthand{german}{"T}{\textormath{\bbl at disc@german T{TT}}{T}}%
-  \declare at shorthand{german}{"f}{\textormath{\bbl at discff}{f}}%
+  \declare at shorthand{german}{"f}{\texorpdfstring{\textormath{\bbl at discff}{f}}{f}}%
   \def\bbl at discff{\penalty\@M
-    \afterassignment\bbl at insertff \let\bbl at nextff= }%
+    \afterassignment\bbl at insertff \cslet{bbl at nextff}{ }}%
   \def\bbl at insertff{%
     \if f\bbl at nextff
       \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
     {\relax\discretionary{ff-}{f}{ff}\allowhyphens}{f\bbl at nextff}}%
-  \let\bbl at nextff=f%
+  \cslet{bbl at nextff}{f}%
   \declare at shorthand{german}{"-}{\nobreak\-\nobreak\hskip\z at skip}%
   \declare at shorthand{german}{"|}{\textormath{\penalty\@M\discretionary{-}{}{\kern.03em}}{}}%
   \declare at shorthand{german}{""}{\hskip\z at skip}%
@@ -8082,15 +13770,15 @@
 }
 
 \def\noextras at german{%
-  \nogerman at shorthands%
+  \ifgerman at babelshorthands\nogerman at shorthands\fi%
 }
 
 \def\blockextras at german{%
-  \ifgerman at babelshorthands\german at shorthands\fi
+  \ifgerman at babelshorthands\german at shorthands\fi%
 }
 
 \def\inlineextras at german{%
-  \ifgerman at babelshorthands\german at shorthands\fi
+  \ifgerman at babelshorthands\german at shorthands\fi%
 }
 
 %    \end{macrocode}
@@ -8579,12 +14267,7 @@
 % \subsection{gloss-hebrew.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-hebrew.ldf}[polyglossia: module for hebrew]
-\ifluatex
-  \xpg at 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 @@
    \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 at hebrew@DigitsDotDashInterCharToks{\ifbool{@nonlatin}{\char"200E }{}}
+  \let\xpg at orig@DigitsDotDashInterCharToks\DigitsDotDashInterCharToks%
 \fi
 
 \def\hebrew at ltr@numbers{%
     \ifxetex
-      \XeTeXinterchartoks \bidi at sepmark@charclass  \bidi at digits@charclass = {\xpg at 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 at ltr@numbers{%
     \ifxetex
-      % This is bidi's original intervention
-      \XeTeXinterchartoks \bidi at sepmark@charclass  \bidi at digits@charclass = {\DigitsDotDashInterCharToks}%
+      % Restore bidi's \DigitsDotDashInterCharToks
+      \let\DigitsDotDashInterCharToks\xpg at orig@DigitsDotDashInterCharToks%
     \fi%
 }
 
@@ -8852,7 +14535,7 @@
      \def\listfigurename{चित्रों की सूची}%
      \def\listtablename{तालिकाओं की सूची}%
      \def\pagename{पृष्ठ}%
-     \def\partname{खणड}%
+     \def\partname{खण्ड}%
      \def\prefacename{प्रस्तावना}% प्राक्कथन
      \def\refname{हवाले}%
      \def\tablename{तालिका}%
@@ -9572,21 +15255,21 @@
 
 
 \def\noextras at italian{%
-   \lccode\string"2019=\z@
-   \noitalian at shorthands
-   \xpgit at savedvalues
+   \lccode\string"2019=\z@%
+   \ifitalian at babelshorthands\noitalian at shorthands\fi%
+   \xpgit at savedvalues%
 }
 
 \def\blockextras at italian{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifitalian at babelshorthands\italian at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifitalian at babelshorthands\italian at shorthands\fi%
 }
 
 \def\inlineextras at italian{%
-   \lccode\string"2019=\string"2019
-   \ifitalian at babelshorthands\italian at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifitalian at babelshorthands\italian at shorthands\fi%
 }
 %%% CHANGES END %%%
 %    \end{macrocode}
@@ -9880,12 +15563,7 @@
 %
 % This work consists of the file gloss-kannada.ldf
 \ProvidesFile{gloss-kannada.ldf}[polyglossia: module for kannada]
-\ifluatex
-  \xpg at 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 @@
 % \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 at 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 @@
 \define at key{kurdish}{locale}[default]{%
   \def\@kurdish at locale{#1}}
 
-
 %TODO add option for CALENDAR
 
 % Register default options
@@ -10859,9 +16538,9 @@
 }%
 
 \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 @@
 }
 
 \def\captionskurdish at sorani@arabic{%
-  \def\prefacename{\@ensure at RTL{پێشه‌كی}}%
-  \def\refname{\@ensure at RTL{سه‌رچاوه‌کان}}%
-  \def\abstractname{\@ensure at RTL{پوخته‌}}%
-  \def\bibname{\@ensure at RTL{کتێبنامه‌}}%
-  \def\chaptername{\@ensure at RTL{به‌ندی}}%
+  \def\prefacename{\@ensure at RTL{پێشەكی}}%
+  \def\refname{\@ensure at RTL{سەرچاوەکان}}%
+  \def\abstractname{\@ensure at RTL{پوختە}}%
+  \def\bibname{\@ensure at RTL{کتێبنامە}}%
+  \def\chaptername{\@ensure at RTL{بەندی}}%
   \def\appendixname{\@ensure at RTL{پاشکۆ}}%
-  \def\contentsname{\@ensure at RTL{نێوه‌ڕۆک}}%
-  \def\listfigurename{\@ensure at RTL{لیستی وێنه‌کان}}%
-  \def\listtablename{\@ensure at RTL{لیستی خشته‌کان}}%
+  \def\contentsname{\@ensure at RTL{نێوەڕۆک}}%
+  \def\listfigurename{\@ensure at RTL{لیستی وێنەکان}}%
+  \def\listtablename{\@ensure at RTL{لیستی خشتەکان}}%
   \def\indexname{\@ensure at RTL{پێنوێن}}%
-  \def\figurename{\@ensure at RTL{وێنه‌}}%
-  \def\tablename{\@ensure at RTL{خشتە}}%
-  \def\partname{\@ensure at RTL{به‌شی}}%
+  \def\figurename{\@ensure at RTL{وێنەی}}%
+  \def\tablename{\@ensure at RTL{خشتەی}}%
+  \def\partname{\@ensure at RTL{بەشی}}%
   \def\enclname{\@ensure at RTL{هاوپێچ}}%
-  \def\ccname{\@ensure at RTL{روونووس}}%
+  \def\ccname{\@ensure at RTL{ڕوونووس}}%
   \def\headtoname{\@ensure at RTL{بۆ}}%
-  \def\pagename{\@ensure at RTL{لاپه‌ڕه‌}}%
-  \def\seename{\@ensure at RTL{چاو لێکه‌ن}}%
-  \def\alsoname{\@ensure at RTL{هه‌روه‌ها چاو لێکه‌ن}}%
+  \def\pagename{\@ensure at RTL{لاپەڕە}}%
+  \def\seename{\@ensure at RTL{چاو لێکەن}}%
+  \def\alsoname{\@ensure at RTL{هەروەها چاو لێکەن}}%
   \def\proofname{\@ensure at RTL{سەلماندن}}%
-  \def\glossaryname{\@ensure at RTL{فه‌رهه‌نگۆک}}%
+  \def\glossaryname{\@ensure at RTL{فەرهەنگۆک}}%
 }
 
 \def\captionskurdish at sorani@latin{%
@@ -10901,17 +16580,17 @@
   \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 @@
 
 \def\captionskurdish at 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,7 +16616,7 @@
   \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ê}%
 }
@@ -10944,7 +16623,7 @@
 
 \def\captionskurdish at kurmanji@arabic{%
   \def\prefacename{\@ensure at RTL{پێشگۆتن}}%
-  \def\refname{\@ensure at RTL{پرتووکێن بژارتی}}%
+  \def\refname{\@ensure at RTL{ژێدەر}}%
   \def\abstractname{\@ensure at RTL{کورتەبیر}}%
   \def\bibname{\@ensure at RTL{چاڤکانییا پرتووکان}}%
   \def\chaptername{\@ensure at RTL{سەرێ}}%
@@ -10976,17 +16655,17 @@
 
 \def\datekurdish at 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 @@
 
 \def\datekurdish at 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 @@
   \def\decembername{Çileya Pêşîn}%
 }
 
+\def\kurdishmonthkurmanji#1{\ifcase#1%
+  چلەیا پاشین \or شبات \or ئادار \or نیسان \or گولان \or حەزیران \or تیرمەهـ \or تەباخ \or ئیلۆن \or چریا پێشین \or چریا پاشین \or چلەیا پێشین\fi}
+
 \def\datekurdish at kurmanji@arabic{%
-   \datekurdish at sorani@arabic% FIXME: correct?
+   \def\today{\@ensure at RTL{\kurdishnumber\day\space\kurdishmonthkurmanji{\month}\space\kurdishnumber\year}}%
 }
 
 % TODO: babel-kurmanji has these "alternative" month names
@@ -11193,12 +16875,7 @@
 % \subsection{gloss-lao.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-lao.ldf}[polyglossia: module for Lao]
-\ifluatex
-  \xpg at 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 @@
 % 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 at write \@auxout { } { \shorthandoff {=} } % for the aux file
 
@@ -12932,12 +18609,7 @@
 % \subsection{gloss-malayalam.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-malayalam.ldf}[polyglossia: module for malayalam]
-\ifluatex
-  \xpg at 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 @@
 % TODO implement Hindu calendar (not used in day-to-day practice)
 
 \ProvidesFile{gloss-marathi.ldf}[polyglossia: module for marathi]
-\ifluatex
-  \xpg at 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 @@
    \def\appendixname{परिशिष्ट}%
    \def\contentsname{अनुक्रमणिका}%
    \def\listfigurename{आकृत्यांची सूची}%
-   \def\listtablename{कोष्टक सूची}%
+   \def\listtablename{कोष्टकसूची}%
    \def\indexname{सूची}%
    \def\figurename{आकृती}%
    \def\tablename{कोष्टक}%
@@ -13075,10 +18742,10 @@
    \def\seename{पाहा}%
    \def\alsoname{हेदेखील पाहा}%
    \def\enclname{समाविष्ट}%
-   \def\ccname{सी.सी.}%
+   \def\ccname{प्रत}%
    \def\headtoname{प्रति}%
    \def\proofname{सिद्धता}%
-   \def\glossaryname{संक्षेपसूची}%
+   \def\glossaryname{संज्ञांची सूची}%
    \def\authorsand{आणि}%
 }
 
@@ -13104,23 +18771,23 @@
    }%
 }
 
-\def\devanagari at akshar#1{\ifcase#1\or अ\or आ\or इ\or ई\or उ\or ऊ\or ए\or ऐ\or ओ\or औ\or अं\or अः\else\@ctrerr\fi}
+\def\devanagari at 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 at 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 at 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 @@
   \let\@Roman\xpg at save@Roman
 }
 
-\def\blockextras at marathi{%
-  \let\xpg at orig@baselinestretch\baselinestrech%
-  \renewcommand{\baselinestretch}{1.2}%
-  \renewcommand{\labelitemii}{$\rightarrow$}%
-}
-
-\let\xpg at orig@labelitemii\labelitemii
-
-\def\noextras at marathi{%
-  \let\baselinestrech\xpg at orig@baselinestretch%
-  \let\labelitemii\xpg at orig@labelitemii%
-}
-
 %    \end{macrocode}
 % \iffalse
 %</gloss-marathi.ldf>
@@ -13309,7 +18963,7 @@
   \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 at shorthand{mongolian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -13423,7 +19077,7 @@
 
 \def\noextras at mongolian{%
    \ifcyrillic at numerals\nomongolian at numbers\fi%
-   \nomongolian at shorthands%
+   \ifmongolian at babelshorthands\nomongolian at shorthands\fi%
 }
 
 \def\blockextras at mongolian{%
@@ -13925,20 +19579,20 @@
     \finalhyphendemerits=\the\finalhyphendemerits}
 }
 \def\noextras at occitan{%
-   \lccode\string"2019=\z@
-   \nooccitan at shorthands
-   \xpgoc at savedvalues
+   \lccode\string"2019=\z@%
+   \ifoccitan at babelshorthands\nooccitan at shorthands\fi%
+   \xpgoc at savedvalues%
 }
 \def\blockextras at occitan{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifoccitan at babelshorthands\occitan at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifoccitan at babelshorthands\occitan at shorthands\fi%
 }
 
 \def\inlineextras at occitan{%
-   \lccode\string"2019=\string"2019
-   \ifoccitan at babelshorthands\occitan at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifoccitan at babelshorthands\occitan at shorthands\fi%
 }
 %% Distributable under the LaTeX Project Public License,
 %% version 1.3c or higher (your choice). The latest version of
@@ -13959,12 +19613,7 @@
 % \subsection{gloss-persian.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-persian.ldf}[polyglossia: module for persian]
-\ifluatex
-  \xpg at 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 @@
 
 
 \def\noextras at piedmontese{%
-   \lccode\string"2019=\z@
-   \nopiedmontese at shorthands
-   \xpgpms at savedvalues
+   \lccode\string"2019=\z@%
+   \ifpiedmontese at babelshorthands\nopiedmontese at shorthands\fi%
+   \xpgpms at savedvalues%
 }
 
 \def\blockextras at piedmontese{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi%
 }
 
 \def\inlineextras at piedmontese{%
-   \lccode\string"2019=\string"2019
-   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi%
 }
 %%% CHANGES END %%%
 %    \end{macrocode}
@@ -14354,10 +20003,8 @@
       % brazilian:
       \def\portuguese at variant{brazil}%
       \SetLanguageKeys{portuguese}{babelname=brazil,bcp47=pt-BR}%
-      \xpg at ifdefined{brazil}{}%
-	    {\xpg at warning{No hyphenation patterns were loaded for "Portuguese (Brazil)"\MessageBreak
-	      I will use the standard patterns for Portuguese instead}%
-	    \adddialect\l at brazil\l at portuges\relax}%
+      % There are no specific brazil patterns
+      \adddialect\l at brazil\l at portuges\relax%
    \fi
    \xpg at info{Option: portuguese, variant=\xpg at val}%
 }{\xpg at warning{Unknown portuguese variant `#1'}}
@@ -14621,19 +20268,26 @@
    \xpg at info{Option: Russian, numerals=\xpg at val}%
 }{\xpg at warning{Unknown Russian numerals value `#1'}}
 
-\define at boolkey{russian}[russian@]{indentfirst}[true]{
-   \ifrussian at indentfirst
-      \SetLanguageKeys{russian}{indentfirst=true}
-   \else
-      \SetLanguageKeys{russian}{indentfirst=false}
-  \fi
+\define at boolkey{russian}[russian@]{indentfirst}[true]{%
+  \ifrussian at indentfirst
+      \SetLanguageKeys{russian}{indentfirst=true}%
+  \else
+      \SetLanguageKeys{russian}{indentfirst=false}%
+  \fi%
 }
 
 \define at boolkey{russian}[russian@]{babelshorthands}[true]{}
 
+% Force punctuation after heading number
+\define at boolkey{russian}[russian@]{forceheadingpunctuation}[true]{}
 
+
 % Register default options
-\xpg at initialize@gloss at options{russian}{babelshorthands=false,spelling=modern,numerals=arabic,indentfirst=false}
+\xpg at initialize@gloss at options{russian}{babelshorthands=false,
+                                       spelling=modern,
+                                       numerals=arabic,
+                                       indentfirst=true,
+                                       forceheadingpunctuation=true}
 
 
 \ifsystem at babelshorthands
@@ -14681,7 +20335,7 @@
   \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 at shorthand{russian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -14778,41 +20432,48 @@
       \space \number\year\space г.}%
 }
 
-% The following is based on some ideas from ruscor.sty
+% Russian needs trailing dots in all headings
+\def\xpg at save@autodot{}
+\ifdef{\KOMAScript}{%
+    \let\xpg at save@autodot\autodot%
+}
+
 \def\russian at capsformat{%
+  \ifrussian at 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 at capsformat{%
+  \ifrussian at forceheadingpunctuation%
+    \ifdef{\KOMAScript}{%
+       \let\autodot\xpg at save@autodot%
+    }{%
+       \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
+    }%
+  \fi%
+}
+
 \newcommand{\russiannumerals}[2]{\russiannumber{#2}}
 \newcommand{\Russiannumerals}[2]{\Russiannumber{#2}}
 
@@ -14885,24 +20546,9 @@
 }
 
 \def\noextras at 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 at capsformat%
    \ifcyrillic at numerals\norussian at numbers\fi%
-   \norussian at shorthands%
+   \ifrussian at babelshorthands\norussian at shorthands\fi%
 }
 
 \def\blockextras at russian{%
@@ -15061,12 +20707,6 @@
 % \subsection{gloss-sanskrit.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-sanskrit.ldf}[polyglossia: module for sanskrit]
-\ifluatex
-  \xpg at 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 @@
   indentfirst=true,
   fontsetup=false,
   localnumeral=serbiannumerals,
-  Localnumeral=Serbiannumerals
+  Localnumeral=Serbiannumerals,
+  babelname=serbian
   %TODO localalph
 }
 
@@ -15271,7 +20912,7 @@
    \or
       % latin:
       \@serbian at cyrfalse
-      \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,bcp47=sr-Latn}
+      \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,babelname=serbian,bcp47=sr-Latn}
       \xpg at fontsetup@latin{serbian}%
       %TODO \def\serbian at language{\language=\l at serbianlat}%
       % or should we use Croatian patterns as a fallback for the time being???
@@ -15579,7 +21220,7 @@
       \chardef\slovak at boundary=4095 %
       \def\newXeTeXintercharclass{%
         \e at alloc\XeTeXcharclass\chardef
-              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}
+              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}%
     \else
       \chardef\slovak at boundary=255
     \fi
@@ -15608,6 +21249,24 @@
 
 % 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 at nointerchartoks{\let\slovak at interchartoks\slovak at PreCSpreposition}%
+    \def\slovak at PreCSpreposition{%
+       \def\next{}%
+       \ifnum\catcode`\ =10 % nothing will be done in verbatim
+       \ifmmode % nothing in math
+       \else
+          \let\slovak at interchartoks\slovak at nointerchartoks
+          \let\next\slovak at ExamineCSpreposition
+       \fi\fi
+       \next%
+    }%
+    \def\slovak at ExamineCSpreposition #1{#1\futurelet\next\slovak at ProcessCSpreposition}%
+    \def\slovak at ProcessCSpreposition{\ifx\next\slovak at XeTeXspace\nobreak\fi}%
+    \futurelet\slovak at XeTeXspace{ }\slovak at nointerchartoks
+\fi
+
 \def\slovak at vlna{%
     \ifluatex
        \preventsingleon
@@ -15634,21 +21293,8 @@
         \XeTeXcharclass `\a \slovak at nonsyllabicpreposition
         \XeTeXcharclass `\I \slovak at nonsyllabicpreposition
         \XeTeXcharclass `\i \slovak at nonsyllabicpreposition
-        \XeTeXinterchartoks \slovak at boundary \slovak at nonsyllabicpreposition {\slovak at interchartoks}
-        \XeTeXinterchartoks \slovak at openpunctuation \slovak at nonsyllabicpreposition {\slovak at interchartoks}
-        \def\slovak at nointerchartoks{\let\slovak at interchartoks\slovak at PreCSpreposition}
-        \def\slovak at PreCSpreposition{\def\next{}%
-           \ifnum\catcode`\ =10 % nothing will be done in verbatim
-           \ifmmode % nothing in math
-           \else
-              \let\slovak at interchartoks\slovak at nointerchartoks
-              \let\next\slovak at ExamineCSpreposition
-           \fi \fi
-          \next%
-        }
-        \def\slovak at ExamineCSpreposition ##1{##1\futurelet\next\slovak at ProcessCSpreposition}
-        \def\slovak at ProcessCSpreposition{\ifx\next\slovak at XeTeXspace\nobreak\fi}
-        \futurelet\slovak at XeTeXspace{ }\slovak at nointerchartoks
+        \XeTeXinterchartoks \slovak at boundary \slovak at nonsyllabicpreposition {\slovak at interchartoks}%
+        \XeTeXinterchartoks \slovak at openpunctuation \slovak at nonsyllabicpreposition {\slovak at interchartoks}%
     \fi
 }
 
@@ -15714,7 +21360,7 @@
 }
 
 \def\noextras at slovak{%
-  \noslovak at shorthands%
+  \ifslovak at babelshorthands\noslovak at shorthands\fi%
   \noslovak at hyphens%
   \noslovak at vlna%
   \ifxetex\XeTeXinterchartokenstate=0\fi%
@@ -16354,12 +22000,7 @@
 % \subsection{gloss-syriac.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-syriac.ldf}[polyglossia: module for syriac]
-\ifluatex
-  \xpg at 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 @@
 % \subsection{gloss-tamil.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-tamil.ldf}[polyglossia: module for tamil]
-\ifluatex
-  \xpg at 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 @@
 % \subsection{gloss-telugu.ldf}
 %    \begin{macrocode}
 \ProvidesFile{gloss-telugu.ldf}[polyglossia: module for telugu]
-\ifluatex
-  \xpg at warning{Telugu is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
 % Translations provided by Anmol Sharma <unmole.in at gmail.com>
 
 \PolyglossiaSetup{telugu}{
@@ -16697,12 +22328,6 @@
 %%%%              Thai Linux Working Group
 %%%%              http://linux.thai.net/
 %%%%
-\ifluatex
-  \xpg at 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 @@
   \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 at shorthand{ukrainian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -17370,7 +22995,7 @@
 \def\ukrainiannumber#1{%
   \ifcyrillic at numerals
     \ifcyrillic at asbuk@numerals
-      \serbian at asbuk@alph{#1}%
+      \ukrainian at asbuk@alph{#1}%
     \else
       \cyr at alph{#1}%
     \fi
@@ -17382,7 +23007,7 @@
 \def\Ukrainiannumber#1{%
   \ifcyrillic at numerals
     \ifcyrillic at asbuk@numerals
-      \serbian at asbuk@Alph{#1}%
+      \ukrainian at asbuk@Alph{#1}%
     \else
       \cyr at Alph{#1}%
     \fi
@@ -17402,25 +23027,29 @@
 
 % This is a poor man's cyrillic alphanumeric. It just uses the alphabet and
 % thus ends at 30.
-\def\ukranian at asbuk@Alph#1{\ifcase#1\or
+\def\ukrainian at 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 at ill@value{#1}{ukranian at asbuk@Alph}\fi%
+   \else\xpg at ill@value{#1}{ukrainian at asbuk@Alph}\fi%
 }
 
-\def\ukranian at asbuk@alph#1{\ifcase#1\or
+\def\ukrainian at 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 at ill@value{#1}{ukranian at asbuk@alph}\fi%
+   \else\xpg at ill@value{#1}{ukrainian at asbuk@alph}\fi%
 }
 
 \def\ukrainian at numbers{%
-   \let\@Alph\ukrainian at Alph%
-   \let\@alph\ukrainian at alph%
+  \ifcyrillic at numerals
+     \def\ukrainian at alph##1{\expandafter\ukrainiannumeral\expandafter{\the##1}}%
+     \def\ukrainian at Alph##1{\expandafter\Ukrainiannumeral\expandafter{\the##1}}%
+     \let\@Alph\ukrainian at Alph%
+     \let\@alph\ukrainian at alph%
+  \fi
 }
 
 \def\noukrainian at numbers{%
@@ -17431,13 +23060,13 @@
 \def\noextras at ukrainian{%
   \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
   \ifcyrillic at numerals\noukrainian at numbers\fi
-  \noukrainian at shorthands%
+  \ifukrainian at babelshorthands\noukrainian at shorthands\fi%
 }
 
 \def\blockextras at ukrainian{%
   \ukrainian at capsformat%
-  \ifcyrillic at numerals\ukrainian at numbers\fi
-  \ifukrainian at babelshorthands\ukrainian at shorthands\fi
+  \ifcyrillic at numerals\ukrainian at numbers\fi%
+  \ifukrainian at babelshorthands\ukrainian at shorthands\fi%
 }
 
 \def\inlineextras at ukrainian{%
@@ -17492,12 +23121,7 @@
 %    \begin{macrocode}
 %%% Adapted from a file contributed by Kamal Abdali
 \ProvidesFile{gloss-urdu.ldf}[polyglossia: module for Urdu]
-\ifluatex
-  \xpg at 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 @@
 
 -- 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 @@
         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,16 +24542,16 @@
                         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
                         if leftspace.unit == "quad" then
                             unit = fontparameters.quad
@@ -18952,11 +24579,11 @@
                             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
                             unit = fontparameters.quad
@@ -19368,53 +24995,69 @@
 % \Finale
 % 
 % \iffalse
-%<*../README.md>
-# THE POLYGLOSSIA PACKAGE v1.49
-## Multilingual typesetting with XeLaTeX and LuaLaTeX
+%<*Changelog>
+1.50 (09-10-2020)
 
-This package provides an alternative to Babel for users of XeLaTeX and LuaLaTeX
-(with a few languages incompletely supported for the latter). This version
-includes support for over 70 different languages, some of which in different
-regional or national varieties, or using a different writing system.
+New features:
 
-Polyglossia makes it possible to automate the following tasks:
+  * Polyglossia now uses the Harfbuzz renderer by default with LuaTeX
+    output. This brings LuaTeX on par with XeTeX for all scripts (#337).
+    The renderer can be changed via the new global luatexrenderer option.
+  * The (previously inadvertently working) hyphenrules environment that ceased
+    to work after a recent babel update is back and now officially supported.
+    The environment now also supports language options and aliases (#427).
+  * New command \setlanghyphenmins to adapt hyphenation thresholds of languages
+    and varieties.
+  * New command \abjadalph for Arabic with corresponding option (#431).
+  * Replace consecutive glues around punctuation by the correct amount of space
+    with LuaLaTeX for French, ecclesiastic Latin, and Sanskrit (#437).
 
-* Loading the appropriate hyphenation patterns.
-* Setting the script and language tags of the current font (if possible and
-  available), using the package fontspec.
-* Switching to a font assigned by the user to a particular script or language.
-* Adjusting some typographical conventions in function of the current language
-  (such as afterindent, frenchindent, spaces before or after punctuation marks,
-  etc.).
-* Redefining the document strings (like “chapter”, “figure”, “bibliography”).
-* Adapting the formatting of dates (for non-gregorian calendars via external
-  packages bundled with polyglossia: currently the Hebrew, Islamic and Farsi
-  calendars are supported).
-* For languages that have their own numeration system, modifying the formatting
-  of numbers appropriately.
-* Ensuring the proper directionality if the document contains languages
-  written from right to left (via the packages bidi and luabidi, available
-  separately).
+Bug fixes:
 
-# LICENCE
+  * Remove warning about missing Brazil patterns (#404).
+  * Fix incompatibility with recent babel release (#408).
+  * Fixed some spellings in Marathi (#409).
+  * Fix spacing of geminating dot in Catalan (#410).
+  * Fix incompatibility of Marathi with Beamer.
+  * Correct \partname in Hindi (#416).
+  * Updates and improvements to Kurdish (#418).
+  * Only activate shorthand character if babelshorthands is true (#421). 
+  * Fix whitespace issue in Czech and Slovak with vlna=true (#423).
+  * Fix whitespace issue in Danish (#424).
+  * Fix catcode conflicts that might occur in language definition files
+    f. ex. when loaded from a LaTeX3 class (#67, #425).
+  * Robustify font family switches (#428).
+  * Fix whitespace issue in Russian indentfirst option (#433).
+  * In Russian, indentfirst is now again default (#434).
+  * Fix LaTeX error with arabic numbering in Ukrainian (#440).
+  * Fix directionality after Hebrew decimal numbers (#441).
+  * Fix babelname of Latin Serbian (#442).
+  * Fix recording of secondary languages in \xpg at bloaded and \xpg at bcp@loaded
+    lists (#443).
+  * Simplify and robustify section heading modification in Russian
+    and introduce option forceheadingpunctuation (#444).
+  * Fix Cyrillic dash (via babelshorthand "---) when TeX ligatures
+    are disabled (#445)
+  * Fix problem with large character indices in Lua module for punctuation
+    spacing
 
-Copyright (c) 2008-2010 François Charette, 2013 Élie Roux, 2011-2020 Arthur Reutenauer,
-Copyright (c) 2019-2020 Bastien Roucariès, 2019-2020 Jürgen Spitzmüller
+Interface and defaults changes:
 
-Except where otherwise noted, Polyglossia is placed under the terms of the MIT licence
-(https://opensource.org/licenses/MIT).
+  * Polyglossia now uses the Harfbuzz renderer by default with LuaTeX
+    output. See new features section.
 
-# BUGS
+Build fixes:
 
-If you run into a bug, or suspect you do, or you have a request or comment, please
-use the GitHub issue tracker: http://github.com/reutenauer/polyglossia/issues
+  * Fix a bug in the dtx build script which was the reason for an utterly
+    incomplete polyglossia.dtx file (#420).
 
-This is more efficient than contacting the maintainer by email as it allows me
-to track the issues and follow progress.
-%</../README.md>
-%<*Changelog>
-1.49 (???)
+Documentation improvements:
+  * Document how to change \lefthyphenmin and \righthyphenmin for a language
+    (#435).
 
+
+1.49 (08-04-2020)
+
 New features:
 
   * Add hook \polyglossia at language@switched to the external package interface (#398).

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/babelsh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/babelsh.def	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/babelsh.def	2020-10-09 20:23:21 UTC (rev 56613)
@@ -216,6 +216,17 @@
 %
 % ------------------------------------------------------------------------------
 %
+% lines 293 to 301 from babel.def
+%
+% NOTE: In order to avoid importing more unneeded definitions, this macro
+%       does nothing for us.
+%
+% ------------------------------------------------------------------------------
+%
+\def\bbl at usehooks#1#2{}
+%
+% ------------------------------------------------------------------------------
+%
 % lines 443 to 558 from babel.def
 %
 % ------------------------------------------------------------------------------

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-afrikaans.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-afrikaans.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-afrikaans.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -79,7 +79,7 @@
 }
 
 \def\noextras at afrikaans{%
-  \noafrikaans at shorthands%
+  \ifafrikaans at babelshorthands\noafrikaans at shorthands\fi%
 }
 
 \def\blockextras at afrikaans{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-arabic.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-arabic.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-arabic.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,4 @@
 \ProvidesFile{gloss-arabic.ldf}[polyglossia: module for arabic]
-\ifluatex
-  \xpg at 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}
@@ -39,6 +33,8 @@
 \setlanguagealias*[locale=default]{arabic}{apd}
 \setlanguagealias*[locale=mashriq]{arabic}{ar-PS}
 
+\define at boolkey{arabic}[arabic@]{abjadalph}[true]{}
+
 \newif\ifeastern at numerals
 \def\tmp at mashriq{mashriq}
 \def\tmp at maghrib{maghrib}
@@ -173,6 +169,19 @@
 \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 at abjad@alph{\number#1}}
+
+% This is a poor man's Arabic alphanumeric. It just uses the alphabet and
+% thus ends at 28.
+\def\arabic at abjad@alph#1{\ifcase#1%
+   \or ا\or ب\or\abjad at 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 at ill@value{#1}{arabic at abjad@alph}\fi%
+}
+
+
 \def\abjadmaghribi#1{%
 \ifnum#1>1999\xpg at ill@value{#1}{abjad}%
 \else
@@ -207,8 +216,13 @@
   \ifnum#1=\z@\fi\abj at maghribi@num at iii}
 
 \def\arabic at numbers{%
+ \ifarabic at abjadalph
+   \let\@alph\abjadalph%
+   \let\@Alph\abjadalph%
+ \else
    \let\@alph\abjad%
    \let\@Alph\abjad%
+ \fi
 }
 
 \def\noarabic at numbers{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-belarusian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-belarusian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-belarusian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -112,7 +112,7 @@
   \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 at shorthand{belarusian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -297,7 +297,7 @@
 
 \def\noextras at belarusian{%
    \ifcyrillic at numerals\nobelarusian at numbers\fi%
-   \nobelarusian at shorthands%
+   \ifbelarusian at babelshorthands\nobelarusian at shorthands\fi%
 }
 
 \def\blockextras at belarusian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-bengali.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-bengali.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-bengali.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -3,13 +3,6 @@
 
 \ProvidesFile{gloss-bengali.ldf}[polyglossia: module for bengali]
 
-\ifluatex
-  \xpg at 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}
 

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-catalan.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-catalan.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-catalan.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -41,18 +41,23 @@
     \csname normal at char\string"\endcsname l%
   \else
     \leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
-    \setbox0\hbox{l}\setbox1\hbox{l\/}%
+    \setbox0\hbox{l}%
     \xpg at if@char at 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 at raiseddot%
       \kern\rightllkern\hbox{l}}\allowhyphens
@@ -64,19 +69,24 @@
     \csname normal at char\string"\endcsname L%
   \else
     \leftllkern=0pt\rightllkern=0pt\raiselldim=0pt%
-    \setbox0\hbox{L}\setbox1\hbox{L\/}%
+    \setbox0\hbox{L}%
     \xpg at if@char at 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 at raiseddot%
       \kern\rightllkern\hbox{L}}\allowhyphens
@@ -134,7 +144,7 @@
     \space de~\number\year}}
 
 \def\noextras at catalan{%
-   \nocatalan at shorthands%
+   \ifcatalan at babelshorthands\nocatalan at shorthands\fi%
 }
 
 \def\blockextras at catalan{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-croatian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-croatian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-croatian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -163,7 +163,7 @@
 }
 
 \def\noextras at croatian{%
-  \nocroatian at shorthands%
+  \ifcroatian at babelshorthands\nocroatian at shorthands\fi%
 }
 
 \def\blockextras at croatian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-czech.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-czech.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-czech.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -77,7 +77,7 @@
       \chardef\czech at boundary=4095 %
       \def\newXeTeXintercharclass{%
         \e at alloc\XeTeXcharclass\chardef
-              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}
+              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}%
     \else
       \chardef\czech at boundary=255
     \fi
@@ -106,6 +106,24 @@
 
 % 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 at nointerchartoks{\let\czech at interchartoks\czech at PreCSpreposition}%
+    \def\czech at PreCSpreposition{%
+       \def\next{}%
+       \ifnum\catcode`\ =10 % nothing will be done in verbatim
+       \ifmmode % nothing in math
+       \else
+          \let\czech at interchartoks\czech at nointerchartoks
+          \let\next\czech at ExamineCSpreposition
+       \fi\fi
+       \next%
+    }%
+    \def\czech at ExamineCSpreposition #1{#1\futurelet\next\czech at ProcessCSpreposition}%
+    \def\czech at ProcessCSpreposition{\ifx\next\czech at XeTeXspace\nobreak\fi}%
+    \futurelet\czech at XeTeXspace{ }\czech at nointerchartoks
+\fi
+
 \def\czech at vlna{%
     \ifluatex
        \preventsingleon
@@ -132,21 +150,8 @@
         \XeTeXcharclass `\a \czech at nonsyllabicpreposition
         \XeTeXcharclass `\I \czech at nonsyllabicpreposition
         \XeTeXcharclass `\i \czech at nonsyllabicpreposition
-        \XeTeXinterchartoks \czech at boundary \czech at nonsyllabicpreposition {\czech at interchartoks}
-        \XeTeXinterchartoks \czech at openpunctuation \czech at nonsyllabicpreposition {\czech at interchartoks}
-        \def\czech at nointerchartoks{\let\czech at interchartoks\czech at PreCSpreposition}
-        \def\czech at PreCSpreposition{\def\next{}%
-           \ifnum\catcode`\ =10 % nothing will be done in verbatim
-           \ifmmode % nothing in math
-           \else
-              \let\czech at interchartoks\czech at nointerchartoks
-              \let\next\czech at ExamineCSpreposition
-           \fi \fi
-          \next%
-        }
-        \def\czech at ExamineCSpreposition ##1{##1\futurelet\next\czech at ProcessCSpreposition}
-        \def\czech at ProcessCSpreposition{\ifx\next\czech at XeTeXspace\nobreak\fi}
-        \futurelet\czech at XeTeXspace{ }\czech at nointerchartoks
+        \XeTeXinterchartoks \czech at boundary \czech at nonsyllabicpreposition {\czech at interchartoks}%
+        \XeTeXinterchartoks \czech at openpunctuation \czech at nonsyllabicpreposition {\czech at interchartoks}%
     \fi
 }
 
@@ -212,7 +217,7 @@
 }
 
 \def\noextras at czech{%
-  \noczech at shorthands%
+  \ifczech at babelshorthands\noczech at shorthands\fi%
   \noczech at hyphens%
   \noczech at vlna%
   \ifxetex\XeTeXinterchartokenstate=0\fi%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-danish.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-danish.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-danish.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -34,11 +34,12 @@
   \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}%
 }
 
 \endinput

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-divehi.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-divehi.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-divehi.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-divehi.ldf}[polyglossia: module for divehi]
-\ifluatex
-  \xpg at 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,

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-dutch.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-dutch.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-dutch.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -79,7 +79,7 @@
 }
 
 \def\noextras at dutch{%
-  \nodutch at shorthands%
+  \ifdutch at babelshorthands\nodutch at shorthands\fi%
 }
 
 \def\blockextras at dutch{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-finnish.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-finnish.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-finnish.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -76,7 +76,7 @@
     \space\number\year}}
 
 \def\noextras at finnish{%
-  \nofinnish at shorthands%
+  \iffinnish at babelshorthands\nofinnish at shorthands\fi%
 }
 
 \def\blockextras at finnish{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-georgian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-georgian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-georgian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -72,7 +72,7 @@
   \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 at shorthand{georgian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -217,7 +217,7 @@
 
 \def\noextras at georgian{%
    \ifgeorgian at numerals\nogeorgian at numbers\fi%
-   \nogeorgian at shorthands%
+   \ifgeorgian at babelshorthands\nogeorgian at shorthands\fi%
 }
 
 \def\blockextras at georgian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-german.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-german.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-german.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -198,14 +198,14 @@
   \declare at shorthand{german}{"R}{\textormath{\bbl at disc@german R{RR}}{R}}%
   \declare at shorthand{german}{"t}{\textormath{\bbl at disc@german t{tt}}{t}}%
   \declare at shorthand{german}{"T}{\textormath{\bbl at disc@german T{TT}}{T}}%
-  \declare at shorthand{german}{"f}{\textormath{\bbl at discff}{f}}%
+  \declare at shorthand{german}{"f}{\texorpdfstring{\textormath{\bbl at discff}{f}}{f}}%
   \def\bbl at discff{\penalty\@M
-    \afterassignment\bbl at insertff \let\bbl at nextff= }%
+    \afterassignment\bbl at insertff \cslet{bbl at nextff}{ }}%
   \def\bbl at insertff{%
     \if f\bbl at nextff
       \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
     {\relax\discretionary{ff-}{f}{ff}\allowhyphens}{f\bbl at nextff}}%
-  \let\bbl at nextff=f%
+  \cslet{bbl at nextff}{f}%
   \declare at shorthand{german}{"-}{\nobreak\-\nobreak\hskip\z at skip}%
   \declare at shorthand{german}{"|}{\textormath{\penalty\@M\discretionary{-}{}{\kern.03em}}{}}%
   \declare at shorthand{german}{""}{\hskip\z at skip}%
@@ -310,15 +310,15 @@
 }
 
 \def\noextras at german{%
-  \nogerman at shorthands%
+  \ifgerman at babelshorthands\nogerman at shorthands\fi%
 }
 
 \def\blockextras at german{%
-  \ifgerman at babelshorthands\german at shorthands\fi
+  \ifgerman at babelshorthands\german at shorthands\fi%
 }
 
 \def\inlineextras at german{%
-  \ifgerman at babelshorthands\german at shorthands\fi
+  \ifgerman at babelshorthands\german at shorthands\fi%
 }
 
 \endinput

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hebrew.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hebrew.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hebrew.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-hebrew.ldf}[polyglossia: module for hebrew]
-\ifluatex
-  \xpg at 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}
 
@@ -111,23 +106,23 @@
    \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 at hebrew@DigitsDotDashInterCharToks{\ifbool{@nonlatin}{\char"200E }{}}
+  \let\xpg at orig@DigitsDotDashInterCharToks\DigitsDotDashInterCharToks%
 \fi
 
 \def\hebrew at ltr@numbers{%
     \ifxetex
-      \XeTeXinterchartoks \bidi at sepmark@charclass  \bidi at digits@charclass = {\xpg at 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 at ltr@numbers{%
     \ifxetex
-      % This is bidi's original intervention
-      \XeTeXinterchartoks \bidi at sepmark@charclass  \bidi at digits@charclass = {\DigitsDotDashInterCharToks}%
+      % Restore bidi's \DigitsDotDashInterCharToks
+      \let\DigitsDotDashInterCharToks\xpg at orig@DigitsDotDashInterCharToks%
     \fi%
 }
 

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hindi.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hindi.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-hindi.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -75,7 +75,7 @@
      \def\listfigurename{चित्रों की सूची}%
      \def\listtablename{तालिकाओं की सूची}%
      \def\pagename{पृष्ठ}%
-     \def\partname{खणड}%
+     \def\partname{खण्ड}%
      \def\prefacename{प्रस्तावना}% प्राक्कथन
      \def\refname{हवाले}%
      \def\tablename{तालिका}%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-italian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-italian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-italian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -120,21 +120,21 @@
 
 
 \def\noextras at italian{%
-   \lccode\string"2019=\z@
-   \noitalian at shorthands
-   \xpgit at savedvalues
+   \lccode\string"2019=\z@%
+   \ifitalian at babelshorthands\noitalian at shorthands\fi%
+   \xpgit at savedvalues%
 }
 
 \def\blockextras at italian{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifitalian at babelshorthands\italian at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifitalian at babelshorthands\italian at shorthands\fi%
 }
 
 \def\inlineextras at italian{%
-   \lccode\string"2019=\string"2019
-   \ifitalian at babelshorthands\italian at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifitalian at babelshorthands\italian at shorthands\fi%
 }
 %%% CHANGES END %%%
 \endinput

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kannada.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kannada.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kannada.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -17,12 +17,7 @@
 %
 % This work consists of the file gloss-kannada.ldf
 \ProvidesFile{gloss-kannada.ldf}[polyglossia: module for kannada]
-\ifluatex
-  \xpg at 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,

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kurdish.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kurdish.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-kurdish.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,5 +1,7 @@
 % Created on September 1, 2019
-% Sina Ahmadi (https://sinaahmadi.github.io/)
+% Last updated on May 17, 2020
+% Sina Ahmadi (ahmadi.sina at 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
@@ -127,7 +129,6 @@
 \define at key{kurdish}{locale}[default]{%
   \def\@kurdish at locale{#1}}
 
-
 %TODO add option for CALENDAR
 
 % Register default options
@@ -138,9 +139,9 @@
 }%
 
 \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}{%
@@ -150,27 +151,27 @@
 }
 
 \def\captionskurdish at sorani@arabic{%
-  \def\prefacename{\@ensure at RTL{پێشه‌كی}}%
-  \def\refname{\@ensure at RTL{سه‌رچاوه‌کان}}%
-  \def\abstractname{\@ensure at RTL{پوخته‌}}%
-  \def\bibname{\@ensure at RTL{کتێبنامه‌}}%
-  \def\chaptername{\@ensure at RTL{به‌ندی}}%
+  \def\prefacename{\@ensure at RTL{پێشەكی}}%
+  \def\refname{\@ensure at RTL{سەرچاوەکان}}%
+  \def\abstractname{\@ensure at RTL{پوختە}}%
+  \def\bibname{\@ensure at RTL{کتێبنامە}}%
+  \def\chaptername{\@ensure at RTL{بەندی}}%
   \def\appendixname{\@ensure at RTL{پاشکۆ}}%
-  \def\contentsname{\@ensure at RTL{نێوه‌ڕۆک}}%
-  \def\listfigurename{\@ensure at RTL{لیستی وێنه‌کان}}%
-  \def\listtablename{\@ensure at RTL{لیستی خشته‌کان}}%
+  \def\contentsname{\@ensure at RTL{نێوەڕۆک}}%
+  \def\listfigurename{\@ensure at RTL{لیستی وێنەکان}}%
+  \def\listtablename{\@ensure at RTL{لیستی خشتەکان}}%
   \def\indexname{\@ensure at RTL{پێنوێن}}%
-  \def\figurename{\@ensure at RTL{وێنه‌}}%
-  \def\tablename{\@ensure at RTL{خشتە}}%
-  \def\partname{\@ensure at RTL{به‌شی}}%
+  \def\figurename{\@ensure at RTL{وێنەی}}%
+  \def\tablename{\@ensure at RTL{خشتەی}}%
+  \def\partname{\@ensure at RTL{بەشی}}%
   \def\enclname{\@ensure at RTL{هاوپێچ}}%
-  \def\ccname{\@ensure at RTL{روونووس}}%
+  \def\ccname{\@ensure at RTL{ڕوونووس}}%
   \def\headtoname{\@ensure at RTL{بۆ}}%
-  \def\pagename{\@ensure at RTL{لاپه‌ڕه‌}}%
-  \def\seename{\@ensure at RTL{چاو لێکه‌ن}}%
-  \def\alsoname{\@ensure at RTL{هه‌روه‌ها چاو لێکه‌ن}}%
+  \def\pagename{\@ensure at RTL{لاپەڕە}}%
+  \def\seename{\@ensure at RTL{چاو لێکەن}}%
+  \def\alsoname{\@ensure at RTL{هەروەها چاو لێکەن}}%
   \def\proofname{\@ensure at RTL{سەلماندن}}%
-  \def\glossaryname{\@ensure at RTL{فه‌رهه‌نگۆک}}%
+  \def\glossaryname{\@ensure at RTL{فەرهەنگۆک}}%
 }
 
 \def\captionskurdish at sorani@latin{%
@@ -180,17 +181,17 @@
   \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}%
@@ -199,7 +200,7 @@
 
 \def\captionskurdish at 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ê}%
@@ -216,7 +217,7 @@
   \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ê}%
 }
@@ -223,7 +224,7 @@
 
 \def\captionskurdish at kurmanji@arabic{%
   \def\prefacename{\@ensure at RTL{پێشگۆتن}}%
-  \def\refname{\@ensure at RTL{پرتووکێن بژارتی}}%
+  \def\refname{\@ensure at RTL{ژێدەر}}%
   \def\abstractname{\@ensure at RTL{کورتەبیر}}%
   \def\bibname{\@ensure at RTL{چاڤکانییا پرتووکان}}%
   \def\chaptername{\@ensure at RTL{سەرێ}}%
@@ -255,17 +256,17 @@
 
 \def\datekurdish at 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}%
@@ -282,13 +283,13 @@
 
 \def\datekurdish at 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
@@ -307,8 +308,11 @@
   \def\decembername{Çileya Pêşîn}%
 }
 
+\def\kurdishmonthkurmanji#1{\ifcase#1%
+  چلەیا پاشین \or شبات \or ئادار \or نیسان \or گولان \or حەزیران \or تیرمەهـ \or تەباخ \or ئیلۆن \or چریا پێشین \or چریا پاشین \or چلەیا پێشین\fi}
+
 \def\datekurdish at kurmanji@arabic{%
-   \datekurdish at sorani@arabic% FIXME: correct?
+   \def\today{\@ensure at RTL{\kurdishnumber\day\space\kurdishmonthkurmanji{\month}\space\kurdishnumber\year}}%
 }
 
 % TODO: babel-kurmanji has these "alternative" month names

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-lao.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-lao.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-lao.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-lao.ldf}[polyglossia: module for Lao]
-\ifluatex
-  \xpg at 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,

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-latin.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-latin.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-latin.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -625,7 +625,7 @@
 % 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 at write \@auxout { } { \shorthandoff {=} } % for the aux file
 

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-malayalam.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-malayalam.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-malayalam.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-malayalam.ldf}[polyglossia: module for malayalam]
-\ifluatex
-  \xpg at 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}{

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-marathi.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-marathi.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-marathi.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -3,12 +3,7 @@
 % TODO implement Hindu calendar (not used in day-to-day practice)
 
 \ProvidesFile{gloss-marathi.ldf}[polyglossia: module for marathi]
-\ifluatex
-  \xpg at 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}{
@@ -62,7 +57,7 @@
    \def\appendixname{परिशिष्ट}%
    \def\contentsname{अनुक्रमणिका}%
    \def\listfigurename{आकृत्यांची सूची}%
-   \def\listtablename{कोष्टक सूची}%
+   \def\listtablename{कोष्टकसूची}%
    \def\indexname{सूची}%
    \def\figurename{आकृती}%
    \def\tablename{कोष्टक}%
@@ -71,10 +66,10 @@
    \def\seename{पाहा}%
    \def\alsoname{हेदेखील पाहा}%
    \def\enclname{समाविष्ट}%
-   \def\ccname{सी.सी.}%
+   \def\ccname{प्रत}%
    \def\headtoname{प्रति}%
    \def\proofname{सिद्धता}%
-   \def\glossaryname{संक्षेपसूची}%
+   \def\glossaryname{संज्ञांची सूची}%
    \def\authorsand{आणि}%
 }
 
@@ -100,23 +95,23 @@
    }%
 }
 
-\def\devanagari at akshar#1{\ifcase#1\or अ\or आ\or इ\or ई\or उ\or ऊ\or ए\or ऐ\or ओ\or औ\or अं\or अः\else\@ctrerr\fi}
+\def\devanagari at 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 at 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 at 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%
 }
@@ -138,17 +133,4 @@
   \let\@Roman\xpg at save@Roman
 }
 
-\def\blockextras at marathi{%
-  \let\xpg at orig@baselinestretch\baselinestrech%
-  \renewcommand{\baselinestretch}{1.2}%
-  \renewcommand{\labelitemii}{$\rightarrow$}%
-}
-
-\let\xpg at orig@labelitemii\labelitemii
-
-\def\noextras at marathi{%
-  \let\baselinestrech\xpg at orig@baselinestretch%
-  \let\labelitemii\xpg at orig@labelitemii%
-}
-
 \endinput

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-mongolian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-mongolian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-mongolian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -98,7 +98,7 @@
   \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 at shorthand{mongolian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -212,7 +212,7 @@
 
 \def\noextras at mongolian{%
    \ifcyrillic at numerals\nomongolian at numbers\fi%
-   \nomongolian at shorthands%
+   \ifmongolian at babelshorthands\nomongolian at shorthands\fi%
 }
 
 \def\blockextras at mongolian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-occitan.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-occitan.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-occitan.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -140,20 +140,20 @@
     \finalhyphendemerits=\the\finalhyphendemerits}
 }
 \def\noextras at occitan{%
-   \lccode\string"2019=\z@
-   \nooccitan at shorthands
-   \xpgoc at savedvalues
+   \lccode\string"2019=\z@%
+   \ifoccitan at babelshorthands\nooccitan at shorthands\fi%
+   \xpgoc at savedvalues%
 }
 \def\blockextras at occitan{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifoccitan at babelshorthands\occitan at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifoccitan at babelshorthands\occitan at shorthands\fi%
 }
 
 \def\inlineextras at occitan{%
-   \lccode\string"2019=\string"2019
-   \ifoccitan at babelshorthands\occitan at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifoccitan at babelshorthands\occitan at shorthands\fi%
 }
 %% Distributable under the LaTeX Project Public License,
 %% version 1.3c or higher (your choice). The latest version of

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-persian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-persian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-persian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-persian.ldf}[polyglossia: module for persian]
-\ifluatex
-  \xpg at 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}

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-piedmontese.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-piedmontese.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-piedmontese.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -99,21 +99,21 @@
 
 
 \def\noextras at piedmontese{%
-   \lccode\string"2019=\z@
-   \nopiedmontese at shorthands
-   \xpgpms at savedvalues
+   \lccode\string"2019=\z@%
+   \ifpiedmontese at babelshorthands\nopiedmontese at shorthands\fi%
+   \xpgpms at savedvalues%
 }
 
 \def\blockextras at piedmontese{%
-   \lccode\string"2019=\string"2019
-   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000
-   \finalhyphendemerits=50000000
-   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \clubpenalty=3000 \@clubpenalty=3000 \widowpenalty=3000%
+   \finalhyphendemerits=50000000%
+   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi%
 }
 
 \def\inlineextras at piedmontese{%
-   \lccode\string"2019=\string"2019
-   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi
+   \lccode\string"2019=\string"2019%
+   \ifpiedmontese at babelshorthands\piedmontese at shorthands\fi%
 }
 %%% CHANGES END %%%
 \endinput

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-portuguese.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-portuguese.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-portuguese.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -28,10 +28,8 @@
       % brazilian:
       \def\portuguese at variant{brazil}%
       \SetLanguageKeys{portuguese}{babelname=brazil,bcp47=pt-BR}%
-      \xpg at ifdefined{brazil}{}%
-	    {\xpg at warning{No hyphenation patterns were loaded for "Portuguese (Brazil)"\MessageBreak
-	      I will use the standard patterns for Portuguese instead}%
-	    \adddialect\l at brazil\l at portuges\relax}%
+      % There are no specific brazil patterns
+      \adddialect\l at brazil\l at portuges\relax%
    \fi
    \xpg at info{Option: portuguese, variant=\xpg at val}%
 }{\xpg at warning{Unknown portuguese variant `#1'}}

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-russian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-russian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-russian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -59,19 +59,26 @@
    \xpg at info{Option: Russian, numerals=\xpg at val}%
 }{\xpg at warning{Unknown Russian numerals value `#1'}}
 
-\define at boolkey{russian}[russian@]{indentfirst}[true]{
-   \ifrussian at indentfirst
-      \SetLanguageKeys{russian}{indentfirst=true}
-   \else
-      \SetLanguageKeys{russian}{indentfirst=false}
-  \fi
+\define at boolkey{russian}[russian@]{indentfirst}[true]{%
+  \ifrussian at indentfirst
+      \SetLanguageKeys{russian}{indentfirst=true}%
+  \else
+      \SetLanguageKeys{russian}{indentfirst=false}%
+  \fi%
 }
 
 \define at boolkey{russian}[russian@]{babelshorthands}[true]{}
 
+% Force punctuation after heading number
+\define at boolkey{russian}[russian@]{forceheadingpunctuation}[true]{}
 
+
 % Register default options
-\xpg at initialize@gloss at options{russian}{babelshorthands=false,spelling=modern,numerals=arabic,indentfirst=false}
+\xpg at initialize@gloss at options{russian}{babelshorthands=false,
+                                       spelling=modern,
+                                       numerals=arabic,
+                                       indentfirst=true,
+                                       forceheadingpunctuation=true}
 
 
 \ifsystem at babelshorthands
@@ -119,7 +126,7 @@
   \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 at shorthand{russian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -216,41 +223,48 @@
       \space \number\year\space г.}%
 }
 
-% The following is based on some ideas from ruscor.sty
+% Russian needs trailing dots in all headings
+\def\xpg at save@autodot{}
+\ifdef{\KOMAScript}{%
+    \let\xpg at save@autodot\autodot%
+}
+
 \def\russian at capsformat{%
+  \ifrussian at 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 at capsformat{%
+  \ifrussian at forceheadingpunctuation%
+    \ifdef{\KOMAScript}{%
+       \let\autodot\xpg at save@autodot%
+    }{%
+       \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
+    }%
+  \fi%
+}
+
 \newcommand{\russiannumerals}[2]{\russiannumber{#2}}
 \newcommand{\Russiannumerals}[2]{\Russiannumber{#2}}
 
@@ -323,24 +337,9 @@
 }
 
 \def\noextras at 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 at capsformat%
    \ifcyrillic at numerals\norussian at numbers\fi%
-   \norussian at shorthands%
+   \ifrussian at babelshorthands\norussian at shorthands\fi%
 }
 
 \def\blockextras at russian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-sanskrit.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-sanskrit.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-sanskrit.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,4 @@
 \ProvidesFile{gloss-sanskrit.ldf}[polyglossia: module for sanskrit]
-\ifluatex
-  \xpg at 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}
 

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-serbian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-serbian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-serbian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -14,7 +14,8 @@
   indentfirst=true,
   fontsetup=false,
   localnumeral=serbiannumerals,
-  Localnumeral=Serbiannumerals
+  Localnumeral=Serbiannumerals,
+  babelname=serbian
   %TODO localalph
 }
 
@@ -36,7 +37,7 @@
    \or
       % latin:
       \@serbian at cyrfalse
-      \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,bcp47=sr-Latn}
+      \SetLanguageKeys{serbian}{scripttag=latn,script=Latin,babelname=serbian,bcp47=sr-Latn}
       \xpg at fontsetup@latin{serbian}%
       %TODO \def\serbian at language{\language=\l at serbianlat}%
       % or should we use Croatian patterns as a fallback for the time being???

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-slovak.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-slovak.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-slovak.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -85,7 +85,7 @@
       \chardef\slovak at boundary=4095 %
       \def\newXeTeXintercharclass{%
         \e at alloc\XeTeXcharclass\chardef
-              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}
+              \xe at alloc@intercharclass\m at ne\@ucharclass at boundary}%
     \else
       \chardef\slovak at boundary=255
     \fi
@@ -114,6 +114,24 @@
 
 % 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 at nointerchartoks{\let\slovak at interchartoks\slovak at PreCSpreposition}%
+    \def\slovak at PreCSpreposition{%
+       \def\next{}%
+       \ifnum\catcode`\ =10 % nothing will be done in verbatim
+       \ifmmode % nothing in math
+       \else
+          \let\slovak at interchartoks\slovak at nointerchartoks
+          \let\next\slovak at ExamineCSpreposition
+       \fi\fi
+       \next%
+    }%
+    \def\slovak at ExamineCSpreposition #1{#1\futurelet\next\slovak at ProcessCSpreposition}%
+    \def\slovak at ProcessCSpreposition{\ifx\next\slovak at XeTeXspace\nobreak\fi}%
+    \futurelet\slovak at XeTeXspace{ }\slovak at nointerchartoks
+\fi
+
 \def\slovak at vlna{%
     \ifluatex
        \preventsingleon
@@ -140,21 +158,8 @@
         \XeTeXcharclass `\a \slovak at nonsyllabicpreposition
         \XeTeXcharclass `\I \slovak at nonsyllabicpreposition
         \XeTeXcharclass `\i \slovak at nonsyllabicpreposition
-        \XeTeXinterchartoks \slovak at boundary \slovak at nonsyllabicpreposition {\slovak at interchartoks}
-        \XeTeXinterchartoks \slovak at openpunctuation \slovak at nonsyllabicpreposition {\slovak at interchartoks}
-        \def\slovak at nointerchartoks{\let\slovak at interchartoks\slovak at PreCSpreposition}
-        \def\slovak at PreCSpreposition{\def\next{}%
-           \ifnum\catcode`\ =10 % nothing will be done in verbatim
-           \ifmmode % nothing in math
-           \else
-              \let\slovak at interchartoks\slovak at nointerchartoks
-              \let\next\slovak at ExamineCSpreposition
-           \fi \fi
-          \next%
-        }
-        \def\slovak at ExamineCSpreposition ##1{##1\futurelet\next\slovak at ProcessCSpreposition}
-        \def\slovak at ProcessCSpreposition{\ifx\next\slovak at XeTeXspace\nobreak\fi}
-        \futurelet\slovak at XeTeXspace{ }\slovak at nointerchartoks
+        \XeTeXinterchartoks \slovak at boundary \slovak at nonsyllabicpreposition {\slovak at interchartoks}%
+        \XeTeXinterchartoks \slovak at openpunctuation \slovak at nonsyllabicpreposition {\slovak at interchartoks}%
     \fi
 }
 
@@ -220,7 +225,7 @@
 }
 
 \def\noextras at slovak{%
-  \noslovak at shorthands%
+  \ifslovak at babelshorthands\noslovak at shorthands\fi%
   \noslovak at hyphens%
   \noslovak at vlna%
   \ifxetex\XeTeXinterchartokenstate=0\fi%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-syriac.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-syriac.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-syriac.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-syriac.ldf}[polyglossia: module for syriac]
-\ifluatex
-  \xpg at 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}
 

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-tamil.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-tamil.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-tamil.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-tamil.ldf}[polyglossia: module for tamil]
-\ifluatex
-  \xpg at 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}{

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-telugu.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-telugu.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-telugu.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,10 +1,5 @@
 \ProvidesFile{gloss-telugu.ldf}[polyglossia: module for telugu]
-\ifluatex
-  \xpg at warning{Telugu is not supported with LuaTeX.\MessageBreak
-I will proceed with the compilation, but\MessageBreak
-the output is not guaranteed to be correct\MessageBreak
-and may look very wrong.}
-\fi
+
 % Translations provided by Anmol Sharma <unmole.in at gmail.com>
 
 \PolyglossiaSetup{telugu}{

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-thai.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-thai.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-thai.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -8,12 +8,6 @@
 %%%%              Thai Linux Working Group
 %%%%              http://linux.thai.net/
 %%%%
-\ifluatex
-  \xpg at 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,

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-ukrainian.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-ukrainian.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-ukrainian.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -96,7 +96,7 @@
   \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 at shorthand{ukrainian}{",}{\nobreak\hskip.2em\ignorespaces}%
 }
@@ -174,7 +174,7 @@
 \def\ukrainiannumber#1{%
   \ifcyrillic at numerals
     \ifcyrillic at asbuk@numerals
-      \serbian at asbuk@alph{#1}%
+      \ukrainian at asbuk@alph{#1}%
     \else
       \cyr at alph{#1}%
     \fi
@@ -186,7 +186,7 @@
 \def\Ukrainiannumber#1{%
   \ifcyrillic at numerals
     \ifcyrillic at asbuk@numerals
-      \serbian at asbuk@Alph{#1}%
+      \ukrainian at asbuk@Alph{#1}%
     \else
       \cyr at Alph{#1}%
     \fi
@@ -206,25 +206,29 @@
 
 % This is a poor man's cyrillic alphanumeric. It just uses the alphabet and
 % thus ends at 30.
-\def\ukranian at asbuk@Alph#1{\ifcase#1\or
+\def\ukrainian at 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 at ill@value{#1}{ukranian at asbuk@Alph}\fi%
+   \else\xpg at ill@value{#1}{ukrainian at asbuk@Alph}\fi%
 }
 
-\def\ukranian at asbuk@alph#1{\ifcase#1\or
+\def\ukrainian at 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 at ill@value{#1}{ukranian at asbuk@alph}\fi%
+   \else\xpg at ill@value{#1}{ukrainian at asbuk@alph}\fi%
 }
 
 \def\ukrainian at numbers{%
-   \let\@Alph\ukrainian at Alph%
-   \let\@alph\ukrainian at alph%
+  \ifcyrillic at numerals
+     \def\ukrainian at alph##1{\expandafter\ukrainiannumeral\expandafter{\the##1}}%
+     \def\ukrainian at Alph##1{\expandafter\Ukrainiannumeral\expandafter{\the##1}}%
+     \let\@Alph\ukrainian at Alph%
+     \let\@alph\ukrainian at alph%
+  \fi
 }
 
 \def\noukrainian at numbers{%
@@ -235,13 +239,13 @@
 \def\noextras at ukrainian{%
   \def\@seccntformat##1{\csname the##1\endcsname\quad}% = LaTeX kernel
   \ifcyrillic at numerals\noukrainian at numbers\fi
-  \noukrainian at shorthands%
+  \ifukrainian at babelshorthands\noukrainian at shorthands\fi%
 }
 
 \def\blockextras at ukrainian{%
   \ukrainian at capsformat%
-  \ifcyrillic at numerals\ukrainian at numbers\fi
-  \ifukrainian at babelshorthands\ukrainian at shorthands\fi
+  \ifcyrillic at numerals\ukrainian at numbers\fi%
+  \ifukrainian at babelshorthands\ukrainian at shorthands\fi%
 }
 
 \def\inlineextras at ukrainian{%

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-urdu.ldf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-urdu.ldf	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/gloss-urdu.ldf	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,11 +1,6 @@
 %%% Adapted from a file contributed by Kamal Abdali
 \ProvidesFile{gloss-urdu.ldf}[polyglossia: module for Urdu]
-\ifluatex
-  \xpg at 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}

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia-punct.lua
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia-punct.lua	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia-punct.lua	2020-10-09 20:23:21 UTC (rev 56613)
@@ -93,21 +93,21 @@
 
 -- 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
@@ -233,9 +233,12 @@
         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
@@ -243,16 +246,16 @@
                         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
                         if leftspace.unit == "quad" then
                             unit = fontparameters.quad
@@ -280,11 +283,11 @@
                             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
                             unit = fontparameters.quad

Modified: trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia.sty	2020-10-09 20:22:33 UTC (rev 56612)
+++ trunk/Master/texmf-dist/tex/latex/polyglossia/polyglossia.sty	2020-10-09 20:23:21 UTC (rev 56613)
@@ -1,5 +1,5 @@
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{polyglossia}[2020/04/08 v1.49
+\ProvidesPackage{polyglossia}[2020/10/09 v1.50
   Modern multilingual typesetting with XeLaTeX and LuaLaTeX]
 \RequirePackage{etoolbox}
 \RequirePackage{makecmds}
@@ -6,12 +6,7 @@
 \RequirePackage{xkeyval}[2008/08/13]
 % Will raise error if used with anything else than XeTeX or LuaTeX
 \RequirePackage{fontspec}[2010/06/08]% v2.0
-% Ironically, ifluatex.sty is included by some other package if we run
-% LuaTeX, but it's not if we run XeTeX, and we need it to know which of
-% the two engines it is!  Hence we include it here.
-\RequirePackage{ifluatex}
-% For symmetry with ifluatex
-\RequirePackage{ifxetex}
+\RequirePackage{iftex}
 \RequirePackage{expl3}
 \RequirePackage{l3keys2e}
 \RequirePackage{xparse}
@@ -32,6 +27,7 @@
 \def\bbl at cs#1{\csname bbl@#1\endcsname}%
 \AtEndPreamble{\let\bbl at set@language\xpg at set@language at aux} %for biblatex
 \AtEndPreamble{\let\bbl at main@language\xpg at 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
@@ -1031,16 +1027,27 @@
 }
 
 \newcommand{\xpg at input}[1]{%
-  \chardef\xpg at atcatcode\catcode`\@
+  % Store catcode of @ before making at letter
+  \chardef\xpg at saved@at at catcode\catcode`\@
   \makeatletter
-  \input{#1}\catcode`\@=\xpg at atcatcode}
+  \input{#1}%
+  % restore former @ catcode
+  \catcode`\@=\xpg at saved@at 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 at restore@tilde at catcode{\catcode 126 = \the\catcode 126\relax}
+    \catcode 126 = 13
     \xpg at input{gloss-#2.ldf}
     \setkeys{#2}{#1}
+    % restore former ~ catcode
+    \xpg at restore@tilde at catcode
   }
   {
     \xpg at nogloss{#2}
@@ -1054,8 +1061,8 @@
    {
      \exp_args:Nx\polyglossia at define@language at cmd:n{#1}%
    }{}
-   \csgdef{#1 at loaded}{}
-   \global\edef\xpg at loaded{#1\ifx\xpg at loaded\@empty\else,\xpg at loaded\fi}%
+   \polyglossia at register@language:nn{}{#1}%
+   \csgdef{#1 at loaded}{}%
 }
 
 
@@ -1116,17 +1123,38 @@
   \tl_if_blank:nF {#2} {\csgdef{#4 at alias@opts}{#2}}%
 }
 
+\cs_new:Nn \polyglossia at register@language:nn {
+   % register polyglossia language name
+   \ifcsundef{#2 at registered}{%
+       \global\edef\xpg at loaded{%
+           \ifx\xpg at loaded\@empty\else\xpg at loaded,\fi #2%
+        }%
+   }{}
+   \csgdef{#2 at registered}{}%
+   \tl_if_blank:nF {#1}{%
+      % Register the language options
+      \polyglossia at set@lang at options:nn {#2} {#1}%
+   }%
+   % register babelname
+   \def\xpg at tmp@babelname{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}}%
+   \ifcsundef{\csname xpg at tmp@babelname\endcsname @bbl at registered}{%
+       \global\edef\xpg at bloaded{%
+           \ifx\xpg at bloaded\@empty\else\xpg at bloaded,\fi\xpg at tmp@babelname}%
+   }{}%
+   \csgdef{\csname xpg at tmp@babelname\endcsname @bbl at registered}{}%
+   % register BCP-47 ID
+   \def\xpg at tmp@bcpname{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+   \ifcsundef{\csname xpg at tmp@bcpname\endcsname @bcp at registered}{%
+       \global\edef\xpg at bcp@loaded{%
+           \ifx\xpg at bcp@loaded\@empty\else\xpg at bcp@loaded,\fi\xpg at tmp@bcpname}%
+   }{}%
+   \csgdef{\csname xpg at tmp@bcpname\endcsname @bcp at registered}{}%
+}
+
+
 \newcommand{\setdefaultlanguage}[2][]{%
   \ifcsundef{#2 at loaded}%
   {
-    % latex is an internal language, so do not record
-    \ifstrequal{#2}{latex}{}{%
-      \global\edef\xpg at loaded{#2\ifx\xpg at loaded\@empty\else,\xpg at loaded\fi}%
-      \global\edef\xpg at bloaded{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}%
-          \ifx\xpg at bloaded\@empty\else,\xpg at bloaded\fi}%
-      \global\edef\xpg at bcp@loaded{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}%
-          \ifx\xpg at bcp@loaded\@empty\else,\xpg at bcp@loaded\fi}%
-    }%
     \polyglossia_load_lang_definition:nn{#1}{#2}
     % define environment and command (except for internal latex language)
     \ifstrequal{#2}{latex}{}{%
@@ -1151,18 +1179,6 @@
 
 \cs_new:Nn \polyglossia at set@default at language:nn
 {
-  \ifcsundef{#2 at loaded}%
-  {
-    % latex is an internal language, so do not record
-    \ifstrequal{#2}{latex}{}{%
-      \global\edef\xpg at loaded{#2\ifx\xpg at loaded\@empty\else,\xpg at loaded\fi}%
-      \global\edef\xpg at bloaded{\prop_item:Nn{\polyglossia at langsetup}{#2/babelname}%
-          \ifx\xpg at bloaded\@empty\else,\xpg at bloaded\fi}%
-      \global\edef\xpg at bcp@loaded{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}%
-          \ifx\xpg at bcp@loaded\@empty\else,\xpg at bcp@loaded\fi}%
-    }%
-    \csgdef{#2 at loaded}{}%
-  }{}
   \gdef\xpg at main@language{#2}%
   \tl_if_blank:nTF {#1}{\gdef\mainlanguagevariant{}}{%
      % Register the language options
@@ -1393,9 +1409,9 @@
       \else\csuse at warn{#1 at font@rm}\fi\fi}
 
 \def\xpg at set@normalfont#1{%
-  \letcs{\rmfamily}{#1 at font@rm}%
-  \letcs{\sffamily}{#1 at font@sf}%
-  \letcs{\ttfamily}{#1 at font@tt}%
+  \DeclareRobustCommand\rmfamily{\csuse{#1 at font@rm}}%
+  \DeclareRobustCommand\sffamily{\csuse{#1 at font@sf}}%
+  \DeclareRobustCommand\ttfamily{\csuse{#1 at font@tt}}%
   \gdef\normalfont{\protect\xpg at select@fontfamily{#1}%
                      \fontseries{\seriesdefault}\selectfont%
                      \fontshape{\shapedefault}\selectfont}%
@@ -1431,11 +1447,9 @@
 \newcommand{\setotherlanguage}[2][]{%
   \ifcsundef{#2 at loaded}
   {
-    \global\edef\xpg at loaded{#2\ifx\xpg at loaded\@empty\else,\xpg at loaded\fi}%
     \polyglossia_load_lang_definition:nn{#1}{#2}
     % define environment and command
     \exp_args:Nx\polyglossia at define@language at cmd:n{#2}
-    \csgdef{#2 at loaded}{}%
     \ifcsdef{#2 at alias@lang}{%
        \ifcsdef{#2 at alias@opts}{%
          \exp_args:Nxx \polyglossia_load_lang_definition:nn {\csuse{#2 at alias@opts},#1} {\csuse{#2 at alias@lang}}%
@@ -1446,6 +1460,7 @@
     }{%
       \polyglossia at set@other at language:nn {#1} {#2}%
     }%
+    \csgdef{#2 at loaded}{}%
   }
   {}
 }
@@ -1452,11 +1467,7 @@
 
 \cs_new:Nn \polyglossia at set@other at language:nn
 {
-  \ifcsundef{#2 at loaded}
-  {
-    \global\edef\xpg at loaded{#2\ifx\xpg at loaded\@empty\else,\xpg at loaded\fi}%
-    \csgdef{#2 at loaded}{}%
-  }{}
+  \polyglossia at register@language:nn{#1}{#2}%
   % If a variant is set, store it.
   \gdef\otherlanguagevariant{}
   \tl_if_blank:nTF {#1}{}{%
@@ -1523,6 +1534,7 @@
 % wrapper for foreignlanguage and otherlanguage*
 \newcommand*\polyglossia at setforeignlanguage[2][]{
   \select@@language[#1]{#2}
+  \polyglossia at register@language:nn{#1}{#2}%
   % Store babelname of current language (for external packages such as biblatex)
   \tl_if_blank:nTF {#1}{%
     \ifcsundef{#2 at gbabelname}{%
@@ -1678,14 +1690,7 @@
      \directlua{polyglossia.select_language('\luatexluaescapestring{\string#3}',
                      \the\csname l@#3\endcsname)}%
    \fi%
-  \def\xpg at tmp@babelname{\prop_item:Nn{\polyglossia at langsetup}{#3/babelname}}
-  % Store babelname in \xpg at bloaded csv list
-  \ifcsundef{\csname xpg at tmp@babelname\endcsname @bbl at loaded}
-  {
-    \global\edef\xpg at bloaded{\xpg at tmp@babelname%
-          \ifx\xpg at bloaded\@empty\else,\xpg at bloaded\fi}%
-    \csgdef{\csname xpg at tmp@babelname\endcsname @bbl at loaded}{}%
-  }{}
+  \polyglossia at register@language:nn{#2}{#3}%
 }
 
 
@@ -1876,14 +1881,6 @@
    }{%
      \csedef{bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
    }%
-  % Store bcp47 in \xpg at bcp@loaded csv list
-  \def\xpg at tmp@bcpname{\csuse{bcp47id}}%
-  \ifcsundef{\csname xpg at tmp@bcpname\endcsname @bcp at loaded}
-  {
-    \global\edef\xpg at bcp@loaded{\xpg at tmp@bcpname%
-          \ifx\xpg at bcp@loaded\@empty\else,\xpg at bcp@loaded\fi}%
-    \csgdef{\csname xpg at tmp@bcpname\endcsname @bcp at loaded}{}%
-  }{}
    \@select at language[#1]{#2}%
     % Write to the aux
    \if at filesw%
@@ -2039,7 +2036,7 @@
    \cs_if_exist_use:c{date at bbl@\babelname}%
    \polyglossia at local@marks:n{#2}%
    \csuse{init at extras@#2}%
-   \polyglossia at lang@indentfirst:n{#2}
+   \polyglossia at lang@indentfirst:n{#2}%
    \csuse{blockextras@#2}%
    % This is a hook for external packages which want to access variants
    % via babelname (such as biblatex)
@@ -2087,7 +2084,7 @@
   \xpg at select@fontfamily{#2}%
   \csuse at warn{#2 at language}%
   \csuse{#2 at numbers}%
-  \use at localhyphenmins{#2}%
+  \use at localhyphenmins[#1]{#2}%
   \polyglossia at lang@frenchspacing:n{#2}
 }
 
@@ -2124,14 +2121,66 @@
       \fi
    }{%
      \xpg at warning{\string\setlocalhyphenmin\space~ useless~ for~ unknown~ language~ #1}%
-   }}%
+   }%
+}%
 
-\def\use at localhyphenmins#1{%
-   \ifcsundef{#1hyphenmins}{}%
-   {\expandafter\expandafter\expandafter\set at hyphenmins\csname #1hyphenmins\endcsname\relax}
+% \setlanghyphenmins[options]{lang}{l}{r}
+\newcommand*\setlanghyphenmins[4][]{%
+  % Check for real language name and options
+  \edef\xpg at tmp@lang{#2}%
+  \edef\xpg at tmp@opts{#1}%
+  \ifcsdef{#2 at alias@lang}{%
+     \edef\xpg at tmp@lang{\csuse{#2 at alias@lang}}%
+     \ifcsdef{#2 at alias@opts}{%
+       \edef\xpg at tmp@opts{\csuse{#2 at alias@opts},#1}%
+     }{}%
+  }{}%
+  \bgroup
+  \polyglossia at error@iflangnotloaded:n{\xpg at tmp@lang}
+  \exp_args:Nne \setkeys{\xpg at tmp@lang}{\xpg at tmp@opts}%
+  % Store BCP-47 id of language
+  \tl_if_blank:nTF {\xpg at tmp@opts}{%
+    \ifcsundef{\csname xpg at tmp@lang\endcsname @gbcp47id}{%
+       \csedef{tmp at bcp47id}{\exp_args:Nne\prop_item:Nn{\polyglossia at langsetup}{\xpg at tmp@lang /bcp47}}%
+    }{%
+       \csedef{tmp at bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csedef{tmp at bcp47id}{\exp_args:Nne \prop_item:Nn{\polyglossia at langsetup}{\xpg at tmp@lang /bcp47}}%
+  }%
+  \xpg at warning{id: \csuse{tmp at bcp47id}}%
+  \csgdef{\csname tmp at bcp47id\endcsname @hyphenmins}{{#3}{#4}}%
+  \egroup
+}
+
+% \use at localhypenmins[options]{lang}
+\newcommand*\use at localhyphenmins[2][]{%
+  \bgroup
+  \polyglossia at error@iflangnotloaded:n{#2}
+  \setkeys{#2}{#1}%
+  % Store BCP-47 id of language
+  \tl_if_blank:nTF {#1}{%
+    \ifcsundef{#2 at gbcp47id}{%
+       \csxdef{tmp at bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+    }{%
+       \csxdef{tmp at bcp47id}{\csuse{#2 at gbcp47id}}%
+    }%
+  }{%
+    \csxdef{tmp at bcp47id}{\prop_item:Nn{\polyglossia at langsetup}{#2/bcp47}}%
+  }%
+  \egroup
+  \ifcsundef{\csname tmp at bcp47id\endcsname @hyphenmins}{%
+     \ifcsundef{#2hyphenmins}{}%
+        {%
+          \expandafter\expandafter\expandafter\set at hyphenmins\csname #2hyphenmins\endcsname\relax%
+        }
+   }{%
+      \edef\tmpa{\csuse{\csname tmp at bcp47id\endcsname @hyphenmins}}%
+      \expandafter\expandafter\expandafter\set at hyphenmins\tmpa\relax%
+   }
    \ifluatex
      % Set \totalhyphenmin if specified
-     \prop_get:NxNTF \polyglossia at langsetup {#1/totalhyphenmin} \l_tmpa_tl
+     \prop_get:NxNTF \polyglossia at langsetup {#2/totalhyphenmin} \l_tmpa_tl
      {
         \xpg at warning{totalhyphenmin: '\l_tmpa_tl'}
         \expandafter\hyphenationmin \l_tmpa_tl%
@@ -2140,6 +2189,47 @@
    \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 at langsetup}{\languagename/direction}}{RL}%
+       {%
+        \str_if_eq:eeTF{\prop_item:Nn{\polyglossia at langsetup}{#1/direction}}{RL}%
+           {}% RTL -> RTL
+           {\ifvmode\else\booltrue{xpg at noset@groups}\fi}% RTL -> LTR
+       }%
+  \fi%
+  \ifbool{xpg at noset@groups}{}{\xpg at set@group at aux}%
+  % Check for real language name and options
+  \edef\xpg at tmp@lang{#2}%
+  \edef\xpg at tmp@opts{#1}%
+  \ifcsdef{#2 at alias@lang}{%
+     \edef\xpg at tmp@lang{\csuse{#2 at alias@lang}}%
+     \ifcsdef{#2 at alias@opts}{%
+       \edef\xpg at tmp@opts{\csuse{#2 at alias@opts},#1}%
+     }{}%
+  }{}%
+  \tl_if_blank:nF {\xpg at tmp@opts}{%
+     % Register the language options
+     \polyglossia at set@lang at options:nn {\xpg at tmp@lang} {\xpg at tmp@opts}%
+  }%
+  % Now switch patterns
+  \csuse at warn{\csuse{xpg at tmp@lang}@language}%
+  % And activate hyphenmins
+  \use at localhyphenmins[\xpg at tmp@opts]{\xpg at tmp@lang}%
+}
+{\ifbool{xpg at noset@groups}{}{\xpg at unset@group at aux}}
+
 \AtEndPreamble{%
    \@ifpackageloaded{bidi}{%
       \providecommand*{\aemph}[1]{$\overline{\hboxR{#1}}$}%
@@ -2172,6 +2262,11 @@
      .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 } {
@@ -2178,6 +2273,7 @@
   localmarks = false,
   verbose = true,
   babelshorthands = false,
+  luatexrenderer = Harfbuzz
 }
 
 % load by default latex
@@ -2185,6 +2281,16 @@
 % 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 at 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 at info#1{\relax}% no latex info
    \gdef\@font at info#1{\relax}% no latex font info



More information about the tex-live-commits mailing list.