From a50631c54fcd57d69c71325208f42b3da94d98a1 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Thu, 14 May 2020 03:02:48 +0000
Subject: CTAN sync 202005140302

---
 macros/latex/required/babel/base/babel.dtx | 1366 +++++++++++++++++-----------
 1 file changed, 845 insertions(+), 521 deletions(-)

(limited to 'macros/latex/required/babel/base/babel.dtx')

diff --git a/macros/latex/required/babel/base/babel.dtx b/macros/latex/required/babel/base/babel.dtx
index ed38c3b139..8da203640c 100644
--- a/macros/latex/required/babel/base/babel.dtx
+++ b/macros/latex/required/babel/base/babel.dtx
@@ -31,7 +31,7 @@
 %
 % \iffalse
 %<*filedriver>
-\ProvidesFile{babel.dtx}[2020/04/28 v3.43 The Babel package]
+\ProvidesFile{babel.dtx}[2020/05/13 v3.44 The Babel package]
 \documentclass{ltxdoc}
 \GetFileInfo{babel.dtx}
 \usepackage{fontspec}
@@ -390,6 +390,15 @@ Package babel Warning: No hyphenation patterns were preloaded for
   it.
 \end{troubleshooting}
 
+\begin{note}
+  With \textsf{hyperref} you may want to set the document language with
+  something like:
+\begin{verbatim}
+\usepackage[_pdflang=es-MX_]{hyperref}
+\end{verbatim}
+This is not currently done by \babel{} and you must set it by hand.
+\end{note}
+
 \subsection{Multilingual documents}
 
 In multilingual documents, just use a list of the required languages as
@@ -640,18 +649,31 @@ This command can be used as environment, too.
   code with an additional grouping level.
 \end{warning}
 
-\Describe{\foreignlanguage}{\marg{language}\marg{text}}
-The command |\foreignlanguage| takes two arguments; the second
-argument is a phrase to be typeset according to the rules of the
-language named in its first one. This command (1) only switches the
-extra definitions and the hyphenation rules for the language,
-\emph{not} the names and dates, (2) does not send information about
-the language to auxiliary files (i.e., the surrounding language is
-still in force), and (3) it works even if the language has not been
-set as package option (but in such a case it only sets the hyphenation
-patterns and a warning is shown). With the |bidi| option, it also 
-enters in horizontal mode (this is not done always for backwards 
-compatibility).
+\Describe{\foreignlanguage}{\oarg{option-list}\marg{language}\marg{text}}
+
+The command |\foreignlanguage| takes two arguments; the second argument
+is a phrase to be typeset according to the rules of the language named
+in its first one.
+
+This command (1) only switches the extra definitions and the
+hyphenation rules for the language, \emph{not} the names and dates, (2)
+does not send information about the language to auxiliary files (i.e.,
+the surrounding language is still in force), and (3) it works even if
+the language has not been set as package option (but in such a case it
+only sets the hyphenation patterns and a warning is shown). With the
+|bidi| option, it also enters in horizontal mode (this is not done
+always for backwards compatibility).
+
+\New{3.44} As already said, captions and dates are not switched.
+However, with the optional argument you can switch them, too. So, you
+can write:
+\begin{verbatim}
+\foreignlanguage[date]{polish}{\today}
+\end{verbatim}
+In addition, captions can be switched with |captions| (or both, of
+course, with |date, captions|). Until 3.43 you had to write something
+like |{\selectlanguage{..} ..}|, which was not always the most
+convenient way.
 
 \subsection{Auxiliary language selectors}
 
@@ -676,7 +698,7 @@ environment with an additional grouping, like braces |{}|.
 Spaces after the environment are ignored.
 
 \Describe{\begin\menv{otherlanguage*}}%
-{\marg{language}\Eenv{otherlanguage*}}
+{\oarg{option-list}\marg{language}\Eenv{otherlanguage*}}
 
 Same as |\foreignlanguage| but as environment. Spaces after the
 environment are \textit{not} ignored.
@@ -955,7 +977,7 @@ with, for example, |\useshorthands| or |\useshorthands*|.)
   than |\shorthandoff|, for example if you want to define a macro
   to easy typing phonetic characters with \textsf{tipa}:
 \begin{verbatim}
-\newcommand{\myipa}[1]{{\languageshorthands{none}\tipaencoding#1}}
+\newcommand{\myipa}[1]{{_\languageshorthands{none}_\tipaencoding#1}}
 \end{verbatim}
 \end{example}
 
@@ -973,7 +995,7 @@ macros, or even your own user shorthands provided they do not overlap.)
   |\begin{document}|, you may use this macro when defining the |\title|
   in the preamble:
 \begin{verbatim}
-\title{Documento científico\babelshorthand{"-}técnico}
+\title{Documento científico_\babelshorthand{"-}_técnico}
 \end{verbatim}
 \end{example}
 
@@ -1070,7 +1092,7 @@ $\string|$ \texttt{off}}
 The only language shorthands activated
 are those given, like, eg:
 \begin{verbatim}
-\usepackage[esperanto,french,shorthands=:;!?]{babel}
+\usepackage[esperanto,french,_shorthands=:;!?_]{babel}
 \end{verbatim}
 If \verb|'| is included, \texttt{activeacute} is set; if \verb|`| is
 included, \texttt{activegrave} is set.  Active characters (like
@@ -1265,7 +1287,7 @@ for auxiliary tasks.
 \documentclass{book}
 
 \usepackage{babel}
-\babelprovide[import, main]{georgian}
+_\babelprovide[import, main]{georgian}_
 
 \babelfont{rm}{DejaVu Sans}
 
@@ -1411,6 +1433,7 @@ captions):
 \tag{ebu} Embu
 \tag{ee} Ewe
 \tag{el} Greek\hascapu\hascapl
+\tag{el-polyton} Polytonic Greek\hascapu\hascapl
 \tag{en-AU} English\hascapu\hascapl
 \tag{en-CA} English\hascapu\hascapl
 \tag{en-GB} English\hascapu\hascapl
@@ -1438,6 +1461,7 @@ captions):
 \tag{ga} Irish\hascapu\hascapl
 \tag{gd} Scottish Gaelic\hascapu\hascapl
 \tag{gl} Galician\hascapu\hascapl
+\tag{grc} Ancient Greek\hascapu\hascapl
 \tag{gsw} Swiss German
 \tag{gu} Gujarati
 \tag{guz} Gusii
@@ -1639,6 +1663,7 @@ akan\\
 albanian\\
 american\\
 amharic\\
+ancientgreek\\
 arabic\\
 arabic-algeria\\
 arabic-DZ\\
@@ -1848,6 +1873,7 @@ pashto\\
 persian\\
 piedmontese\\
 polish\\
+polytonicgreek\\
 portuguese-br\\
 portuguese-brazil\\
 portuguese-portugal\\
@@ -2198,6 +2224,13 @@ As of 3.15, there is no need to hide spaces with \texttt{\%%
 \end{verbatim}
 There is a counterpart for code to be run when a language is
 unselected: |\noextras|\m{lang}.
+\item With data |import|’ed from |ini| files, you can modify the values
+of specific keys, like:
+\begin{verbatim}
+\babelprovide[import, _captions/listtable = Lista de tablas_]{spanish}
+\end{verbatim}
+(In this particular case, instead of the |captions| group you may need
+to modify the |captions.licr| one.)
 \end{itemize}
 
 \begin{note} Do \textit{not} redefine a caption in the following way:
@@ -2315,7 +2348,9 @@ format (\textsf{french}, \textsf{breton}, and \textsf{occitan}).
 Besides |\today|, this option defines an additional command for dates:
 |\<language>date|, which takes three arguments, namely, year, month and
 day numbers. In fact, |\today| calls |\<language>today|, which in turn
-calls |\<language>date{\the\year}{\the\month}{\the\day}|.
+calls |\<language>date{\the\year}{\the\month}{\the\day}|. \New{3.44}
+More convenient is usually |\localedate|, with prints the date for the
+current locale.
 
 \Describe{captions=}{\meta{language-tag}}
 Loads only the strings. For example:
@@ -2610,13 +2645,29 @@ loaded (and therefore the corresponding data) even if these two
 conditions are not met, write |\BabelEnsureInfo| in the preamble.
 \end{note}
 
+\Describe{\localeid}{}
+
+Each language in the \babel{} sense has its own unique numeric
+identifier, which can be retrieved with |\localeid|.
+
+\begin{note}
+  The |\localeid| is not the same as the |\language| identifier, which
+  refers to a set of hyphenation patters (which, in turn, is just a
+  component of the line breaking algorithm described in the next
+  section). The data about preloaded patterns are store in an internal
+  macro named |\bbl@languages| (see the code for further details), but
+  note several locales may share a single |\language|, so they are
+  separated concepts. In \luatex, the |\localeid| is saved in each node
+  (where it makes sense) as an attribute, too.
+\end{note}
+
 \subsection{Hyphenation and line breaking}
 
 \Babel{} deals with three kinds of line breaking rules: Western,
 typically the LGC group, South East Asian, like Thai, and CJK, but
 support depends on the engine: \textsf{pdftex} only deals with the
-former, \xetex{} also with the second one, while \luatex{} provides
-basic rules for the latter, too.
+former, \xetex{} also with the second one (although in a limited way),
+while \luatex{} provides basic rules for the latter, too.
 
 \Describe{\babelhyphen}{%
   \colorbox{thegrey}{\ttfamily\hskip-.2em*\hskip-.2em}\marg{type}}
@@ -2743,7 +2794,7 @@ of the previous char in \luatex, and the font size set by the last
 \Describe{\babelposthyphenation}{\marg{hyphenrules-name}%
           \marg{lua-pattern}\marg{replacement}}
 
-\New{3.37-3.39} With \luatex{} it is now possible to define
+\New{3.37-3.39} \textit{With \luatex{}} it is now possible to define
 non-standard hyphenation rules, like |f-f| $\to$ |ff-f|, repeated
 hyphens, ranked ruled (or more precisely, ‘penalized’ hyphenation
 points), and so on. No rules are currently provided by default, but
@@ -2793,7 +2844,7 @@ additional replacement type with the key |string|.
 
 \New{3.43} The recommended way to select languages is that described at
 the beginning of this document. However, BCP 47 tags are becoming
-customary, particularly in document (or parts of documents) generated
+customary, particularly in documents (or parts of documents) generated
 by external sources, and therefore \babel{} will provide a set of tools
 to select the locales in different situations, adapted to the
 particular needs of each case. Currently, \babel{} provides autoloading
@@ -2844,7 +2895,7 @@ The behaviour is adjusted with |\babeladjust| with the following parameters:
 \item \texttt{autoload.bcp47.options}, which are passed to
   |\babelprovide|; empty by default, but you may add \texttt{import}
   (features defined in the corresponding |babel-...tex| file might not
-  available).
+  be available).
 \item \texttt{autoload.bcp47.prefix}. Although the public name used in
   selectors is the tag, the internal name will be different and
   generated by prepending a prefix, which by default is
@@ -3371,19 +3422,19 @@ the current options may be different. It does not include |ini| files.
 \item[Greek] greek, polutonikogreek
 \item[Hebrew] hebrew
 \item[Icelandic] icelandic
-\item[Indonesian] indonesian, bahasa, indon, bahasai
+\item[Indonesian] indonesian (bahasa, indon, bahasai)
 \item[Interlingua] interlingua
 \item[Irish Gaelic] irish
 \item[Italian] italian
 \item[Latin] latin
 \item[Lower Sorbian] lowersorbian
-\item[Malay] malay, melayu, bahasam
+\item[Malay] malay, melayu (bahasam)
 \item[North Sami] samin
 \item[Norwegian] norsk, nynorsk
 \item[Polish] polish
-\item[Portuguese] portuguese, portuges\footnote{This name comes from
-  the times when they had to be shortened to 8 characters}, brazilian,
-  brazil
+\item[Portuguese] portuguese, brazilian (portuges, brazil)\footnote{The
+two last name comes from the times when they had to be shortened to 8
+characters}
 \item[Romanian] romanian
 \item[Russian] russian
 \item[Scottish Gaelic] scottish
@@ -3588,28 +3639,27 @@ for a small example (|xe-bidi|).
 See the code section for |\foreignlanguage*| (a new starred
 version of |\foreignlanguage|).
 
+For old an deprecated functions, see the wiki.
+
 \medskip
-\textbf{Old and deprecated stuff}
+\textbf{\string\babelprehyphenation}
 
-A couple of tentative macros were provided by \babel{} ($\ge$3.9g) with
-a partial solution for ``Unicode'' fonts. These macros are now
-deprecated --- use |\babelfont|. A short description follows, for
-reference:
-\begin{itemize}
-\item |\babelFSstore|\marg{babel-language} sets the current three
-  basic families (rm, sf, tt) as the default for the language
-  given.
-\item |\babelFSdefault|\marg{babel-language}\marg{fontspec-features}
-  patches |\fontspec| so that the given features are always passed as
-  the optional argument or added to it (not an ideal solution).
-\end{itemize}
-So, for example:
-\begin{verbatim}
-\setmainfont[Language=Turkish]{Minion Pro}
-\babelFSstore{turkish}
-\setmainfont{Minion Pro}
-\babelFSfeatures{turkish}{Language=Turkish}
-\end{verbatim}
+\New{3.44} Note it is tentative, but the current behavior for glyphs
+should be correct.
+
+It is similar to |\babelposthyphenation|, but (as its name implies)
+applied before hyphenation. There are other differences: (1) the first
+argument is the locale instead the name of hyphenation patterns; (2) in
+the search patterns |=| has no special meaning (\verb+|+ is still
+reserved, but currently unused); (3) in the replacement,
+discretionaries are not accepted, only remove, {}, and string = ...
+
+Currently it handles glyphs, not discretionaries or spaces (in
+particular, it will not catch the hyphen and you can't insert or remove
+spaces). Also, you are limited to substitutions as done by lua,
+although a future implementation may alternatively accept lpeg.
+
+Performance is still somewhat poor.
 
 \section{Loading languages with \file{language.dat}}
 
@@ -4458,24 +4508,24 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \section{Identification and loading of required files}
 %
-%    \textit{Code documentation is still under revision.}
-%
-%  \textbf{The following description is no longer valid, because switch
-%  and plain have been merged into babel.def.}
-%
-%    The \babel{} package after unpacking consists of the following files:
-%    \begin{description}
-%    \itemsep=-\parskip
-%    \item[switch.def] defines macros to set and switch languages.
-%    \item[babel.def] defines the rest of macros. It has tow parts: a
-%    generic one and a second one only for LaTeX{}.
-%    \item[babel.sty] is the \LaTeX{} package, which set options and
-%    load language styles.
-%  \item[plain.def] defines some \LaTeX{} macros required by
-%    \file{babel.def} and provides a few tools for Plain.
-%   \item[hyphen.cfg] is the file to be used when generating the
-%    formats to load hyphenation patterns.
-%    \end{description}
+% \textit{Code documentation is still under revision.}
+%
+% \textbf{The following description is no longer valid, because switch
+% and plain have been merged into babel.def.}
+%
+% The \babel{} package after unpacking consists of the following files:
+% \begin{description}
+% \itemsep=-\parskip
+% \item[switch.def] defines macros to set and switch languages.
+% \item[babel.def] defines the rest of macros. It has tow parts: a
+%   generic one and a second one only for LaTeX{}.
+% \item[babel.sty] is the \LaTeX{} package, which set options and
+%   load language styles.
+% \item[plain.def] defines some \LaTeX{} macros required by
+%   \file{babel.def} and provides a few tools for Plain.
+% \item[hyphen.cfg] is the file to be used when generating the
+%   formats to load hyphenation patterns.
+% \end{description}
 %
 % The \babel{} installer extends \textsf{docstrip} with a few
 % ``pseudo-guards'' to set ``variables'' used at installation time.
@@ -4522,16 +4572,17 @@ help from Bernd Raichle, for which I am grateful.
 %
 % Keys may be further qualified in a particular language with a suffix
 % starting with a uppercase letter. It can be just a letter (eg,
-% babel.name.A, babel.name.B) or a name (eg, date.long.Nominative,
-% date.long.Formal, but no language is currently using the latter).
-% Multi-letter qualifiers are forward compatible in the sense they
-% won’t conflict with new ``global'' keys (all lowercase).
+% |babel.name.A|, |babel.name.B|) or a name (eg,
+% |date.long.Nominative|, |date.long.Formal|, but no language is
+% currently using the latter). \textit{Multi-letter} qualifiers are
+% forward compatible in the sense they won’t conflict with new
+% ``global'' keys (which start always with a lowercase case).
 %
 % \section{Tools}
 %
 %    \begin{macrocode}
-%<<version=3.43>>
-%<<date=2020/04/28>>
+%<<version=3.44>>
+%<<date=2020/05/13>>
 %    \end{macrocode}
 %
 % \textbf{Do not use the following macros in \texttt{ldf} files. They
@@ -4539,13 +4590,13 @@ help from Bernd Raichle, for which I am grateful.
 % added for replacing, trimming and looping. The older ones, like
 % |\bbl@afterfi|, will not change.
 %
-%    We define some basic macros which just make the code cleaner.
-%    |\bbl@add| is now used internally instead of |\addto| because of
-%    the unpredictable behavior of the latter. Used in
-%    \file{babel.def} and in \file{babel.sty}, which means in \LaTeX{}
-%    is executed twice, but we need them when defining options and
-%    \file{babel.def} cannot be load until options have been defined.
-%    This does not hurt, but should be fixed somehow.
+% We define some basic macros which just make the code cleaner.
+% |\bbl@add| is now used internally instead of |\addto| because of
+% the unpredictable behavior of the latter. Used in
+% \file{babel.def} and in \file{babel.sty}, which means in \LaTeX{}
+% is executed twice, but we need them when defining options and
+% \file{babel.def} cannot be load until options have been defined.
+% This does not hurt, but should be fixed somehow.
 %
 %    \begin{macrocode}
 %<<*Basic macros>>
@@ -4832,13 +4883,14 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsection{Multiple languages}
 %
-%  \begin{macro}{\language}
-%    Plain \TeX\ version~3.0 provides the primitive |\language| that
-%    is used to store the current language. When used with a pre-3.0
-%    version this function has to be implemented by allocating a
-%    counter. The following block is used in \file{switch.def} and
-%    \file{hyphen.cfg}; the latter may seem redundant, but remember
-%    \babel{} doesn't requires loading \file{switch.def} in the format.
+% \begin{macro}{\language}
+%
+% Plain \TeX\ version~3.0 provides the primitive |\language| that
+% is used to store the current language. When used with a pre-3.0
+% version this function has to be implemented by allocating a
+% counter. The following block is used in \file{switch.def} and
+% \file{hyphen.cfg}; the latter may seem redundant, but remember
+% \babel{} doesn't requires loading \file{switch.def} in the format.
 %
 %    \begin{macrocode}
 %<<*Define core switching macros>>
@@ -4848,28 +4900,29 @@ help from Bernd Raichle, for which I am grateful.
 %<</Define core switching macros>>
 %    \end{macrocode}
 %
-%  \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\last@language}
 %
-%  \begin{macro}{\last@language}
-%    Another counter is used to store the last language defined.  For
-%    pre-3.0 formats an extra counter has to be allocated.
+% Another counter is used to store the last language defined.  For
+% pre-3.0 formats an extra counter has to be allocated.
 %
-%  \begin{macro}{\addlanguage}
+% \begin{macro}{\addlanguage}
 %
-%    To add languages to \TeX's memory plain \TeX\ version~3.0
-%    supplies |\newlanguage|, in a pre-3.0 environment a similar macro
-%    has to be provided. For both cases a new macro is defined here,
-%    because the original |\newlanguage| was defined to be |\outer|.
+% To add languages to \TeX's memory plain \TeX\ version~3.0
+% supplies |\newlanguage|, in a pre-3.0 environment a similar macro
+% has to be provided. For both cases a new macro is defined here,
+% because the original |\newlanguage| was defined to be |\outer|.
 %
-%    For a format based on plain version~2.x, the definition of
-%    |\newlanguage| can not be copied because |\count 19| is used for
-%    other purposes in these formats. Therefore |\addlanguage| is
-%    defined using a definition based on the macros used to define
-%    |\newlanguage| in plain \TeX\ version~3.0.
+% For a format based on plain version~2.x, the definition of
+% |\newlanguage| can not be copied because |\count 19| is used for
+% other purposes in these formats. Therefore |\addlanguage| is
+% defined using a definition based on the macros used to define
+% |\newlanguage| in plain \TeX\ version~3.0.
 %
-%    For formats based on plain version~3.0 the definition of
-%    |\newlanguage| can be simply copied, removing |\outer|.
-%    Plain \TeX\ version 3.0 uses |\count 19| for this purpose.
+% For formats based on plain version~3.0 the definition of
+% |\newlanguage| can be simply copied, removing |\outer|.
+% Plain \TeX\ version 3.0 uses |\count 19| for this purpose.
 %
 %    \begin{macrocode}
 %<<*Define core switching macros>>
@@ -5054,68 +5107,6 @@ help from Bernd Raichle, for which I am grateful.
   \endinput}{}%
 % \end{macrocode}
 %
-% TODO. Code for lua bidi options must be moved to a logical place. The
-% problem is |\RequirePackage|, which is forbidden allowed in the options
-% section.
-%
-% \begin{macrocode}
-\ifodd\bbl@engine
-  \def\bbl@activate@preotf{%
-    \let\bbl@activate@preotf\relax  % only once
-    \directlua{
-      Babel = Babel or {}
-      %
-      function Babel.pre_otfload_v(head)
-        if Babel.numbers and Babel.digits_mapped then
-          head = Babel.numbers(head)
-        end
-        if Babel.bidi_enabled then
-          head = Babel.bidi(head, false, dir)
-        end
-        return head
-      end
-      %
-      function Babel.pre_otfload_h(head, gc, sz, pt, dir)
-        if Babel.numbers and Babel.digits_mapped then
-          head = Babel.numbers(head)
-        end
-        if Babel.bidi_enabled then
-          head = Babel.bidi(head, false, dir)
-        end
-        return head
-      end
-      %
-      luatexbase.add_to_callback('pre_linebreak_filter',
-        Babel.pre_otfload_v,
-        'Babel.pre_otfload_v',
-        luatexbase.priority_in_callback('pre_linebreak_filter',
-          'luaotfload.node_processor') or nil)
-      %
-      luatexbase.add_to_callback('hpack_filter',
-        Babel.pre_otfload_h,
-        'Babel.pre_otfload_h',
-        luatexbase.priority_in_callback('hpack_filter',
-          'luaotfload.node_processor') or nil)
-    }}
-  \let\bbl@tempa\relax
-  \@ifpackagewith{babel}{bidi=basic}%
-    {\def\bbl@tempa{basic}}%
-    {\@ifpackagewith{babel}{bidi=basic-r}%
-      {\def\bbl@tempa{basic-r}}%
-      {}}
-  \ifx\bbl@tempa\relax\else
-    \let\bbl@beforeforeign\leavevmode
-    \AtEndOfPackage{\EnableBabelHook{babel-bidi}}%
-    \RequirePackage{luatexbase}%
-    \directlua{
-      require('babel-data-bidi.lua')
-      require('babel-bidi-\bbl@tempa.lua')
-    }
-    \bbl@activate@preotf
-  \fi
-\fi
-%    \end{macrocode}
-%
 % \subsection{\texttt{key=value} options and other general option}
 %
 %    The following macros extract language modifiers, and only real
@@ -5217,7 +5208,7 @@ help from Bernd Raichle, for which I am grateful.
   \fi}
 %    \end{macrocode}
 %
-%    Now we finish the first pass (and start over).
+% Now we finish the first pass (and start over).
 %
 %    \begin{macrocode}
 \ProcessOptions*
@@ -5225,14 +5216,14 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsection{Conditional loading of shorthands}
 %
-%    If there is no |shorthands=<chars>|, the original \textsf{babel}
-%    macros are left untouched, but if there is, these macros are
-%    wrapped (in |babel.def|) to define only those given.
+% If there is no |shorthands=<chars>|, the original \textsf{babel}
+% macros are left untouched, but if there is, these macros are
+% wrapped (in |babel.def|) to define only those given.
 %
-%    A bit of optimization: if there is no |shorthands=|, then
-%    |\bbl@ifshorthand| is always true, and it is always false if
-%    |shorthands| is empty. Also, some code makes sense only with
-%    |shorthands=...|.
+% A bit of optimization: if there is no |shorthands=|, then
+% |\bbl@ifshorthand| is always true, and it is always false if
+% |shorthands| is empty. Also, some code makes sense only with
+% |shorthands=...|.
 %
 %    \begin{macrocode}
 \bbl@trace{Conditional loading of shorthands}
@@ -5264,16 +5255,16 @@ help from Bernd Raichle, for which I am grateful.
     \fi}
 %    \end{macrocode}
 %
-%    We make sure all chars in the string are `other', with the help
-%    of an auxiliary macro defined above (which also zaps spaces).
+% We make sure all chars in the string are `other', with the help
+% of an auxiliary macro defined above (which also zaps spaces).
 %
 %    \begin{macrocode}
   \edef\bbl@opt@shorthands{%
     \expandafter\bbl@sh@string\bbl@opt@shorthands\@empty}%
 %    \end{macrocode}
 %
-%    The following is ignored with |shorthands=off|, since it is
-%    intended to take some aditional actions for certain chars.
+% The following is ignored with |shorthands=off|, since it is
+% intended to take some aditional actions for certain chars.
 %
 %    \begin{macrocode}
   \bbl@ifshorthand{'}%
@@ -5283,9 +5274,9 @@ help from Bernd Raichle, for which I am grateful.
 \fi\fi
 %    \end{macrocode}
 %
-%    With |headfoot=lang| we can set the language used in heads/foots.
-%    For example, in babel/3796 just adds |headfoot=english|.  It
-%    misuses \cs{@resetactivechars} but seems to work.
+% With |headfoot=lang| we can set the language used in heads/foots.
+% For example, in babel/3796 just adds |headfoot=english|.  It
+% misuses \cs{@resetactivechars} but seems to work.
 %
 %    \begin{macrocode}
 \ifx\bbl@opt@headfoot\@nnil\else
@@ -5339,23 +5330,23 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsection{Cross referencing macros}
 %
-%    The \LaTeX\ book states:
-%  \begin{quote}
-%    The \emph{key} argument is any sequence of letters, digits, and
-%    punctuation symbols; upper- and lowercase letters are regarded as
-%    different.
-%  \end{quote}
-%    When the above quote should still be true when a document is
-%    typeset in a language that has active characters, special care
-%    has to be taken of the category codes of these characters when
-%    they appear in an argument of the cross referencing macros.
+% The \LaTeX\ book states:
+% \begin{quote}
+%   The \emph{key} argument is any sequence of letters, digits, and
+%   punctuation symbols; upper- and lowercase letters are regarded as
+%   different.
+% \end{quote}
+% When the above quote should still be true when a document is
+% typeset in a language that has active characters, special care
+% has to be taken of the category codes of these characters when
+% they appear in an argument of the cross referencing macros.
 %
-%    When a cross referencing command processes its argument, all
-%    tokens in this argument should be character tokens with category
-%    `letter' or `other'.
+% When a cross referencing command processes its argument, all
+% tokens in this argument should be character tokens with category
+% `letter' or `other'.
 %
-%    The following package options control which macros are to be
-%    redefined.
+% The following package options control which macros are to be
+% redefined.
 %
 %    \begin{macrocode}
 %<<*More package options>>
@@ -5365,12 +5356,12 @@ help from Bernd Raichle, for which I am grateful.
 %<</More package options>>
 %    \end{macrocode}
 %
-%  \begin{macro}{\@newl@bel}
+% \begin{macro}{\@newl@bel}
 %
-%    First we open a new group to keep the changed setting of
-%    |\protect| local and then we set the |@safe@actives| switch to
-%    true to make sure that any shorthand that appears in any of the
-%    arguments immediately expands to its non-active self.
+% First we open a new group to keep the changed setting of
+% |\protect| local and then we set the |@safe@actives| switch to
+% true to make sure that any shorthand that appears in any of the
+% arguments immediately expands to its non-active self.
 %
 %    \begin{macrocode}
 \bbl@trace{Cross referencing macros}
@@ -5389,9 +5380,9 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \begin{macro}{\@testdef}
 %
-%    An internal \LaTeX\ macro used to test if the labels that have
-%    been written on the |.aux| file have changed.  It is called by
-%    the |\enddocument| macro.
+% An internal \LaTeX\ macro used to test if the labels that have
+% been written on the |.aux| file have changed.  It is called by
+% the |\enddocument| macro.
 %
 %    \begin{macrocode}
   \CheckCommand*\@testdef[3]{%
@@ -5402,13 +5393,13 @@ help from Bernd Raichle, for which I am grateful.
     \fi}
 %    \end{macrocode}
 %
-%  Now that we made sure that |\@testdef| still has the same definition
-%  we can rewrite it. First we make the shorthands `safe'. Then we use
-%  |\bbl@tempa| as an `alias' for the macro that contains the label
-%  which is being checked. Then we define |\bbl@tempb| just as
-%  |\@newl@bel| does it. When the label is defined we replace the
-%  definition of |\bbl@tempa| by its meaning. If the label didn't
-%  change, |\bbl@tempa| and |\bbl@tempb| should be identical macros.
+% Now that we made sure that |\@testdef| still has the same definition
+% we can rewrite it. First we make the shorthands `safe'. Then we use
+% |\bbl@tempa| as an `alias' for the macro that contains the label
+% which is being checked. Then we define |\bbl@tempb| just as
+% |\@newl@bel| does it. When the label is defined we replace the
+% definition of |\bbl@tempa| by its meaning. If the label didn't
+% change, |\bbl@tempa| and |\bbl@tempb| should be identical macros.
 %
 %    \begin{macrocode}
   \def\@testdef#1#2#3{%  TODO. With @samestring?
@@ -5430,13 +5421,13 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\ref}
-%  \begin{macro}{\pageref}
+% \begin{macro}{\ref}
+% \begin{macro}{\pageref}
 %
-%    The same holds for the macro |\ref| that references a label and
-%    |\pageref| to reference a page. We make them robust as well (if
-%    they weren't already) to prevent problems if they should become
-%    expanded at the wrong moment.
+% The same holds for the macro |\ref| that references a label and
+% |\pageref| to reference a page. We make them robust as well (if
+% they weren't already) to prevent problems if they should become
+% expanded at the wrong moment.
 %
 %    \begin{macrocode}
 \bbl@xin@{R}\bbl@opt@safe
@@ -5454,13 +5445,14 @@ help from Bernd Raichle, for which I am grateful.
 %  \end{macro}
 %  \end{macro}
 %
-%  \begin{macro}{\@citex}
-%    The macro used to cite from a bibliography, |\cite|, uses an
-%    internal macro, |\@citex|.
-%    It is this internal macro that picks up the argument(s),
-%    so we redefine this internal macro and leave |\cite| alone. The
-%    first argument is used for typesetting, so the shorthands need
-%    only be deactivated in the second argument.
+% \begin{macro}{\@citex}
+%
+% The macro used to cite from a bibliography, |\cite|, uses an
+% internal macro, |\@citex|.
+% It is this internal macro that picks up the argument(s),
+% so we redefine this internal macro and leave |\cite| alone. The
+% first argument is used for typesetting, so the shorthands need
+% only be deactivated in the second argument.
 %
 %    \begin{macrocode}
 \bbl@xin@{B}\bbl@opt@safe
@@ -5470,25 +5462,25 @@ help from Bernd Raichle, for which I am grateful.
     \org@@citex[#1]{\@tempa}}
 %    \end{macrocode}
 %
-%    Unfortunately, the packages \pkg{natbib} and \pkg{cite} need a
-%    different definition of |\@citex|...
-%    To begin with, \pkg{natbib} has a definition for |\@citex| with
-%    \emph{three} arguments... We only know that a package is loaded
-%    when |\begin{document}| is executed, so we need to postpone the
-%    different redefinition.
+% Unfortunately, the packages \pkg{natbib} and \pkg{cite} need a
+% different definition of |\@citex|...
+% To begin with, \pkg{natbib} has a definition for |\@citex| with
+% \emph{three} arguments... We only know that a package is loaded
+% when |\begin{document}| is executed, so we need to postpone the
+% different redefinition.
 %
 %    \begin{macrocode}
   \AtBeginDocument{%
     \@ifpackageloaded{natbib}{%
 %    \end{macrocode}
 %
-%    Notice that we use |\def| here instead of |\bbl@redefine| because
-%    |\org@@citex| is already defined and we don't want to overwrite
-%    that definition (it would result in parameter stack overflow
-%    because of a circular definition).
+% Notice that we use |\def| here instead of |\bbl@redefine| because
+% |\org@@citex| is already defined and we don't want to overwrite
+% that definition (it would result in parameter stack overflow
+% because of a circular definition).
 %
-%   (Recent versions of \pkg{natbib} change dynamically |\@citex|, so PR4087
-%    doesn't seem fixable in a simple way. Just load \pkg{natbib} before.)
+% (Recent versions of \pkg{natbib} change dynamically |\@citex|, so PR4087
+% doesn't seem fixable in a simple way. Just load \pkg{natbib} before.)
 %
 %    \begin{macrocode}
     \def\@citex[#1][#2]#3{%
@@ -5497,8 +5489,8 @@ help from Bernd Raichle, for which I am grateful.
     }{}}
 %    \end{macrocode}
 %
-%    The package \pkg{cite} has a definition of |\@citex| where the
-%    shorthands need to be turned off in both arguments.
+% The package \pkg{cite} has a definition of |\@citex| where the
+% shorthands need to be turned off in both arguments.
 %
 %    \begin{macrocode}
   \AtBeginDocument{%
@@ -5510,9 +5502,10 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\nocite}
-%    The macro |\nocite| which is used to instruct BiB\TeX\ to
-%    extract uncited references from the database.
+% \begin{macro}{\nocite}
+%
+% The macro |\nocite| which is used to instruct BiB\TeX\ to
+% extract uncited references from the database.
 %
 %    \begin{macrocode}
   \bbl@redefine\nocite#1{%
@@ -5521,19 +5514,20 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\bibcite}
-%  The macro that is used in the |.aux| file to
-%  define citation labels. When packages such as \pkg{natbib} or
-%  \pkg{cite} are not loaded its second argument is used to typeset the
-%  citation label. In that case, this second argument can contain
-%  active characters but is used in an environment where
-%  |\@safe@activestrue| is in effect. This switch needs to be reset
-%  inside the |\hbox| which contains the citation label. In order to
-%  determine during \file{.aux} file processing which definition of
-%  |\bibcite| is needed we define |\bibcite| in such a way that it
-%  redefines itself with the proper definition. We call
-%  |\bbl@cite@choice| to select the proper definition for |\bibcite|.
-%  This new definition is then activated.
+% \begin{macro}{\bibcite}
+%
+% The macro that is used in the |.aux| file to
+% define citation labels. When packages such as \pkg{natbib} or
+% \pkg{cite} are not loaded its second argument is used to typeset the
+% citation label. In that case, this second argument can contain
+% active characters but is used in an environment where
+% |\@safe@activestrue| is in effect. This switch needs to be reset
+% inside the |\hbox| which contains the citation label. In order to
+% determine during \file{.aux} file processing which definition of
+% |\bibcite| is needed we define |\bibcite| in such a way that it
+% redefines itself with the proper definition. We call
+% |\bbl@cite@choice| to select the proper definition for |\bibcite|.
+% This new definition is then activated.
 %
 %    \begin{macrocode}
   \bbl@redefine\bibcite{%
@@ -5543,9 +5537,10 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\bbl@bibcite}
-%    The macro |\bbl@bibcite| holds the definition of |\bibcite|
-%    needed when neither \pkg{natbib} nor \pkg{cite} is loaded.
+% \begin{macro}{\bbl@bibcite}
+%
+% The macro |\bbl@bibcite| holds the definition of |\bibcite|
+% needed when neither \pkg{natbib} nor \pkg{cite} is loaded.
 %
 %    \begin{macrocode}
   \def\bbl@bibcite#1#2{%
@@ -5554,10 +5549,11 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\bbl@cite@choice}
-%    The macro |\bbl@cite@choice| determines which definition of
-%    |\bibcite| is needed. First we give |\bibcite| its default
-%    definition.
+% \begin{macro}{\bbl@cite@choice}
+%
+% The macro |\bbl@cite@choice| determines which definition of
+% |\bibcite| is needed. First we give |\bibcite| its default
+% definition.
 %
 %    \begin{macrocode}
   \def\bbl@cite@choice{%
@@ -5567,9 +5563,9 @@ help from Bernd Raichle, for which I am grateful.
     \global\let\bbl@cite@choice\relax}
 %    \end{macrocode}
 %
-%    When a document is run for the first time, no \file{.aux} file is
-%    available, and |\bibcite| will not yet be properly defined. In
-%    this case, this has to happen before the document starts.
+% When a document is run for the first time, no \file{.aux} file is
+% available, and |\bibcite| will not yet be properly defined. In
+% this case, this has to happen before the document starts.
 %
 %    \begin{macrocode}
   \AtBeginDocument{\bbl@cite@choice}
@@ -5577,9 +5573,10 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\@bibitem}
-%    One of the two internal \LaTeX\ macros called by |\bibitem|
-%    that write the citation label on the |.aux| file.
+% \begin{macro}{\@bibitem}
+%
+% One of the two internal \LaTeX\ macros called by |\bibitem|
+% that write the citation label on the |.aux| file.
 %
 %    \begin{macrocode}
   \bbl@redefine\@bibitem#1{%
@@ -5673,30 +5670,30 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsubsection{\pkg{ifthen}}
 %
-%  \begin{macro}{\ifthenelse}
+% \begin{macro}{\ifthenelse}
 %
-%    Sometimes a document writer wants to create a special effect
-%    depending on the page a certain fragment of text appears on. This
-%    can be achieved by the following piece of code:
+% Sometimes a document writer wants to create a special effect
+% depending on the page a certain fragment of text appears on. This
+% can be achieved by the following piece of code:
 %\begin{verbatim}
 %    \ifthenelse{\isodd{\pageref{some:label}}}
 %               {code for odd pages}
 %               {code for even pages}
 %\end{verbatim}
-%    In order for this to work the argument of |\isodd| needs to be
-%    fully expandable. With the above redefinition of |\pageref| it is
-%    not in the case of this example. To overcome that, we add some
-%    code to the definition of |\ifthenelse| to make things work.
+% In order for this to work the argument of |\isodd| needs to be
+% fully expandable. With the above redefinition of |\pageref| it is
+% not in the case of this example. To overcome that, we add some
+% code to the definition of |\ifthenelse| to make things work.
 %
-%    We want to revert the definition of |\pageref| and |\ref| to
-%    their original definition for the first argument of |\ifthenelse|,
-%    so we first need to store their current meanings.
+% We want to revert the definition of |\pageref| and |\ref| to
+% their original definition for the first argument of |\ifthenelse|,
+% so we first need to store their current meanings.
 %
-%    Then we can set the |\@safe@actives| switch and call the original
-%    |\ifthenelse|. In order to be able to use shorthands in the
-%    second and third arguments of |\ifthenelse| the resetting of the
-%    switch \emph{and} the definition of |\pageref| happens inside
-%    those arguments. 
+% Then we can set the |\@safe@actives| switch and call the original
+% |\ifthenelse|. In order to be able to use shorthands in the
+% second and third arguments of |\ifthenelse| the resetting of the
+% switch \emph{and} the definition of |\pageref| happens inside
+% those arguments. 
 %
 %    \begin{macrocode}
 \bbl@trace{Preventing clashes with other packages}
@@ -5728,14 +5725,14 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsubsection{\pkg{varioref}}
 %
-%  \begin{macro}{\@@vpageref}
-%  \begin{macro}{\vrefpagenum}
-%  \begin{macro}{\Ref}
+% \begin{macro}{\@@vpageref}
+% \begin{macro}{\vrefpagenum}
+% \begin{macro}{\Ref}
 %
-%    When the package varioref is in use we need to modify its
-%    internal command |\@@vpageref| in order to prevent problems when
-%    an active character ends up in the argument of |\vref|. The same
-%    needs to happen for |\vrefpagenum|.
+% When the package varioref is in use we need to modify its
+% internal command |\@@vpageref| in order to prevent problems when
+% an active character ends up in the argument of |\vref|. The same
+% needs to happen for |\vrefpagenum|.
 %
 %    \begin{macrocode}
   \AtBeginDocument{%
@@ -5750,14 +5747,14 @@ help from Bernd Raichle, for which I am grateful.
         \@safe@activesfalse}%
 %    \end{macrocode}
 %
-%    The package \pkg{varioref} defines |\Ref| to be a robust command
-%    wich uppercases the first character of the reference text. In
-%    order to be able to do that it needs to access the expandable form
-%    of |\ref|. So we employ a little trick here. We redefine the
-%    (internal) command \verb*|\Ref | to call |\org@ref| instead of
-%    |\ref|. The disadvantage of this solution is that whenever the
-%    definition of |\Ref| changes, this definition needs to be updated
-%    as well.
+% The package \pkg{varioref} defines |\Ref| to be a robust command
+% wich uppercases the first character of the reference text. In
+% order to be able to do that it needs to access the expandable form
+% of |\ref|. So we employ a little trick here. We redefine the
+% (internal) command \verb*|\Ref | to call |\org@ref| instead of
+% |\ref|. The disadvantage of this solution is that whenever the
+% definition of |\Ref| changes, this definition needs to be updated
+% as well.
 %
 %    \begin{macrocode}
       \expandafter\def\csname Ref \endcsname#1{%
@@ -5773,14 +5770,15 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsubsection{\pkg{hhline}}
 %
-%  \begin{macro}{\hhline}
-%    Delaying the activation of the shorthand characters has introduced
-%    a problem with the \pkg{hhline} package. The reason is that it
-%    uses the `:' character which is made active by the french support
-%    in \babel. Therefore we need to \emph{reload} the package when
-%    the `:' is an active character. Note that this happens
-%    \emph{after} the category code of the @-sign has been changed to
-%    other, so we need to temporarily change it to letter again.
+% \begin{macro}{\hhline}
+%
+% Delaying the activation of the shorthand characters has introduced
+% a problem with the \pkg{hhline} package. The reason is that it
+% uses the `:' character which is made active by the french support
+% in \babel. Therefore we need to \emph{reload} the package when
+% the `:' is an active character. Note that this happens
+% \emph{after} the category code of the @-sign has been changed to
+% other, so we need to temporarily change it to letter again.
 %
 %    \begin{macrocode}
 \AtEndOfPackage{%
@@ -5798,15 +5796,15 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsubsection{\pkg{hyperref}}
 %
-%  \begin{macro}{\pdfstringdefDisableCommands}
+% \begin{macro}{\pdfstringdefDisableCommands}
 %
-%    A number of interworking problems between \pkg{babel} and
-%    \pkg{hyperref} are tackled by \pkg{hyperref} itself. The
-%    following code was introduced to prevent some annoying warnings
-%    but it broke bookmarks. This was quickly fixed in \pkg{hyperref},
-%    which essentially made it no-op. However, it will not removed for
-%    the moment because \pkg{hyperref} is expecting it. TODO. Still
-%    true? 
+% A number of interworking problems between \pkg{babel} and
+% \pkg{hyperref} are tackled by \pkg{hyperref} itself. The
+% following code was introduced to prevent some annoying warnings
+% but it broke bookmarks. This was quickly fixed in \pkg{hyperref},
+% which essentially made it no-op. However, it will not removed for
+% the moment because \pkg{hyperref} is expecting it. TODO. Still
+% true? 
 %
 %    \begin{macrocode}
 \AtBeginDocument{%
@@ -5819,13 +5817,14 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsubsection{\pkg{fancyhdr}}
 %
-%  \begin{macro}{\FOREIGNLANGUAGE}
-%    The package \pkg{fancyhdr} treats the running head and fout lines
-%    somewhat differently as the standard classes. A symptom of this is
-%    that the command |\foreignlanguage| which \babel\ adds to the
-%    marks can end up inside the argument of |\MakeUppercase|. To
-%    prevent unexpected results we need to define |\FOREIGNLANGUAGE|
-%    here.
+% \begin{macro}{\FOREIGNLANGUAGE}
+%
+% The package \pkg{fancyhdr} treats the running head and fout lines
+% somewhat differently as the standard classes. A symptom of this is
+% that the command |\foreignlanguage| which \babel\ adds to the
+% marks can end up inside the argument of |\MakeUppercase|. To
+% prevent unexpected results we need to define |\FOREIGNLANGUAGE|
+% here.
 %
 %    \begin{macrocode}
 \DeclareRobustCommand{\FOREIGNLANGUAGE}[1]{%
@@ -5834,12 +5833,12 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%  \begin{macro}{\substitutefontfamily}
+% \begin{macro}{\substitutefontfamily}
 %
-%    The command |\substitutefontfamily| creates an
-%    \file{.fd} file on the fly. The first argument is an encoding
-%    mnemonic, the second and third arguments are font family names.
-%    This command is deprecated. Use the tools provides by \LaTeX.
+% The command |\substitutefontfamily| creates an
+% \file{.fd} file on the fly. The first argument is an encoding
+% mnemonic, the second and third arguments are font family names.
+% This command is deprecated. Use the tools provides by \LaTeX.
 %
 %    \begin{macrocode}
 \def\substitutefontfamily#1#2#3{%
@@ -6020,25 +6019,147 @@ help from Bernd Raichle, for which I am grateful.
 % by introducing a “middle layer” just below the user interface
 % (sectioning, footnotes).
 %
-%    \begin{itemize}
-%    \item pdftex provides a minimal support for bidi text, and it
-%      must be done by hand. Vertical typesetting is not possible.
-%    \item \xetex{} is somewhat better, thanks to its font engine
-%      (even if not always reliable) and a few additional tools. However,
-%      very little is done at the paragraph level. Another challenging
-%      problem is text direction does not honour \TeX{} grouping.
-%    \item \luatex{} can provide the most complete solution, as we can
-%      manipulate almost freely the node list, the generated lines,
-%      and so on, but bidi text does not work out of the box and some
-%      development is necessary. It also provides tools to properly
-%      set left-to-right and right-to-left page layouts. As Lua\TeX-ja
-%      shows, vertical typesetting is possible, too.
-%    \end{itemize}
-%
-%    \begin{macrocode}
-\bbl@trace{Basic (internal) bidi support}
+% \begin{itemize}
+% \item pdftex provides a minimal support for bidi text, and it
+%   must be done by hand. Vertical typesetting is not possible.
+% \item \xetex{} is somewhat better, thanks to its font engine
+%   (even if not always reliable) and a few additional tools. However,
+%   very little is done at the paragraph level. Another challenging
+%   problem is text direction does not honour \TeX{} grouping.
+% \item \luatex{} can provide the most complete solution, as we can
+%   manipulate almost freely the node list, the generated lines,
+%   and so on, but bidi text does not work out of the box and some
+%   development is necessary. It also provides tools to properly
+%   set left-to-right and right-to-left page layouts. As Lua\TeX-ja
+%   shows, vertical typesetting is possible, too.
+% \end{itemize}
+%
+% As a frist step, add a handler for bidi and digits (and potentially
+% other processes) just before \textsf{luaoftload} is applied, which is
+% loaded by default by \LaTeX. Just in case, consider the possibility
+% it has not been loaded.
+%
+%    \begin{macrocode}
+\ifodd\bbl@engine
+  \def\bbl@activate@preotf{%
+    \let\bbl@activate@preotf\relax  % only once
+    \directlua{
+      Babel = Babel or {}
+      %
+      function Babel.pre_otfload_v(head)
+        if Babel.numbers and Babel.digits_mapped then
+          head = Babel.numbers(head)
+        end
+        if Babel.bidi_enabled then
+          head = Babel.bidi(head, false, dir)
+        end
+        return head
+      end
+      %
+      function Babel.pre_otfload_h(head, gc, sz, pt, dir)
+        if Babel.numbers and Babel.digits_mapped then
+          head = Babel.numbers(head)
+        end
+        if Babel.bidi_enabled then
+          head = Babel.bidi(head, false, dir)
+        end
+        return head
+      end
+      %
+      luatexbase.add_to_callback('pre_linebreak_filter',
+        Babel.pre_otfload_v,
+        'Babel.pre_otfload_v',
+        luatexbase.priority_in_callback('pre_linebreak_filter',
+          'luaotfload.node_processor') or nil)
+      %
+      luatexbase.add_to_callback('hpack_filter',
+        Babel.pre_otfload_h,
+        'Babel.pre_otfload_h',
+        luatexbase.priority_in_callback('hpack_filter',
+          'luaotfload.node_processor') or nil)
+    }}
+\fi
+%    \end{macrocode}
+%
+% The basic setup. In luatex, the output is modified at a very low
+% level to set the |\bodydir| to the |\pagedir|.
+%
+%    \begin{macrocode}
+\bbl@trace{Loading basic (internal) bidi support}
+\ifodd\bbl@engine
+  \ifnum\bbl@bidimode>100 \ifnum\bbl@bidimode<200
+    \let\bbl@beforeforeign\leavevmode
+    \AtEndOfPackage{\EnableBabelHook{babel-bidi}}
+    \RequirePackage{luatexbase}
+    \bbl@activate@preotf
+    \directlua{
+      require('babel-data-bidi.lua')
+      \ifcase\expandafter\@gobbletwo\the\bbl@bidimode\or
+        require('babel-bidi-basic.lua')
+      \or
+        require('babel-bidi-basic-r.lua')
+      \fi}
+    % TODO - to locale_props, not as separate attribute
+    \newattribute\bbl@attr@dir
+    % TODO. I don't like it, hackish:
+    \bbl@exp{\output{\bodydir\pagedir\the\output}}
+    \AtEndOfPackage{\EnableBabelHook{babel-bidi}}
+  \fi\fi
+\else
+  \ifnum\bbl@bidimode>100 \ifnum\bbl@bidimode<200
+    \bbl@error
+      {The bidi method `basic' is available only in\\%
+       luatex. I'll continue with `bidi=default', so\\%
+       expect wrong results}%
+      {See the manual for further details.}%
+    \let\bbl@beforeforeign\leavevmode
+    \AtEndOfPackage{%
+      \EnableBabelHook{babel-bidi}%
+      \bbl@xebidipar}
+  \fi\fi
+  \def\bbl@loadxebidi#1{%
+    \ifx\RTLfootnotetext\@undefined
+      \AtEndOfPackage{%
+        \EnableBabelHook{babel-bidi}%
+        \ifx\fontspec\@undefined
+          \usepackage{fontspec}% bidi needs fontspec
+        \fi
+        \usepackage#1{bidi}}%
+    \fi}
+  \ifnum\bbl@bidimode>200
+    \ifcase\expandafter\@gobbletwo\the\bbl@bidimode\or
+      \bbl@tentative{bidi=bidi}
+      \bbl@loadxebidi{}
+    \or
+      \bbl@tentative{bidi=bidi-r}
+      \bbl@loadxebidi{[rldocument]}
+    \or
+      \bbl@tentative{bidi=bidi-l}
+      \bbl@loadxebidi{}
+    \fi
+  \fi
+\fi
+\ifnum\bbl@bidimode=\@ne
+  \let\bbl@beforeforeign\leavevmode
+  \ifodd\bbl@engine
+    \newattribute\bbl@attr@dir
+    \bbl@exp{\output{\bodydir\pagedir\the\output}}%
+  \fi
+  \AtEndOfPackage{%
+    \EnableBabelHook{babel-bidi}%
+    \ifodd\bbl@engine\else
+      \bbl@xebidipar
+    \fi}
+\fi
+%    \end{macrocode}
+%
+% Now come the macros used to set the direction when a language is
+% switched. First the (mostly) common macros.
+%
+%    \begin{macrocode}
+\bbl@trace{Macros to switch the text direction}
 \def\bbl@alscripts{,Arabic,Syriac,Thaana,}
-\def\bbl@rscripts{%
+\def\bbl@rscripts{% TODO. Base on codes ??
   ,Imperial Aramaic,Avestan,Cypriot,Hatran,Hebrew,%
   Old Hungarian,Old Hungarian,Lydian,Mandaean,Manichaean,%
   Manichaean,Meroitic Cursive,Meroitic,Old North Arabian,%
@@ -6075,9 +6196,16 @@ help from Bernd Raichle, for which I am grateful.
     \bbl@pardir{#1}%
   \fi
   \bbl@textdir{#1}}
+% TODO. Only if \bbl@bidimode > 0?:
+\AddBabelHook{babel-bidi}{afterextras}{\bbl@switchdir}
+\DisableBabelHook{babel-bidi}
+%    \end{macrocode}
+%
+% Now the engine-dependent macros. TODO. Must be moved to the engine
+% files?
+%
+%    \begin{macrocode} 
 \ifodd\bbl@engine  % luatex=1
-  \AddBabelHook{babel-bidi}{afterextras}{\bbl@switchdir}
-  \DisableBabelHook{babel-bidi}
   \chardef\bbl@thetextdir\z@
   \chardef\bbl@thepardir\z@
   \def\bbl@getluadir#1{%
@@ -6115,9 +6243,11 @@ help from Bernd Raichle, for which I am grateful.
     \else
       \everyhbox{\textdir TRT\relax}%
     \fi}
+  \frozen@everymath\expandafter{%
+    \expandafter\bbl@mathboxdir\the\frozen@everymath}
+  \frozen@everydisplay\expandafter{%
+    \expandafter\bbl@mathboxdir\the\frozen@everydisplay}
 \else % pdftex=0, xetex=2
-  \AddBabelHook{babel-bidi}{afterextras}{\bbl@switchdir}
-  \DisableBabelHook{babel-bidi}
   \newcount\bbl@dirlevel
   \chardef\bbl@thetextdir\z@
   \chardef\bbl@thepardir\z@
@@ -6182,20 +6312,18 @@ help from Bernd Raichle, for which I am grateful.
     \newtoks\everypar
     \everypar=\bbl@severypar
     \bbl@severypar{\bbl@xeeverypar\the\everypar}}
-  \def\bbl@tempb{%
+  \ifnum\bbl@bidimode>200
     \let\bbl@textdir@i\@gobbletwo
     \let\bbl@xebidipar\@empty
     \AddBabelHook{bidi}{foreign}{%
-      \def\bbl@tempa{\def\BabelText########1}%
+      \def\bbl@tempa{\def\BabelText####1}%
       \ifcase\bbl@thetextdir
-        \expandafter\bbl@tempa\expandafter{\BabelText{\LR{####1}}}%
+        \expandafter\bbl@tempa\expandafter{\BabelText{\LR{##1}}}%
       \else
-        \expandafter\bbl@tempa\expandafter{\BabelText{\RL{####1}}}%
+        \expandafter\bbl@tempa\expandafter{\BabelText{\RL{##1}}}%
       \fi}
-    \def\bbl@pardir##1{\ifcase##1\relax\setLR\else\setRL\fi}}
-  \@ifpackagewith{babel}{bidi=bidi}{\bbl@tempb}{}%
-  \@ifpackagewith{babel}{bidi=bidi-l}{\bbl@tempb}{}%
-  \@ifpackagewith{babel}{bidi=bidi-r}{\bbl@tempb}{}%
+    \def\bbl@pardir#1{\ifcase#1\relax\setLR\else\setRL\fi}
+  \fi
 \fi
 %    \end{macrocode}
 %
@@ -6214,16 +6342,17 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsection{Local Language Configuration}
 %
-%  \begin{macro}{\loadlocalcfg}
-%    At some sites it may be necessary to add site-specific actions to
-%    a language definition file. This can be done by creating a file
-%    with the same name as the language definition file, but with the
-%    extension \file{.cfg}. For instance the file \file{norsk.cfg}
-%    will be loaded when the language definition file \file{norsk.ldf}
-%    is loaded.
+% \begin{macro}{\loadlocalcfg}
+%
+% At some sites it may be necessary to add site-specific actions to
+% a language definition file. This can be done by creating a file
+% with the same name as the language definition file, but with the
+% extension \file{.cfg}. For instance the file \file{norsk.cfg}
+% will be loaded when the language definition file \file{norsk.ldf}
+% is loaded. 
 %
-%    For plain-based formats we don't want to override the definition
-%    of |\loadlocalcfg| from \file{plain.def}.
+% For plain-based formats we don't want to override the definition
+% of |\loadlocalcfg| from \file{plain.def}.
 %
 %    \begin{macrocode}
 \bbl@trace{Local Language Configuration}
@@ -6240,8 +6369,8 @@ help from Bernd Raichle, for which I am grateful.
 %    \end{macrocode}%
 %    \end{macro}
 %
-%    Just to be compatible with \LaTeX$\:$2.09 we add a few more lines
-%    of code. TODO. Necessary? Correct place? Used by some ldf file?
+% Just to be compatible with \LaTeX$\:$2.09 we add a few more lines
+% of code. TODO. Necessary? Correct place? Used by some ldf file?
 %
 %    \begin{macrocode}
 \ifx\@unexpandable@protect\@undefined
@@ -6259,11 +6388,11 @@ help from Bernd Raichle, for which I am grateful.
 %
 % \subsection{Language options}
 %
-%    Languages are loaded when processing the corresponding option
-%    \textit{except} if a |main| language has been set. In such a
-%    case, it is not loaded until all options has been processed.
-%    The following macro inputs the ldf file and does some additional
-%    checks (|\input| works, too, but possible errors are not catched).
+% Languages are loaded when processing the corresponding option
+% \textit{except} if a |main| language has been set. In such a
+% case, it is not loaded until all options has been processed.
+% The following macro inputs the ldf file and does some additional
+% checks (|\input| works, too, but possible errors are not catched).
 %
 %    \begin{macrocode}
 \bbl@trace{Language options}
@@ -6286,7 +6415,10 @@ help from Bernd Raichle, for which I am grateful.
        headfoot=, strings=, config=, hyphenmap=, or a language name.}}}
 %    \end{macrocode}
 %
-%    Now, we set language options whose names are different from |ldf| files.
+% Now, we set a few language options whose names are different from
+% |ldf| files. These declarations are preserved for backwards
+% compatibility, but they must be eventually removed. Use proxy files
+% instead.
 %
 %    \begin{macrocode}
 \def\bbl@try@load@lang#1#2#3{%
@@ -6294,8 +6426,6 @@ help from Bernd Raichle, for which I am grateful.
       {\bbl@load@language{\CurrentOption}}%
       {#1\bbl@load@language{#2}#3}}
 \DeclareOption{afrikaans}{\bbl@try@load@lang{}{dutch}{}}
-\DeclareOption{brazil}{\bbl@try@load@lang{}{portuges}{}}
-\DeclareOption{brazilian}{\bbl@try@load@lang{}{portuges}{}}
 \DeclareOption{hebrew}{%
   \input{rlbabel.def}%
   \bbl@load@language{hebrew}}
@@ -6304,19 +6434,18 @@ help from Bernd Raichle, for which I am grateful.
 \DeclareOption{nynorsk}{\bbl@try@load@lang{}{norsk}{}}
 \DeclareOption{polutonikogreek}{%
   \bbl@try@load@lang{}{greek}{\languageattribute{greek}{polutoniko}}}
-\DeclareOption{portuguese}{\bbl@try@load@lang{}{portuges}{}}
 \DeclareOption{russian}{\bbl@try@load@lang{}{russianb}{}}
 \DeclareOption{ukrainian}{\bbl@try@load@lang{}{ukraineb}{}}
 \DeclareOption{uppersorbian}{\bbl@try@load@lang{}{usorbian}{}}
 %    \end{macrocode}
 %
-%    Another way to extend the list of `known' options for \babel\ was
-%    to create the file \file{bblopts.cfg} in which one can add option
-%    declarations. However, this mechanism is deprecated -- if you
-%    want an alternative name for a language, just create a new |.ldf|
-%    file loading the actual one. You can also set the name
-%    of the file with the package option |config=<name>|, which will
-%    load |<name>.cfg| instead.
+% Another way to extend the list of `known' options for \babel\ was
+% to create the file \file{bblopts.cfg} in which one can add option
+% declarations. However, this mechanism is deprecated -- if you
+% want an alternative name for a language, just create a new |.ldf|
+% file loading the actual one. You can also set the name
+% of the file with the package option |config=<name>|, which will
+% load |<name>.cfg| instead.
 %
 %    \begin{macrocode}
 \ifx\bbl@opt@config\@nnil
@@ -6337,13 +6466,13 @@ help from Bernd Raichle, for which I am grateful.
 \fi
 %    \end{macrocode}
 %
-%    Recognizing global options in packages not having a closed set of
-%    them is not trivial, as for them to be processed they must be
-%    defined explicitly. So, package options not yet taken into
-%    account and stored in |bbl@language@opts| are assumed to be
-%    languages (note this list also contains the language given with
-%    |main|). If not declared above, the names of the option and the
-%    file are the same.
+% Recognizing global options in packages not having a closed set of
+% them is not trivial, as for them to be processed they must be
+% defined explicitly. So, package options not yet taken into
+% account and stored in |bbl@language@opts| are assumed to be
+% languages (note this list also contains the language given with
+% |main|). If not declared above, the names of the option and the
+% file are the same.
 %
 %    \begin{macrocode}
 \bbl@for\bbl@tempa\bbl@language@opts{%
@@ -6356,11 +6485,11 @@ help from Bernd Raichle, for which I am grateful.
      \@empty}
 %    \end{macrocode}
 %
-%    Now, we make sure an option is explicitly declared for any
-%    language set as global option, by checking if an |ldf|
-%    exists. The previous step was, in fact, somewhat redundant, but
-%    that way we minimize accesing the file system just to see if the
-%    option could be a language.
+% Now, we make sure an option is explicitly declared for any
+% language set as global option, by checking if an |ldf|
+% exists. The previous step was, in fact, somewhat redundant, but
+% that way we minimize accesing the file system just to see if the
+% option could be a language.
 %
 %    \begin{macrocode}
 \bbl@foreach\@classoptionslist{%
@@ -6381,13 +6510,13 @@ help from Bernd Raichle, for which I am grateful.
 \fi
 %    \end{macrocode}
 %
-%    And we are done, because all options for this pass has been
-%    declared. Those already processed in the first pass are just
-%    ignored.
+% And we are done, because all options for this pass has been
+% declared. Those already processed in the first pass are just
+% ignored.
 %
-%    The options have to be processed in the order in which the user
-%    specified them (except, of course, global options, which \LaTeX{}
-%    processes before):
+% The options have to be processed in the order in which the user
+% specified them (except, of course, global options, which \LaTeX{}
+% processes before):
 %
 %    \begin{macrocode}
 \def\AfterBabelLanguage#1{%
@@ -6396,13 +6525,13 @@ help from Bernd Raichle, for which I am grateful.
 \ProcessOptions*
 %    \end{macrocode}
 %
-%    This finished the second pass. Now the third one begins, which
-%    loads the main language set with the key |main|. A warning is
-%    raised if the main language is not the same as the last named
-%    one, or if the value of the key |main| is not a language. Then
-%    execute directly the option (because it could be used only in
-%    |main|). After loading all languages, we deactivate
-%    |\AfterBabelLanguage|.
+% This finished the second pass. Now the third one begins, which
+% loads the main language set with the key |main|. A warning is
+% raised if the main language is not the same as the last named
+% one, or if the value of the key |main| is not a language. Then
+% execute directly the option (because it could be used only in
+% |main|). After loading all languages, we deactivate
+% |\AfterBabelLanguage|.
 %
 %    \begin{macrocode}
 \bbl@trace{Option 'main'}
@@ -6434,10 +6563,10 @@ help from Bernd Raichle, for which I am grateful.
     {Languages have been loaded, so I can do nothing}}
 %    \end{macrocode}
 %      
-%    In order to catch the case where the user forgot to specify a
-%    language we check whether |\bbl@main@language|, has become
-%    defined. If not, no language has been loaded and an error
-%    message is displayed.
+% In order to catch the case where the user forgot to specify a
+% language we check whether |\bbl@main@language|, has become
+% defined. If not, no language has been loaded and an error
+% message is displayed.
 %
 %    \begin{macrocode}
 \ifx\bbl@main@language\@undefined
@@ -6512,6 +6641,7 @@ help from Bernd Raichle, for which I am grateful.
   \ifx\@uclclist\@undefined\let\@uclclist\@empty\fi
   \ifx\bbl@trace\@undefined\def\bbl@trace#1{}\fi
   \expandafter\newif\csname ifbbl@single\endcsname
+  \chardef\bbl@bidimode\z@
 \fi
 %    \end{macrocode}
 %
@@ -7006,13 +7136,24 @@ help from Bernd Raichle, for which I am grateful.
       \csname date#1\endcsname\relax
     \fi
   \else
-    \ifbbl@usedategroup   % if \foreign... within \<lang>date
-      \bbl@usedategroupfalse
-      \ifhmode
-        \hskip\z@skip % trick to ignore spaces
+    \ifhmode
+      \hskip\z@skip % trick to ignore spaces
+      \bbl@xin@{,captions,}{,\bbl@select@opts,}%
+      \ifin@
+        \csname captions#1\endcsname\relax
+      \fi
+      \bbl@xin@{,date,}{,\bbl@select@opts,}%
+      \ifin@  % if \foreign... within \<lang>date
         \csname date#1\endcsname\relax
-        \loop\ifdim\lastskip>\z@\unskip\repeat\unskip
-      \else
+      \fi
+      \loop\ifdim\lastskip>\z@\unskip\repeat\unskip
+    \else
+      \bbl@xin@{,captions,}{,\bbl@select@opts,}%
+      \ifin@ 
+        \csname captions#1\endcsname\relax
+      \fi
+      \bbl@xin@{,date,}{,\bbl@select@opts,}%
+      \ifin@
         \csname date#1\endcsname\relax
       \fi
     \fi
@@ -7085,9 +7226,12 @@ help from Bernd Raichle, for which I am grateful.
 % This environment makes use of |\foreign@language|.
 %
 %    \begin{macrocode}
-\expandafter\def\csname otherlanguage*\endcsname#1{%
+\expandafter\def\csname otherlanguage*\endcsname{%
+  \@ifnextchar[\bbl@otherlanguage@s{\bbl@otherlanguage@s[]}}
+\def\bbl@otherlanguage@s[#1]#2{%
   \ifnum\bbl@hymapsel=\@cclv\chardef\bbl@hymapsel4\relax\fi
-  \foreign@language{#1}}
+  \def\bbl@select@opts{#1}%
+  \foreign@language{#2}}
 %    \end{macrocode}
 %
 % At the end of the environment we need to switch off the extra
@@ -7146,13 +7290,14 @@ help from Bernd Raichle, for which I am grateful.
   \expandafter\noexpand\csname foreignlanguage \endcsname}
 \expandafter\def\csname foreignlanguage \endcsname{%
   \@ifstar\bbl@foreign@s\bbl@foreign@x}
-\def\bbl@foreign@x#1#2{%
+\newcommand\bbl@foreign@x[3][]{%
   \begingroup
+    \def\bbl@select@opts{#1}%
     \let\BabelText\@firstofone
     \bbl@beforeforeign
-    \foreign@language{#1}%
+    \foreign@language{#2}%
     \bbl@usehooks{foreign}{}%
-    \BabelText{#2}% Now in horizontal mode!
+    \BabelText{#3}% Now in horizontal mode!
   \endgroup}
 \def\bbl@foreign@s#1#2{% TODO - \shapemode, \@setpar, ?\@@par
   \begingroup
@@ -7179,6 +7324,10 @@ help from Bernd Raichle, for which I am grateful.
 \def\foreign@language#1{%
   % set name
   \edef\languagename{#1}%
+  \ifbbl@usedategroup
+    \bbl@add\bbl@select@opts{,date,}%
+    \bbl@usedategroupfalse
+  \fi
   \bbl@fixname\languagename
   % TODO. name@map here?
   \bbl@provide@locale
@@ -9932,17 +10081,17 @@ help from Bernd Raichle, for which I am grateful.
 %
 %  \end{macro}
 %
-%    For all vowels we declare |\"| to be a composite command which
-%    uses |\bbl@umlauta| or |\bbl@umlaute| to position the umlaut
-%    character. We need to be sure that these definitions override the
-%    ones that are provided when the package \pkg{fontenc} with
-%    option \Lopt{OT1} is used. Therefore these declarations are
-%    postponed until the beginning of the document. Note these
-%    definitions only apply to some languages, but
-%    babel sets them for \textit{all} languages -- you may want to
-%    redefine |\bbl@umlauta| and/or |\bbl@umlaute| for a language
-%    in the corresponding |ldf| (using the babel switching mechanism,
-%    of course).
+% For all vowels we declare |\"| to be a composite command which
+% uses |\bbl@umlauta| or |\bbl@umlaute| to position the umlaut
+% character. We need to be sure that these definitions override the
+% ones that are provided when the package \pkg{fontenc} with
+% option \Lopt{OT1} is used. Therefore these declarations are
+% postponed until the beginning of the document. Note these
+% definitions only apply to some languages, but
+% babel sets them for \textit{all} languages -- you may want to
+% redefine |\bbl@umlauta| and/or |\bbl@umlaute| for a language
+% in the corresponding |ldf| (using the babel switching mechanism,
+% of course).
 %
 %    \begin{macrocode}
 \AtBeginDocument{%
@@ -9956,17 +10105,21 @@ help from Bernd Raichle, for which I am grateful.
   \DeclareTextCompositeCommand{\"}{OT1}{E}{\bbl@umlaute{E}}%
   \DeclareTextCompositeCommand{\"}{OT1}{I}{\bbl@umlaute{I}}%
   \DeclareTextCompositeCommand{\"}{OT1}{O}{\bbl@umlauta{O}}%
-  \DeclareTextCompositeCommand{\"}{OT1}{U}{\bbl@umlauta{U}}%
-}
+  \DeclareTextCompositeCommand{\"}{OT1}{U}{\bbl@umlauta{U}}}
 %    \end{macrocode}
 %
 % Finally, make sure the default hyphenrules are defined (even if
-% empty). 
+% empty). For internal use, another empty |\language| is defined.
+% Currently used in Amharic.
 %
 %    \begin{macrocode}
 \ifx\l@english\@undefined
   \chardef\l@english\z@
 \fi
+% The following is used to cancel rules in ini files (see Amharic).
+\ifx\l@babelnohyhens\@undefined
+  \newlanguage\l@babelnohyphens
+\fi
 %    \end{macrocode}
 %
 % \subsection{Layout}
@@ -10109,7 +10262,8 @@ help from Bernd Raichle, for which I am grateful.
   \bbl@ifunset{bbl@lname@#2}%  TODO. Duplicated
     {\def\BabelBeforeIni##1##2{%
        \begingroup
-         \catcode`\[=12 \catcode`\]=12 \catcode`\==12  \catcode`\;=12 %
+         \catcode`\[=12 \catcode`\]=12 \catcode`\==12
+         \catcode`\;=12 \catcode`\|=12 %
          \let\bbl@ini@captions@aux\@gobbletwo
          \def\bbl@inidate ####1.####2.####3.####4\relax ####5####6{}%
          \bbl@read@ini{##1}{basic data}%
@@ -10120,7 +10274,8 @@ help from Bernd Raichle, for which I am grateful.
          \bbl@exportkey{lfthm}{typography.lefthyphenmin}{2}%
          \bbl@exportkey{rgthm}{typography.righthyphenmin}{3}%
          \bbl@exportkey{hyphr}{typography.hyphenrules}{}%
-         \bbl@exportkey{hyoth}{typography.hyphenate.other}{}%
+         \bbl@exportkey{hyotl}{typography.hyphenate.other.locale}{}%
+         \bbl@exportkey{hyots}{typography.hyphenate.other.script}{}%
          \bbl@exportkey{intsp}{typography.intraspace}{}%
          \ifx\bbl@initoload\relax\endinput\fi
        \endgroup}%
@@ -10227,11 +10382,11 @@ help from Bernd Raichle, for which I am grateful.
     \bbl@csarg\edef{intsp@#2}{\bbl@KVP@intraspace}%
   \fi
   \bbl@provide@intraspace
-  % == hyphenate.other ==
-  \bbl@ifunset{bbl@hyoth@\languagename}{}%
-    {\bbl@csarg\bbl@replace{hyoth@\languagename}{ }{,}%
+  % == hyphenate.other.locale ==
+  \bbl@ifunset{bbl@hyotl@\languagename}{}%
+    {\bbl@csarg\bbl@replace{hyotl@\languagename}{ }{,}%
      \bbl@startcommands*{\languagename}{}%
-       \bbl@csarg\bbl@foreach{hyoth@\languagename}{%
+       \bbl@csarg\bbl@foreach{hyotl@\languagename}{%
          \ifcase\bbl@engine
            \ifnum##1<257
              \SetHyphenMap{\BabelLower{##1}{##1}}%
@@ -10240,6 +10395,17 @@ help from Bernd Raichle, for which I am grateful.
            \SetHyphenMap{\BabelLower{##1}{##1}}%
          \fi}%
      \bbl@endcommands}%
+  % == hyphenate.other.script ==
+  \bbl@ifunset{bbl@hyots@\languagename}{}%
+    {\bbl@csarg\bbl@replace{hyots@\languagename}{ }{,}%
+     \bbl@csarg\bbl@foreach{hyots@\languagename}{%
+       \ifcase\bbl@engine
+         \ifnum##1<257
+           \global\lccode##1=##1\relax
+         \fi
+       \else
+         \global\lccode##1=##1\relax
+       \fi}}%
   % == maparabic ==
   % Native digits, if provided in ini (TeX level, xe and lua)
   \ifcase\bbl@engine\else
@@ -10341,9 +10507,12 @@ help from Bernd Raichle, for which I am grateful.
 %
 % A tool to define the macros for native digits from the list provided 
 % in the |ini| file. Somewhat convoluted because there are 10 digits, 
-% but only 9 arguments in \TeX.
+% but only 9 arguments in \TeX. Non-digits characters are kept. The
+% first macro is the generic “localized” command.
 %
 %    \begin{macrocode}
+% TODO. Merge with \localenumeral:
+% \newcommand\localedigits{\@nameuse{\languagename digits}}
 \def\bbl@setdigits#1#2#3#4#5{%
   \bbl@exp{%
     \def\<\languagename digits>####1{%       ie, \langdigits
@@ -10414,7 +10583,8 @@ help from Bernd Raichle, for which I am grateful.
   \bbl@ifunset{bbl@lname@#1}%     TODO. Duplicated
     {\def\BabelBeforeIni##1##2{%
        \begingroup
-         \catcode`\[=12 \catcode`\]=12 \catcode`\==12  \catcode`\;=12 %
+         \catcode`\[=12 \catcode`\]=12 \catcode`\==12
+         \catcode`\;=12 \catcode`\|=12 %
          \let\bbl@ini@captions@aux\@gobbletwo
          \def\bbl@inidate ####1.####2.####3.####4\relax ####5####6{}%
          \bbl@read@ini{##1}{basic data}%
@@ -10422,8 +10592,8 @@ help from Bernd Raichle, for which I am grateful.
          \bbl@exportkey{lnbrk}{typography.linebreaking}{h}%
          \bbl@exportkey{lfthm}{typography.lefthyphenmin}{2}%
          \bbl@exportkey{rgthm}{typography.righthyphenmin}{3}%
-         \bbl@exportkey{hyphr}{typography.hyphenrules}{}%
-         \bbl@exportkey{hyoth}{typography.hyphenate.other}{}%
+         \bbl@exportkey{hyotl}{typography.hyphenate.other.locale}{}%
+         \bbl@exportkey{hyots}{typography.hyphenate.other.script}{}%
          \bbl@exportkey{intsp}{typography.intraspace}{}%
          \bbl@exportkey{chrng}{characters.ranges}{}%
          \bbl@exportkey{dgnat}{numbers.digits.native}{}%
@@ -10662,6 +10832,11 @@ help from Bernd Raichle, for which I am grateful.
 \let\bbl@inikv@characters\bbl@inikv
 \let\bbl@inikv@numbers\bbl@inikv
 \def\bbl@inikv@counters#1=#2\@@{%
+  \bbl@ifsamestring{#1}{digits}%
+    {\bbl@error{The counter name 'digits' is reserved for mapping\\%
+                decimal digits}%
+               {Use another name.}}%
+    {}%
   \def\bbl@tempc{#1}%
   \bbl@trim@def{\bbl@tempb*}{#2}%
   \in@{.1$}{#1$}%
@@ -10685,7 +10860,8 @@ help from Bernd Raichle, for which I am grateful.
   \bbl@exportkey{prehc}{typography.prehyphenchar}{}%
   \bbl@exportkey{lnbrk}{typography.linebreaking}{h}%
   \bbl@exportkey{hyphr}{typography.hyphenrules}{}%
-  \bbl@exportkey{hyoth}{typography.hyphenate.other}{}%
+  \bbl@exportkey{hyotl}{typography.hyphenate.other.locale}{}%
+  \bbl@exportkey{hyots}{typography.hyphenate.other.script}{}%
   \bbl@exportkey{intsp}{typography.intraspace}{}%
   \bbl@exportkey{jstfy}{typography.justify}{w}%
   \bbl@exportkey{chrng}{characters.ranges}{}%
@@ -10747,6 +10923,8 @@ help from Bernd Raichle, for which I am grateful.
   \bbl@csarg\def{secpre@date.gregorian.licr}{%         discard uni
     \ifcase\bbl@engine\let\bbl@savedate\@empty\fi}
 \fi
+% TODO. With the following there is no need to ensure if \select...
+\newcommand\localedate{\@nameuse{bbl@date@\languagename}}
 % eg: 1=months, 2=wide, 3=1, 4=dummy
 \def\bbl@inidate#1.#2.#3.#4\relax#5#6{% TODO - ignore with 'captions'
   \bbl@trim@def\bbl@tempa{#1.#2}%
@@ -10813,9 +10991,13 @@ help from Bernd Raichle, for which I am grateful.
   \bbl@replace\bbl@toreplace{[y]}{\BabelDatey{####1}}%
   \bbl@replace\bbl@toreplace{[yy]}{\BabelDateyy{####1}}%
   \bbl@replace\bbl@toreplace{[yyyy]}{\BabelDateyyyy{####1}}%
+  \bbl@replace\bbl@toreplace{[y|}{\bbl@datecntr[####1|}%
+  \bbl@replace\bbl@toreplace{[m|}{\bbl@datecntr[####2|}%
+  \bbl@replace\bbl@toreplace{[d|}{\bbl@datecntr[####3|}%
 % Note after \bbl@replace \toks@ contains the resulting string.
 % TODO - Using this implicit behavior doesn't seem a good idea.
   \bbl@replace@finish@iii\bbl@toreplace}
+\def\bbl@datecntr[#1|#2]{\localenumeral{#2}{#1}}
 %    \end{macrocode}
 %
 % Language and Script values to be used when defining a font or
@@ -10854,7 +11036,8 @@ help from Bernd Raichle, for which I am grateful.
   \def\BabelBeforeIni##1##2{%
     \begingroup
       \bbl@add\bbl@secpost@identification{\closein\bbl@readstream }%
-      \catcode`\[=12 \catcode`\]=12 \catcode`\==12 \catcode`\;=12 %
+      \catcode`\[=12 \catcode`\]=12 \catcode`\==12
+      \catcode`\;=12 \catcode`\|=12 %
       \bbl@read@ini{##1}{font and identification data}%   
       \endinput          % babel- .tex may contain onlypreamble's
     \endgroup}%            boxed, to avoid extra spaces:
@@ -10882,11 +11065,13 @@ help from Bernd Raichle, for which I am grateful.
 % number of digits in the number to be converted. This explains the
 % reverse set |76543210|. Digits above 10000 are not handled yet. When
 % the key contains the subkey |.F.|, the number after is treated as an
-% special case. for a fixed form (see |babel-he.ini|, for example).
+% special case, for a fixed form (see |babel-he.ini|, for example).
 %
 %    \begin{macrocode}
 \newcommand\localenumeral[2]{\bbl@cs{cntr@#1@\languagename}{#2}}
 \def\bbl@localecntr#1#2{\localenumeral{#2}{#1}}
+% TODO. \localecounter{digits}{..} What a mistake on my part!!
+% But the solution seems even logical ;-)
 \newcommand\localecounter[2]{%
   \expandafter\bbl@localecntr\csname c@#2\endcsname{#1}}
 \def\bbl@alphnumeral#1#2{%
@@ -10905,7 +11090,7 @@ help from Bernd Raichle, for which I am grateful.
      \bbl@cs{cntr@#1.3@\languagename}#6%
      \bbl@cs{cntr@#1.2@\languagename}#7%
      \bbl@cs{cntr@#1.1@\languagename}#8%
-     \ifnum#6#7#8>\z@ % An ad hod rule for Greek. Ugly. To be fixed.
+     \ifnum#6#7#8>\z@ % TODO. An ad hoc rule for Greek. Ugly.
        \bbl@ifunset{bbl@cntr@#1.S.321@\languagename}{}%
          {\bbl@cs{cntr@#1.S.321@\languagename}}%
      \fi}%
@@ -11464,63 +11649,13 @@ help from Bernd Raichle, for which I am grateful.
 %
 %    \begin{macrocode}
 %<<*More package options>>
-\ifodd\bbl@engine
-  \DeclareOption{bidi=basic-r}%
-    {\ExecuteOptions{bidi=basic}}
-  \DeclareOption{bidi=basic}%
-    {\let\bbl@beforeforeign\leavevmode
-     % TODO - to locale_props, not as separate attribute
-     \newattribute\bbl@attr@dir
-     % I don't like it, hackish:
-     \frozen@everymath\expandafter{%
-       \expandafter\bbl@mathboxdir\the\frozen@everymath}%
-     \frozen@everydisplay\expandafter{%
-       \expandafter\bbl@mathboxdir\the\frozen@everydisplay}%
-     \bbl@exp{\output{\bodydir\pagedir\the\output}}%
-     \AtEndOfPackage{\EnableBabelHook{babel-bidi}}}
-\else
-  \DeclareOption{bidi=basic-r}%
-    {\ExecuteOptions{bidi=basic}}
-  \DeclareOption{bidi=basic}%
-    {\bbl@error
-      {The bidi method `basic' is available only in\\%
-       luatex. I'll continue with `bidi=default', so\\%
-       expect wrong results}%
-      {See the manual for further details.}%
-    \let\bbl@beforeforeign\leavevmode
-    \AtEndOfPackage{%
-      \EnableBabelHook{babel-bidi}%
-      \bbl@xebidipar}}
-  \def\bbl@loadxebidi#1{%
-    \ifx\RTLfootnotetext\@undefined
-      \AtEndOfPackage{% 
-        \EnableBabelHook{babel-bidi}%
-        \ifx\fontspec\@undefined
-          \usepackage{fontspec}% bidi needs fontspec 
-        \fi
-        \usepackage#1{bidi}}%
-    \fi}
-  \DeclareOption{bidi=bidi}%
-    {\bbl@tentative{bidi=bidi}%
-     \bbl@loadxebidi{}}
-  \DeclareOption{bidi=bidi-r}%
-    {\bbl@tentative{bidi=bidi-r}%
-     \bbl@loadxebidi{[rldocument]}}
-  \DeclareOption{bidi=bidi-l}%
-    {\bbl@tentative{bidi=bidi-l}%
-     \bbl@loadxebidi{}}
-\fi
-\DeclareOption{bidi=default}%
-  {\let\bbl@beforeforeign\leavevmode
-   \ifodd\bbl@engine
-     \newattribute\bbl@attr@dir
-     \bbl@exp{\output{\bodydir\pagedir\the\output}}%
-   \fi
-   \AtEndOfPackage{%
-     \EnableBabelHook{babel-bidi}%
-     \ifodd\bbl@engine\else
-       \bbl@xebidipar
-     \fi}}
+\chardef\bbl@bidimode\z@
+\DeclareOption{bidi=default}{\chardef\bbl@bidimode=\@ne}
+\DeclareOption{bidi=basic}{\chardef\bbl@bidimode=101 }
+\DeclareOption{bidi=basic-r}{\chardef\bbl@bidimode=102 }
+\DeclareOption{bidi=bidi}{\chardef\bbl@bidimode=201 }
+\DeclareOption{bidi=bidi-r}{\chardef\bbl@bidimode=202 }
+\DeclareOption{bidi=bidi-l}{\chardef\bbl@bidimode=203 }
 %<</More package options>>
 %    \end{macrocode}
 %
@@ -11780,7 +11915,7 @@ help from Bernd Raichle, for which I am grateful.
 %    \begin{macrocode}
 %<<*Footnote changes>>
 \bbl@trace{Bidi footnotes}
-\ifx\bbl@beforeforeign\leavevmode
+\ifnum\bbl@bidimode>\z@
   \def\bbl@footnote#1#2#3{%
     \@ifnextchar[%
       {\bbl@footnote@o{#1}{#2}{#3}}%
@@ -12278,6 +12413,7 @@ help from Bernd Raichle, for which I am grateful.
 \endgroup
 \ifx\newattribute\@undefined\else
   \newattribute\bbl@attr@locale
+  \directlua{ Babel.attr_locale = luatexbase.registernumber'bbl@attr@locale'}
   \AddBabelHook{luatex}{beforeextras}{%
     \setattribute\bbl@attr@locale\localeid}
 \fi
@@ -12774,8 +12910,8 @@ end
 \let\bbl@chprop@bmg\bbl@chprop@mirror
 \def\bbl@chprop@linebreak#1{%
   \directlua{
-    Babel.Babel.cjk_characters[\the\count@] = Babel.Babel.cjk_characters[\the\count@] or {}
-    Babel.Babel.cjk_characters[\the\count@]['c'] = '#1'
+    Babel.cjk_characters[\the\count@] = Babel.cjk_characters[\the\count@] or {}
+    Babel.cjk_characters[\the\count@]['c'] = '#1'
   }}
 \let\bbl@chprop@lb\bbl@chprop@linebreak
 \def\bbl@chprop@locale#1{%
@@ -12814,7 +12950,8 @@ end
 \catcode`\%=12
 \catcode`\&=14
 \directlua{
-  Babel.linebreaking.replacements = {}
+  Babel.linebreaking.post_replacements = {}
+  Babel.linebreaking.pre_replacements = {}
 
   function Babel.str_to_nodes(fn, matches, base)
     local n, head, last    
@@ -12840,24 +12977,29 @@ end
     local word_nodes = {}
     local lang
     local item = head
+    local inmath = false
 
     while item do
 
       if item.id == 29
           and not(item.char == 124) &% ie, not |
           and not(item.char == 61)  &% ie, not =
+          and not inmath
           and (item.lang == lang or lang == nil) then
         lang = lang or item.lang
         word_string = word_string .. unicode.utf8.char(item.char)
         word_nodes[#word_nodes+1] = item
 
-      elseif item.id == 7 and item.subtype == 2 then
+      elseif item.id == 7 and item.subtype == 2 and not inmath then
         word_string = word_string .. '='
         word_nodes[#word_nodes+1] = item
 
-      elseif item.id == 7 and item.subtype == 3 then
+      elseif item.id == 7 and item.subtype == 3 and not inmath then
         word_string = word_string .. '|'       
         word_nodes[#word_nodes+1] = item
+        
+      elseif item.id == node.id'math' then
+        inmath = (item.subtype == 0)
 
       elseif word_string == '' then
         &% pass
@@ -12872,7 +13014,7 @@ end
 
   function Babel.post_hyphenate_replace(head)
     local u = unicode.utf8
-    local lbkr = Babel.linebreaking.replacements
+    local lbkr = Babel.linebreaking.post_replacements
     local word_head = head
 
     while true do
@@ -12977,6 +13119,152 @@ end
     end  &% for words
     return head
   end
+  
+  &%%%
+  &% Preliminary code for \babelprehyphenation
+  &% TODO. Copypaste pattern. Merge with fetch_word
+  function Babel.fetch_subtext(head, funct)
+    local word_string = ''
+    local word_nodes = {}
+    local lang
+    local item = head
+    local inmath = false
+
+    while item do
+
+      if item.id == 29 then     
+        local locale = node.get_attribute(item, Babel.attr_locale)
+
+        if not(item.char == 124) &% ie, not | = space
+            and not inmath
+            and (locale == lang or lang == nil) then
+          lang = lang or locale
+          word_string = word_string .. unicode.utf8.char(item.char)
+          word_nodes[#word_nodes+1] = item
+        end
+
+        if item == node.tail(head) then 
+          item = nil
+          return word_string, word_nodes, item, lang
+        end
+
+      elseif item.id == 12 and item.subtype == 13 and not inmath then
+        word_string = word_string .. '|'       
+        word_nodes[#word_nodes+1] = item
+
+        if item == node.tail(head) then 
+          item = nil
+          return word_string, word_nodes, item, lang
+        end
+      
+      elseif item.id == node.id'math' then
+        inmath = (item.subtype == 0)
+
+      elseif word_string == '' then
+        &% pass
+
+      else
+        return word_string, word_nodes, item, lang
+      end
+
+      item = item.next
+    end
+  end
+  
+  &% TODO. Copypaste pattern. Merge with pre_hyphenate_replace
+  function Babel.pre_hyphenate_replace(head)
+    local u = unicode.utf8
+    local lbkr = Babel.linebreaking.pre_replacements
+    local word_head = head
+
+    while true do
+      local w, wn, nw, lang = Babel.fetch_subtext(word_head)
+      if not lang then return head end
+
+      if not lbkr[lang] then
+        break
+      end
+
+      for k=1, #lbkr[lang] do
+        local p = lbkr[lang][k].pattern 
+        local r = lbkr[lang][k].replace
+
+        while true do
+          local matches = { u.match(w, p) }
+          if #matches < 2 then break end
+
+          local first = table.remove(matches, 1)
+          local last =  table.remove(matches, #matches)
+
+          &% Fix offsets, from bytes to unicode.
+          first = u.len(w:sub(1, first-1)) + 1
+          last  = u.len(w:sub(1, last-1))
+
+          local new  &% used when inserting and removing nodes
+          local changed = 0
+
+          &% This loop traverses the replace list and takes the
+          &% corresponding actions
+          for q = first, last do   
+            local crep = r[q-first+1]
+            local char_node = wn[q]
+            local char_base = char_node
+
+            if crep and crep.data then
+              char_base = wn[crep.data+first-1]
+            end
+
+            if crep == {} then
+              break
+            elseif crep == nil then
+              changed = changed + 1
+              node.remove(head, char_node)
+            elseif crep and crep.string then
+              changed = changed + 1
+              local str = crep.string(matches)
+              if str == '' then 
+                if q == 1 then
+                  word_head = char_node.next
+                end
+                head, new = node.remove(head, char_node)
+              elseif char_node.id == 29 and u.len(str) == 1 then
+                char_node.char = string.utfvalue(str)
+              else
+                local n
+                for s in string.utfvalues(str) do
+                  if char_node.id == 7 then
+                    log('Automatic hyphens cannot be replaced, just removed.')
+                  else
+                    n = node.copy(char_base)
+                  end
+                  n.char = s
+                  if q == 1 then
+                    head, new = node.insert_before(head, char_node, n)   
+                    word_head = new
+                  else 
+                    node.insert_before(head, char_node, n)   
+                  end
+                end
+
+                node.remove(head, char_node)
+              end  &% string length
+            end  &% if char and char.string
+          end  &% for char in match
+          if changed > 20 then
+            texio.write('Too many changes. Ignoring the rest.')
+          elseif changed > 0 then
+            &% For one-to-one can we modifiy directly the
+            &% values without re-fetching? Very likely.
+            w, wn, nw = Babel.fetch_subtext(word_head)   
+          end
+
+        end  &% for match
+      end  &% for patterns
+      word_head = nw
+    end  &% for words
+    return head
+  end
+  &%%% end of preliminary code for \babelprehyphenation
 
   &% The following functions belong to the next macro
 
@@ -13011,7 +13299,6 @@ end
     return "]]..Babel.capt_map(m[" .. capno .. "]," ..
            (mlen) .. ").." .. "[["
   end
-
 }
 %    \end{macrocode}
 %
@@ -13048,10 +13335,10 @@ end
            tex.print([[\string\babeltempa{{]] .. rep .. [[}}]])
          }}}&%
     \directlua{
-      local lbkr = Babel.linebreaking.replacements
+      local lbkr = Babel.linebreaking.post_replacements
       local u = unicode.utf8
       &% Convert pattern:
-      local patt = string.gsub([[#2]], '%s', '')
+      local patt = string.gsub([==[#2]==], '%s', '')
       if not u.find(patt, '()', nil, true) then
         patt = '()' .. patt .. '()'
       end
@@ -13064,18 +13351,53 @@ end
                    { pattern = patt, replace = { \babeltempb } })
     }&%
   \endgroup}
+% TODO. Working !!! Copypaste pattern. 
+\gdef\babelprehyphenation#1#2#3{&%
+  \bbl@activateprehyphen
+  \begingroup
+    \def\babeltempa{\bbl@add@list\babeltempb}&%
+    \let\babeltempb\@empty
+    \bbl@foreach{#3}{&%
+      \bbl@ifsamestring{##1}{remove}&%
+        {\bbl@add@list\babeltempb{nil}}&%
+        {\directlua{
+           local rep = [[##1]]
+           rep = rep:gsub('(string)%s*=%s*([^%s,]*)', Babel.capture_func)
+           tex.print([[\string\babeltempa{{]] .. rep .. [[}}]])
+         }}}&%
+    \directlua{
+      local lbkr = Babel.linebreaking.pre_replacements
+      local u = unicode.utf8
+      &% Convert pattern:
+      local patt = string.gsub([==[#2]==], '%s', '')
+      if not u.find(patt, '()', nil, true) then
+        patt = '()' .. patt .. '()'
+      end
+      patt = u.gsub(patt, '{(.)}', 
+                function (n)
+                  return '%' .. (tonumber(n) and (tonumber(n)+1) or n)
+                end)
+      lbkr[\the\csname bbl@id@@#1\endcsname] = lbkr[\the\csname  bbl@id@@#1\endcsname] or {}
+      table.insert(lbkr[\the\csname bbl@id@@#1\endcsname],
+                   { pattern = patt, replace = { \babeltempb } })
+    }&%
+  \endgroup}
 \endgroup
 \def\bbl@activateposthyphen{%
   \let\bbl@activateposthyphen\relax
   \directlua{
     Babel.linebreaking.add_after(Babel.post_hyphenate_replace)
   }}
+% TODO. Working !!! 
+\def\bbl@activateprehyphen{%
+  \let\bbl@activateprehyphen\relax
+  \directlua{
+    Babel.linebreaking.add_before(Babel.pre_hyphenate_replace)
+  }}
 %    \end{macrocode}
 %
 % \subsection{Layout}
 %
-% \textbf{Work in progress}.
-%
 % Unlike \xetex{}, \luatex{} requires only minimal changes for
 % right-to-left layouts, particularly in monolingual documents (the
 % engine itself reverses boxes -- including column order or headings
@@ -13107,7 +13429,7 @@ end
   \fi
 \fi
 \ifx\bbl@opt@layout\@nnil\endinput\fi  % if no layout
-\ifx\bbl@beforeforeign\leavevmode % A poor test for bidi=
+\ifnum\bbl@bidimode>\z@
   \def\bbl@nextfake#1{%  non-local changes, use always inside a group!
     \bbl@exp{%
       \mathdir\the\bodydir  
@@ -20045,6 +20367,8 @@ end
 %<*cjkdata>
 Babel = Babel or {}
 
+
+
 Babel.cjk_characters = {
   [0x0021]={c='ex'},
   [0x0024]={c='pr'},
-- 
cgit v1.2.3

