% \iffalse meta-comment
%
% Copyright 2013-2017 Javier Bezos and any individual authors
% listed elsewhere in this file.  All rights reserved.
% 
% This file is part of the Babel system.
% --------------------------------------
% 
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2003/12/01 or later.
% 
% This work has the LPPL maintenance status "maintained".
% 
% The Current Maintainer of this work is Javier Bezos.
% 
% The list of all files belonging to the Babel system is
% given in the file `manifest.bbl. See also `legal.bbl' for additional
% information.
% 
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
% \fi
% \CheckSum{795}
%
% \iffalse
%<*dtx>
\ProvidesFile{bbunicode.dtx}
       [2017/06/26 v3.11 Babel hooks for Unicode engines]
%</dtx>
%
%% File `bbunicode.dtx'
%% Babel package for LaTeX version 2e
%% Copyright (C) 2103-2017
%%           by Javier Bezos
%
%<*filedriver>
\documentclass{ltxdoc}
\font\manual=logo10 % font used for the METAFONT logo, etc.
\newcommand*\MF{{\manual META}\-{\manual FONT}}
\newcommand*{\babel}{\textsf{babel}}
\newcommand*{\langvar}{$\langle \it lang \rangle$}
\newcommand*{\note}[1]{}
\newcommand*{\pkg}[1]{\textsf{#1}}
\newcommand*{\Lopt}[1]{\textsf{#1}}
\newcommand*{\file}[1]{\texttt{#1}}
\begin{document}
 \DocInput{bbunicode.dtx}
\end{document}
%</filedriver>
% \fi
%
% \GetFileInfo{bbunicode.dtx}
% \StopEventually{}
%
% \section{Tentative font handling}
%
% A general solution is far from trivial:
% \begin{itemize}
% \item |\addfontfeature| only sets it for the current family and it's
%   not very efficient, and
% \item |\defaultfontfeatures| requires to redefine the font (and the
%   opti\texttt{}ons aren't ``orthogonal'').
% \end{itemize}
%
%    \begin{macrocode}
%<<*Font selection>>
\def\babelFSstore#1{%
  \bbl@for\bbl@tempa{#1}{%
    \edef\bbl@tempb{\noexpand\bbl@FSstore{\bbl@tempa}}
    \bbl@tempb{rm}\rmdefault\bbl@save@rmdefault
    \bbl@tempb{sf}\sfdefault\bbl@save@sfdefault
    \bbl@tempb{tt}\ttdefault\bbl@save@ttdefault}}
\def\bbl@FSstore#1#2#3#4{%
  \bbl@csarg\edef{#2default#1}{#3}%
  \expandafter\addto\csname extras#1\endcsname{%
    \let#4#3%
    \ifx#3\f@family
      \edef#3{\csname bbl@#2default#1\endcsname}%
      \fontfamily{#3}\selectfont
    \else
      \edef#3{\csname bbl@#2default#1\endcsname}%
    \fi}%
  \expandafter\addto\csname noextras#1\endcsname{%
    \ifx#3\f@family
      \fontfamily{#4}\selectfont
    \fi
    \let#3#4}}
\let\bbl@langfeatures\@empty
\def\babelFSfeatures{%
  \let\bbl@ori@fontspec\fontspec
  \renewcommand\fontspec[1][]{%
    \bbl@ori@fontspec[\bbl@langfeatures##1]}
  \let\babelFSfeatures\bbl@FSfeatures
  \babelFSfeatures}
\def\bbl@FSfeatures#1#2{%
  \expandafter\addto\csname extras#1\endcsname{%
    \babel@save\bbl@langfeatures
    \edef\bbl@langfeatures{#2,}}}
%<</Font selection>>
%    \end{macrocode}
%    \section{Hooks for XeTeX and LuaTeX}
%
%    \subsection{XeTeX}
%
%    Unfortunately, the current encoding cannot be retrieved and
%    therefore it is reset always to |utf8|, which seems a sensible
%    default.
%
%    \LaTeX{} sets many ``codes'' just before loading
%    \verb|hyphen.cfg|. That is not a problem in luatex, but in xetex
%    they must be reset to the proper value. Most of the work is done in
%    \textsf{xe(la)tex.ini}, so here we just ``undo'' some of the
%    changes done by \LaTeX. Anyway, for consistency Lua\TeX{} also
%    resets the catcodes. 
% \changes{bbunicode~1.0c}{2014/03/10}{Reset ``codes'' set by \cs{LaTeX}
%    to what xetex expects. Used also in luatex.}
% \changes{bbunicode~1.0f}{2015/12/06}{This block was assigned to
%    xetex, even in luatex. Fixed here and below.}
%    \begin{macrocode}
%<<*Restore Unicode catcodes before loading patterns>>
  \begingroup
      % Reset chars "80-"C0 to category "other", no case mapping:
    \catcode`\@=11 \count@=128
    \loop\ifnum\count@<192
      \global\uccode\count@=0 \global\lccode\count@=0
      \global\catcode\count@=12 \global\sfcode\count@=1000
      \advance\count@ by 1 \repeat
      % Other:
    \def\O ##1 {%
      \global\uccode"##1=0 \global\lccode"##1=0
      \global\catcode"##1=12 \global\sfcode"##1=1000 }%
      % Letter:
    \def\L ##1 ##2 ##3 {\global\catcode"##1=11
      \global\uccode"##1="##2
      \global\lccode"##1="##3
      % Uppercase letters have sfcode=999:
      \ifnum"##1="##3 \else \global\sfcode"##1=999 \fi }%
      % Letter without case mappings:
    \def\l ##1 {\L ##1 ##1 ##1 }%
    \l 00AA
    \L 00B5 039C 00B5
    \l 00BA
    \O 00D7
    \l 00DF
    \O 00F7
    \L 00FF 0178 00FF
  \endgroup
  \input #1\relax
%<</Restore Unicode catcodes before loading patterns>>
%    \end{macrocode}
%
% Now, the code.
%
%    \begin{macrocode}
%<*xetex>
\def\BabelStringsDefault{unicode}
\let\xebbl@stop\relax
\AddBabelHook{xetex}{encodedcommands}{%
  \def\bbl@tempa{#1}%
  \ifx\bbl@tempa\@empty
    \XeTeXinputencoding"bytes"%
  \else
    \XeTeXinputencoding"#1"%
  \fi
  \def\xebbl@stop{\XeTeXinputencoding"utf8"}}
\AddBabelHook{xetex}{stopcommands}{%
  \xebbl@stop
  \let\xebbl@stop\relax}
\AddBabelHook{xetex}{loadkernel}{%
<@Restore Unicode catcodes before loading patterns@>}
<@Font selection@>
%</xetex>
%    \end{macrocode}
%
% \subsection{LuaTeX}
%
% The new loader for luatex is based solely on |language.dat|, which
% is read on the fly. The code shouldn't be executed when the format
% is build, so we check if |\AddBabelHook| is defined. Then comes a
% modified version of the loader in |hyphen.cfg| (without the
% hyphenmins stuff, which is under the direct control of \babel).
%
% The names |\l@<language>| are defined and take some value from the
% beginning because all \texttt{ldf} files assume this for the
% corresponding language to be considered valid, but patterns are not
% loaded (except the first one). This is done later, when the language
% is first selected (which usually means when the \texttt{ldf}
% finishes). If a language has been loaded, |\bbl@hyphendata@<num>|
% exists (with the names of the files read).
%
% The default setup preloads the first language into the format. This
% is intended mainly for `english', so that it's available without
% further intervention from the user.  To avoid duplicating it, the
% following rule applies: if the ``0th'' language and the first
% language in |language.dat| have the same name then just ignore the
% latter. If there are new synonymous, the are added, but note if the
% language patterns have not been preloaded they won't at run time.
%
% Other preloaded languages could be read twice, if they has been
% preloaded into the format. This is not optimal, but it shouldn't
% happen very often -- with \luatex{} patterns are best loaded when
% the document is typeset, and the ``0th'' language is preloaded just
% for backwards compatibility.
%
% As of 1.1b, lua(e)tex is taken into account. Formerly, loading of
% patterns on the fly didn't work in this format, but with the new
% loader it does.  Unfortunately, the format is not based on \babel,
% and data could be duplicated, because languages are reassigned above
% those in the format (nothing serious, anyway). Note even with this
% format |language.dat| is used (under the principle of a single
% source), instead of |language.def|.
%
% Of course, there is room for improvements, like tools to read and
% reassign languages, which would require modifying the language list,
% and better error handling.
%
% We need catcode tables, but no format (targeted by \babel) provide a
% command to allocate them (although there are packages like
% \textsf{ctablestack}). For the moment, a dangerous approach is used
% -- just allocate a high random number and cross the fingers. To
% complicate things, \textsf{etex.sty} changes the way languages are
% allocated.
%
% \changes{bbunicode~1.0b}{2013/04/22}{luatex-hyphen is loaded with
%   require. Changes supplied by \'{E}lie Roux.}
% \changes{bbunicode~1.0c}{2014/03/10}{Defined hook for
%   `initiateactive', to fetch the next token and continue only if
%   letter or other.}
% \changes{bbunicode~1.0d}{2014/03/21}{Removed the `misfeature' for
%   `initiateactive'.}
% \changes{bbunicode~1.0e}{2015/05/10}{Use brackets instead of
%   \cs{luaescapestring}.}
% \changes{bbunicode~1.0e}{2015/07/26}{Added function addpattern
%   and modified the patterns hook.}
% \changes{bbunicode~1.1a}{2016/01/26}{New hyphenation loader for
%   luatex.}
% \changes{bbunicode~1.1b}{2016/02/05}{Also lua(e)tex.}
% \changes{bbunicode~1.1c}{2016/02/08}{Base reading of patterns on
%   number, not in name.}
% \changes{bbunicode~1.1c}{2016/02/08}{Some hacks for polyglossia. To
%   be improved.}
% \changes{bbunicode~1.1c}{2016/02/23}{Thoroughly revised.}
% \changes{bbunicode~1.1d}{2016/4/22}{Lua: Fixed a line break at
%   \cs{foreignlanguage} with unloaded patterns. Added
%   \cs{babelcatcodetablenum}, just in case.}
%
%    \begin{macrocode}
%<*luatex>
\ifx\AddBabelHook\@undefined
\begingroup
  \toks@{}
  \count@\z@ % 0=start, 1=0th, 2=normal
  \def\bbl@process@line#1#2 #3 #4 {%
    \ifx=#1%
      \bbl@process@synonym{#2}%
    \else
      \bbl@process@language{#1#2}{#3}{#4}%
    \fi
    \ignorespaces}
  \def\bbl@manylang{%
    \ifnum\bbl@last>\@ne
      \bbl@info{Non-standard hyphenation setup}%
    \fi
    \let\bbl@manylang\relax}
  \def\bbl@process@language#1#2#3{%
    \ifcase\count@
      \@ifundefined{zth@#1}{\count@\tw@}{\count@\@ne}%
    \or
      \count@\tw@
    \fi
    \ifnum\count@=\tw@
      \expandafter\addlanguage\csname l@#1\endcsname
      \language\allocationnumber
      \chardef\bbl@last\allocationnumber
      \bbl@manylang
      \let\bbl@elt\relax
      \xdef\bbl@languages{%
        \bbl@languages\bbl@elt{#1}{\the\language}{#2}{#3}}%
    \fi
    \the\toks@
    \toks@{}}
  \def\bbl@process@synonym@aux#1#2{%
    \global\expandafter\chardef\csname l@#1\endcsname#2\relax
    \let\bbl@elt\relax
    \xdef\bbl@languages{%
      \bbl@languages\bbl@elt{#1}{#2}{}{}}}%
  \def\bbl@process@synonym#1{%
    \ifcase\count@
      \toks@\expandafter{\the\toks@\relax\bbl@process@synonym{#1}}%
    \or
      \@ifundefined{zth@#1}{\bbl@process@synonym@aux{#1}{0}}{}%
    \else
      \bbl@process@synonym@aux{#1}{\the\bbl@last}%
    \fi}
  \ifx\bbl@languages\@undefined % Just a (sensible?) guess
    \chardef\l@english\z@
    \chardef\l@USenglish\z@
    \chardef\bbl@last\z@
    \global\@namedef{bbl@hyphendata@0}{{hyphen.tex}{}}
    \gdef\bbl@languages{%
      \bbl@elt{english}{0}{hyphen.tex}{}%
      \bbl@elt{USenglish}{0}{}{}}
  \else
    \global\let\bbl@languages@format\bbl@languages
    \def\bbl@elt#1#2#3#4{% Remove all except language 0
      \ifnum#2>\z@\else
        \noexpand\bbl@elt{#1}{#2}{#3}{#4}%
      \fi}%
    \xdef\bbl@languages{\bbl@languages}%
  \fi
  \def\bbl@elt#1#2#3#4{\@namedef{zth@#1}{}} % Define flags
  \bbl@languages
  \openin1=language.dat
  \ifeof1
    \bbl@warning{I couldn't find language.dat. No additional\\%
                 patterns loaded. Reported}%
  \else
    \loop
      \endlinechar\m@ne
      \read1 to \bbl@line
      \endlinechar`\^^M
      \if T\ifeof1F\fi T\relax
        \ifx\bbl@line\@empty\else
          \edef\bbl@line{\bbl@line\space\space\space}%
          \expandafter\bbl@process@line\bbl@line\relax
        \fi
    \repeat
  \fi
\endgroup
\def\bbl@get@enc#1:#2:#3\@@@{\def\bbl@hyph@enc{#2}}
\ifx\babelcatcodetablenum\@undefined
  \def\babelcatcodetablenum{5211}
\fi
\def\bbl@luapatterns#1#2{%
  \bbl@get@enc#1::\@@@
  \setbox\z@\hbox\bgroup
    \begingroup
      \ifx\catcodetable\@undefined
        \let\savecatcodetable\luatexsavecatcodetable
        \let\initcatcodetable\luatexinitcatcodetable
        \let\catcodetable\luatexcatcodetable
      \fi
      \savecatcodetable\babelcatcodetablenum\relax
      \initcatcodetable\numexpr\babelcatcodetablenum+1\relax
      \catcodetable\numexpr\babelcatcodetablenum+1\relax
      \catcode`\#=6  \catcode`\$=3 \catcode`\&=4 \catcode`\^=7
      \catcode`\_=8  \catcode`\{=1 \catcode`\}=2 \catcode`\~=13
      \catcode`\@=11 \catcode`\^^I=10 \catcode`\^^J=12
      \catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\.=12
      \catcode`\-=12 \catcode`\/=12 \catcode`\[=12 \catcode`\]=12
      \catcode`\`=12 \catcode`\'=12 \catcode`\"=12
      \input #1\relax
      \catcodetable\babelcatcodetablenum\relax
    \endgroup
    \def\bbl@tempa{#2}%
    \ifx\bbl@tempa\@empty\else
      \input #2\relax
    \fi
  \egroup}%
\def\bbl@patterns@lua#1{%
  \language=\expandafter\ifx\csname l@#1:\f@encoding\endcsname\relax
    \csname l@#1\endcsname
    \edef\bbl@tempa{#1}%
  \else
    \csname l@#1:\f@encoding\endcsname
    \edef\bbl@tempa{#1:\f@encoding}%
  \fi\relax
  \@namedef{lu@texhyphen@loaded@\the\language}{}% Temp
  \@ifundefined{bbl@hyphendata@\the\language}%
    {\def\bbl@elt##1##2##3##4{%
       \ifnum##2=\csname l@\bbl@tempa\endcsname % #2=spanish, dutch:OT1...
         \def\bbl@tempb{##3}%
         \ifx\bbl@tempb\@empty\else % if not a synonymous
           \def\bbl@tempc{{##3}{##4}}%
         \fi
         \bbl@csarg\xdef{hyphendata@##2}{\bbl@tempc}%
       \fi}%
     \bbl@languages
     \@ifundefined{bbl@hyphendata@\the\language}%
       {\bbl@info{No hyphenation patterns were set for\\%
                  language ‘\bbl@tempa’. Reported}}%
       {\expandafter\expandafter\expandafter\bbl@luapatterns
          \csname bbl@hyphendata@\the\language\endcsname}}{}}
\endinput\fi
\begingroup
\catcode`\%=12
\catcode`\'=12
\catcode`\"=12
\catcode`\:=12
\directlua{
  Babel = {}
  function Babel.bytes(line)
    return line:gsub("(.)",
      function (chr) return unicode.utf8.char(string.byte(chr)) end)
  end
  function Babel.begin_process_input()
    if luatexbase and luatexbase.add_to_callback then
      luatexbase.add_to_callback('process_input_buffer',
                                 Babel.bytes,'Babel.bytes')
    else
      Babel.callback = callback.find('process_input_buffer')
      callback.register('process_input_buffer',Babel.bytes)
    end
  end
  function Babel.end_process_input ()
    if luatexbase and luatexbase.remove_from_callback then
      luatexbase.remove_from_callback('process_input_buffer','Babel.bytes')
    else
      callback.register('process_input_buffer',Babel.callback)
    end
  end
  function Babel.addpatterns(pp, lg)
    local lg = lang.new(lg)
    local pats = lang.patterns(lg) or ''
    lang.clear_patterns(lg)
    for p in pp:gmatch('[^%s]+') do
      ss = ''
      for i in string.utfcharacters(p:gsub('%d', '')) do
         ss = ss .. '%d?' .. i
      end
      ss = ss:gsub('^%%d%?%.', '%%.') .. '%d?'
      ss = ss:gsub('%.%%d%?$', '%%.')
      pats, n = pats:gsub('%s' .. ss .. '%s', ' ' .. p .. ' ')
      if n == 0 then
        tex.sprint(
          [[\string\csname\space bbl@info\endcsname{New pattern: ]]
          .. p .. [[}]])
        pats = pats .. ' ' .. p
      else
        tex.sprint(
          [[\string\csname\space bbl@info\endcsname{Renew pattern: ]]
          .. p .. [[}]])
      end
    end
    lang.patterns(lg, pats)
  end
}
\endgroup
\def\BabelStringsDefault{unicode}
\let\luabbl@stop\relax
\AddBabelHook{luatex}{encodedcommands}{%
  \def\bbl@tempa{utf8}\def\bbl@tempb{#1}%
  \ifx\bbl@tempa\bbl@tempb\else
    \directlua{Babel.begin_process_input()}%
    \def\luabbl@stop{%
      \directlua{Babel.end_process_input()}}%
  \fi}%
\AddBabelHook{luatex}{stopcommands}{%
  \luabbl@stop
  \let\luabbl@stop\relax}
\AddBabelHook{luatex}{patterns}{%
  \@ifundefined{bbl@hyphendata@\the\language}%
    {\def\bbl@elt##1##2##3##4{%
       \ifnum##2=\csname l@#2\endcsname % #2=spanish, dutch:OT1...
         \def\bbl@tempb{##3}%
         \ifx\bbl@tempb\@empty\else % if not a synonymous
           \def\bbl@tempc{{##3}{##4}}%
         \fi
         \bbl@csarg\xdef{hyphendata@##2}{\bbl@tempc}%
       \fi}%
     \bbl@languages
     \@ifundefined{bbl@hyphendata@\the\language}%
       {\bbl@info{No hyphenation patterns were set for\\%
                  language ‘#2’. Reported}}%
       {\expandafter\expandafter\expandafter\bbl@luapatterns
          \csname bbl@hyphendata@\the\language\endcsname}}{}%
  \@ifundefined{bbl@patterns@}{}{%
    \begingroup
      \@expandtwoargs\in@{,\number\language,}{,\bbl@pttnlist}%
      \ifin@\else
        \ifx\bbl@patterns@\@empty\else
           \directlua{ Babel.addpatterns(
             [[\bbl@patterns@]], \number\language) }%
        \fi
        \@ifundefined{bbl@patterns@#1}%
          \@empty
          {\directlua{ Babel.addpatterns(
               [[\space\csname bbl@patterns@#1\endcsname]],
               \number\language) }}%
        \xdef\bbl@pttnlist{\bbl@pttnlist\number\language,}%
      \fi
    \endgroup}}
\AddBabelHook{luatex}{everylanguage}{%
  \def\process@language##1##2##3{%
    \def\process@line####1####2 ####3 ####4 {}}}
\AddBabelHook{luatex}{loadpatterns}{%
   \input #1\relax
   \expandafter\gdef\csname bbl@hyphendata@\the\language\endcsname
     {{#1}{}}}
\AddBabelHook{luatex}{loadexceptions}{%
   \input #1\relax
   \def\bbl@tempb##1##2{{##1}{#1}}%
   \expandafter\xdef\csname bbl@hyphendata@\the\language\endcsname
     {\expandafter\expandafter\expandafter\bbl@tempb
      \csname bbl@hyphendata@\the\language\endcsname}}
%    \end{macrocode}
%
%  \begin{macro}{\babelpatterns}
%
%    This macro adds patterns. Two macros are used to store them:
%    |\bbl@patterns@| for the global ones and |\bbl@patterns@<lang>|
%    for language ones. We make sure there is a space between words
%    when multiple commands are used.
% \changes{bbunicode~1.0e}{2015/07/26}{Macro \cs{babelpatterns} added}
%
%    \begin{macrocode}
\@onlypreamble\babelpatterns
\AtEndOfPackage{%
  \newcommand\babelpatterns[2][\@empty]{%
    \ifx\bbl@patterns@\relax
      \let\bbl@patterns@\@empty
    \fi
    \ifx\bbl@pttnlist\@empty\else
      \bbl@warning{%
        You must not intermingle \string\selectlanguage\space and\\%
        \string\babelpatterns\space or some patterns will not\\%
        be taken into account. Reported}%
    \fi
    \ifx\@empty#1%
      \protected@edef\bbl@patterns@{\bbl@patterns@\space#2}%
    \else
      \edef\bbl@tempb{\zap@space#1 \@empty}%
      \bbl@for\bbl@tempa\bbl@tempb{%
        \bbl@fixname\bbl@tempa
        \bbl@iflanguage\bbl@tempa{%
          \bbl@csarg\protected@edef{patterns@\bbl@tempa}{%
            \@ifundefined{bbl@patterns@\bbl@tempa}%
              \@empty
              {\csname bbl@patterns@\bbl@tempa\endcsname\space}%
            #2}}}%
    \fi}}
%    \end{macrocode}
%  \end{macro}
%
% Common stuff.
%
%    \begin{macrocode}
\AddBabelHook{luatex}{loadkernel}{%
<@Restore Unicode catcodes before loading patterns@>}
<@Font selection@>
%</luatex>
%    \end{macrocode}
%
\endinput
%%
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
