From c682a2af4035b8fc25ef591f11edb7e57bd51179 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Thu, 14 Oct 2021 03:01:09 +0000 Subject: CTAN sync 202110140301 --- macros/latex/required/babel/base/babel.dtx | 11076 +++++++++++++-------------- 1 file changed, 5508 insertions(+), 5568 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 28b1a76683..6fe5db94f2 100644 --- a/macros/latex/required/babel/base/babel.dtx +++ b/macros/latex/required/babel/base/babel.dtx @@ -32,7 +32,7 @@ % % \iffalse %<*filedriver> -\ProvidesFile{babel.dtx}[2021/07/22 v3.63 The Babel package] +\ProvidesFile{babel.dtx}[2021/10/13 v3.64 The Babel package] \documentclass{ltxdoc} \GetFileInfo{babel.dtx} \usepackage{fontspec} @@ -788,9 +788,11 @@ group. |\text...| is heavily overloaded in \LaTeX{} and conflicts with existing macros may arise (|\textlatin|, |\textbar|, |\textit|, |\textcolor| and many others). The same applies to environments, - because |arabic| conflicts with |\arabic|. Except if there is a - reason for this ‘syntactical sugar’, the best option is to stick to - the default selectors or to define your own alternatives. + because |arabic| conflicts with |\arabic|. Furthermore, and because of + this overloading, detecting the language of a chunk of text by + external tools can become unfeasible. Except if there is a reason for + this ‘syntactical sugar’, the best option is to stick to the default + selectors or to define your own alternatives. \end{warning} \begin{example} @@ -2278,7 +2280,7 @@ to select fonts in addition to the three basic families. \textit{Package fontspec Warning: 'Language 'LANG' not available for font 'FONT' with script 'SCRIPT' 'Default' language used instead'}. - \textbf{This is \textit{not} and error.} This warning is shown by + \textbf{This is \textit{not} an error.} This warning is shown by \textsf{fontspec}, not by \babel. It can be irrelevant for English, but not for many other languages, including Urdu and Turkish. This is a useful and harmless warning, and if everything is fine with your @@ -2290,7 +2292,7 @@ to select fonts in addition to the three basic families. standard families} \textit{Package babel Info: The following fonts are not babel standard families}. - \textbf{This is \textit{not} and error.} \babel{} assumes that if you + \textbf{This is \textit{not} an error.} \babel{} assumes that if you are using |\babelfont| for a family, very likely you want to define the rest of them. If you don't, you can find some inconsistencies between families. This checking is done at the beginning of the @@ -4859,7 +4861,7 @@ corresponding place. A selective list follows: \item Active chars where not reset at the end of language options, and that lead to incompatibilities between languages. -\item |\textormath| raised and error with a conditional. +\item |\textormath| raised an error with a conditional. \item |\aliasshorthand| didn't work (or only in a few and very specific cases). @@ -5024,8 +5026,8 @@ help from Bernd Raichle, for which I am grateful. % \section{Tools} % % \begin{macrocode} -%<> -%<> +%<> +%<> % \end{macrocode} % % \textbf{Do not use the following macros in \texttt{ldf} files. They @@ -5111,9 +5113,13 @@ help from Bernd Raichle, for which I am grateful. \def\bbl@exp#1{% \begingroup \let\\\noexpand - \def\<##1>{\expandafter\noexpand\csname##1\endcsname}% + \let\<\bbl@exp@en + \let\[\bbl@exp@ue \edef\bbl@exp@aux{\endgroup#1}% \bbl@exp@aux} +\def\bbl@exp@en#1>{\expandafter\noexpand\csname#1\endcsname}% +\def\bbl@exp@ue#1]{% + \unexpanded\expandafter\expandafter\expandafter{\csname#1\endcsname}}% % \end{macrocode} % \end{macro} % @@ -5146,7 +5152,7 @@ help from Bernd Raichle, for which I am grateful. % \begin{macro}{\bbl@ifunset} % To check if a macro is defined, we create a new macro, which does % the same as |\@ifundefined|. However, in an $\epsilon$-tex engine, -% it is based on |\ifcsname|, which is more efficient, and do not +% it is based on |\ifcsname|, which is more efficient, and does not % waste memory. % % \begin{macrocode} @@ -5157,7 +5163,7 @@ help from Bernd Raichle, for which I am grateful. \else \expandafter\@secondoftwo \fi} - \bbl@ifunset{ifcsname}% + \bbl@ifunset{ifcsname}% TODO. A better test? {}% {\gdef\bbl@ifunset#1{% \ifcsname#1\endcsname @@ -5358,7 +5364,8 @@ help from Bernd Raichle, for which I am grateful. % % The following adds some code to |\extras...| both before and after, % while avoiding doing it twice. It's somewhat convoluted, to deal with -% |#|'s. +% |#|'s. Used to deal with alph, Alph and frenchspacing when there are +% already changes (with |\babel@save|). % % \begin{macrocode} \def\bbl@extras@wrap#1#2#3{% 1:in-test, 2:before, 3:after @@ -5446,21 +5453,16 @@ help from Bernd Raichle, for which I am grateful. % % \subsection{The Package File (\LaTeX, \texttt{babel.sty})} % -% This file also takes care of a number of compatibility issues with -% other packages an defines a few aditional package options. Apart from -% all the language options below we also have a few options that -% influence the behavior of language definition files. -% -% Many of the following options don't do anything themselves, they are -% just defined in order to make it possible for babel and language -% definition files to check if one of them was specified by the user. -% -% The first two options are for debugging. -% % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e}[2005/12/01] \ProvidesPackage{babel}[<@date@> <@version@> The Babel package] +% \end{macrocode} +% +% Start with some “private” debugging tool, and then define macros for +% errors. +% +% \begin{macrocode} \@ifpackagewith{babel}{debug} {\providecommand\bbl@trace[1]{\message{^^J[ #1 ]}}% \let\bbl@debug\@firstofone @@ -5475,64 +5477,43 @@ help from Bernd Raichle, for which I am grateful. \directlua{ Babel = Babel or {} Babel.debug = false }% \fi} +\def\bbl@error#1#2{% + \begingroup + \def\\{\MessageBreak}% + \PackageError{babel}{#1}{#2}% + \endgroup} +\def\bbl@warning#1{% + \begingroup + \def\\{\MessageBreak}% + \PackageWarning{babel}{#1}% + \endgroup} +\def\bbl@infowarn#1{% + \begingroup + \def\\{\MessageBreak}% + \GenericWarning + {(babel) \@spaces\@spaces\@spaces}% + {Package babel Info: #1}% + \endgroup} +\def\bbl@info#1{% + \begingroup + \def\\{\MessageBreak}% + \PackageInfo{babel}{#1}% + \endgroup} +% \end{macrocode} +% +% This file also takes care of a number of compatibility issues with +% other packages an defines a few aditional package options. Apart from +% all the language options below we also have a few options that +% influence the behavior of language definition files. +% +% Many of the following options don’t do anything themselves, they are +% just defined in order to make it possible for babel and language +% definition files to check if one of them was specified by the user. +% +% But first, include here the \textit{Basic macros} defined above. +% +% \begin{macrocode} <@Basic macros@> - % Temporarily repeat here the code for errors. TODO. - \def\bbl@error#1#2{% - \begingroup - \def\\{\MessageBreak}% - \PackageError{babel}{#1}{#2}% - \endgroup} - \def\bbl@warning#1{% - \begingroup - \def\\{\MessageBreak}% - \PackageWarning{babel}{#1}% - \endgroup} - \def\bbl@infowarn#1{% - \begingroup - \def\\{\MessageBreak}% - \GenericWarning - {(babel) \@spaces\@spaces\@spaces}% - {Package babel Info: #1}% - \endgroup} - \def\bbl@info#1{% - \begingroup - \def\\{\MessageBreak}% - \PackageInfo{babel}{#1}% - \endgroup} -\def\bbl@nocaption{\protect\bbl@nocaption@i} -% TODO - Wrong for \today !!! Must be a separate macro. -\def\bbl@nocaption@i#1#2{% 1: text to be printed 2: caption macro \langXname - \global\@namedef{#2}{\textbf{?#1?}}% - \@nameuse{#2}% - \edef\bbl@tempa{#1}% - \bbl@sreplace\bbl@tempa{name}{}% - \bbl@warning{% - \@backslashchar#1 not set for '\languagename'. Please,\\% - define it after the language has been loaded\\% - (typically in the preamble) with\\% - \string\setlocalecaption{\languagename}{\bbl@tempa}{..}\\% - Reported}} -\def\bbl@tentative{\protect\bbl@tentative@i} -\def\bbl@tentative@i#1{% - \bbl@warning{% - Some functions for '#1' are tentative.\\% - They might not work as expected and their behavior\\% - may change in the future.\\% - Reported}} -\def\@nolanerr#1{% - \bbl@error - {You haven't defined the language '#1' yet.\\% - Perhaps you misspelled it or your installation\\% - is not complete}% - {Your command will be ignored, type to proceed}} -\def\@nopatterns#1{% - \bbl@warning - {No hyphenation patterns were preloaded for\\% - the language '#1' into the format.\\% - Please, configure your TeX system to add them and\\% - rebuild the format. Now I will use the patterns\\% - preloaded for \bbl@nulllanguage\space instead}} - % End of errors \@ifpackagewith{babel}{silent} {\let\bbl@info\@gobble \let\bbl@infowarn\@gobble @@ -5601,7 +5582,7 @@ help from Bernd Raichle, for which I am grateful. \global\let\@ifl@ter@@\@ifl@ter \def\@ifl@ter#1#2#3#4#5{\global\let\@ifl@ter\@ifl@ter@@}% \endinput}{}% -% \end{macrocode} +% \end{macrocode} % % \subsection{\texttt{key=value} options and other general option} % @@ -5714,8 +5695,12 @@ help from Bernd Raichle, for which I am grateful. \bbl@xin@{\string=}{\CurrentOption}% \ifin@ \expandafter\bbl@tempa\CurrentOption\bbl@tempa - \else - \bbl@add@list\bbl@language@opts{\CurrentOption}% + \else + \bbl@xin@{,\CurrentOption,}{,\bbl@language@opts,}% + \ifin@ + \bbl@exp{\\\bbl@replace\\\bbl@language@opts{,\CurrentOption,}{}}% + \fi + \edef\bbl@language@opts{\bbl@language@opts,\CurrentOption,} \fi} % \end{macrocode} % @@ -5726,8 +5711,16 @@ help from Bernd Raichle, for which I am grateful. % \end{macrocode} % % \begin{macrocode} -\ifx\bbl@opt@provide\@nnil\else % Tests. Ignore. +\ifx\bbl@opt@provide\@nnil + \let\bbl@opt@provide\@empty % %%% MOVE above +\else \chardef\bbl@iniflag\@ne + \bbl@exp{\\\bbl@forkv{\@nameuse{@raw@opt@babel.sty}}}{% + \in@{,provide,}{,#1,}% + \ifin@ + \def\bbl@opt@provide{#2}% + \bbl@replace\bbl@opt@provide{;}{,}% + \fi} \fi % % \end{macrocode} @@ -5813,10 +5806,13 @@ help from Bernd Raichle, for which I am grateful. \ifx\bbl@opt@safe\@undefined \def\bbl@opt@safe{BR} \fi +% \end{macrocode} +% +% Make sure the language set with `main` is the last one. +% +% \begin{macrocode} \ifx\bbl@opt@main\@nnil\else - \edef\bbl@language@opts{% - \ifx\bbl@language@opts\@empty\else\bbl@language@opts,\fi - \bbl@opt@main} + \edef\bbl@language@opts{\bbl@language@opts,\bbl@opt@main,} \fi % \end{macrocode} % @@ -5837,6463 +5833,6355 @@ help from Bernd Raichle, for which I am grateful. \expandafter\@secondoftwo \fi} \fi +% +%<*core> % \end{macrocode} % -% \textbf{Common definitions.} \textit{In progress.} Still based on -% |babel.def|, but the code should be moved here. -% -% \begin{macrocode} -\input babel.def -% \end{macrocode} -% -% \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. -% -% When a cross referencing command processes its argument, all -% tokens in this argument should be character tokens with category -% `letter' or `other'. +% \subsection{Interlude for Plain} % -% The following package options control which macros are to be -% redefined. +% Because of the way \pkg{docstrip} works, we need to insert some code +% for Plain here. However, the tools provided by the \babel{} +% installer for literate programming makes this section a short +% interlude, because the actual code is below, tagged as +% \textit{Emulate LaTeX}. % % \begin{macrocode} -%<<*More package options>> -\DeclareOption{safe=none}{\let\bbl@opt@safe\@empty} -\DeclareOption{safe=bib}{\def\bbl@opt@safe{B}} -\DeclareOption{safe=ref}{\def\bbl@opt@safe{R}} -%<> +\ifx\ldf@quit\@undefined\else +\endinput\fi % Same line! +<@Make sure ProvidesFile is defined@> +\ProvidesFile{babel.def}[<@date@> <@version@> Babel common definitions] +\ifx\AtBeginDocument\@undefined % TODO. change test. + <@Emulate LaTeX@> +\fi % \end{macrocode} % -% \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. +% That is all for the moment. Now follows some common stuff, for both +% Plain and \LaTeX{}. After it, we will resume the \LaTeX-only stuff. % % \begin{macrocode} -\bbl@trace{Cross referencing macros} -\ifx\bbl@opt@safe\@empty\else - \def\@newl@bel#1#2#3{% - {\@safe@activestrue - \bbl@ifunset{#1@#2}% - \relax - {\gdef\@multiplelabels{% - \@latex@warning@no@line{There were multiply-defined labels}}% - \@latex@warning@no@line{Label `#2' multiply defined}}% - \global\@namedef{#1@#2}{#3}}} +% +%<*package|core> % \end{macrocode} % -% \end{macro} +% \section{Multiple languages} % -% \begin{macro}{\@testdef} +% This is not a separate file (\texttt{switch.def}) anymore. % -% 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. +% 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. % % \begin{macrocode} - \CheckCommand*\@testdef[3]{% - \def\reserved@a{#3}% - \expandafter\ifx\csname#1@#2\endcsname\reserved@a - \else - \@tempswatrue - \fi} +\def\bbl@version{<@version@>} +\def\bbl@date{<@date@>} +<@Define core switching macros@> % \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. +% \begin{macro}{\adddialect} +% The macro |\adddialect| can be used to add the name of a dialect +% or variant language, for which an already defined hyphenation +% table can be used. % % \begin{macrocode} - \def\@testdef#1#2#3{% TODO. With @samestring? - \@safe@activestrue - \expandafter\let\expandafter\bbl@tempa\csname #1@#2\endcsname - \def\bbl@tempb{#3}% - \@safe@activesfalse - \ifx\bbl@tempa\relax - \else - \edef\bbl@tempa{\expandafter\strip@prefix\meaning\bbl@tempa}% - \fi - \edef\bbl@tempb{\expandafter\strip@prefix\meaning\bbl@tempb}% - \ifx\bbl@tempa\bbl@tempb - \else - \@tempswatrue - \fi} -\fi +\def\adddialect#1#2{% + \global\chardef#1#2\relax + \bbl@usehooks{adddialect}{{#1}{#2}}% + \begingroup + \count@#1\relax + \def\bbl@elt##1##2##3##4{% + \ifnum\count@=##2\relax + \edef\bbl@tempa{\expandafter\@gobbletwo\string#1}% + \bbl@info{Hyphen rules for '\expandafter\@gobble\bbl@tempa' + set to \expandafter\string\csname l@##1\endcsname\\% + (\string\language\the\count@). Reported}% + \def\bbl@elt####1####2####3####4{}% + \fi}% + \bbl@cs{languages}% + \endgroup} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\ref} -% \begin{macro}{\pageref} +% |\bbl@iflanguage| executes code only if the language |l@| +% exists. Otherwise raises an error. % -% 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 argument of |\bbl@fixname| has to be a macro name, as it may get +% ``fixed'' if casing (lc/uc) is wrong. It's an attempt to fix a +% long-standing bug when |\foreignlanguage| and the like appear in +% a |\MakeXXXcase|. However, a lowercase form is not imposed to +% improve backward compatibility (perhaps you defined a language +% named |MYLANG|, but unfortunately mixed case names cannot be +% trapped). Note |l@| is encapsulated, so that its case does not +% change. % % \begin{macrocode} -\bbl@xin@{R}\bbl@opt@safe -\ifin@ - \bbl@redefinerobust\ref#1{% - \@safe@activestrue\org@ref{#1}\@safe@activesfalse} - \bbl@redefinerobust\pageref#1{% - \@safe@activestrue\org@pageref{#1}\@safe@activesfalse} -\else - \let\org@ref\ref - \let\org@pageref\pageref -\fi +\def\bbl@fixname#1{% + \begingroup + \def\bbl@tempe{l@}% + \edef\bbl@tempd{\noexpand\@ifundefined{\noexpand\bbl@tempe#1}}% + \bbl@tempd + {\lowercase\expandafter{\bbl@tempd}% + {\uppercase\expandafter{\bbl@tempd}% + \@empty + {\edef\bbl@tempd{\def\noexpand#1{#1}}% + \uppercase\expandafter{\bbl@tempd}}}% + {\edef\bbl@tempd{\def\noexpand#1{#1}}% + \lowercase\expandafter{\bbl@tempd}}}% + \@empty + \edef\bbl@tempd{\endgroup\def\noexpand#1{#1}}% + \bbl@tempd + \bbl@exp{\\\bbl@usehooks{languagename}{{\languagename}{#1}}}} +\def\bbl@iflanguage#1{% + \@ifundefined{l@#1}{\@nolanerr{#1}\@gobble}\@firstofone} % \end{macrocode} % -% \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. +% After a name has been ‘fixed’, the selectors will try to load the +% language. If even the fixed name is not defined, will load it on the +% fly, either based on its name, or if activated, its BCP47 code. % -% \begin{macrocode} -\bbl@xin@{B}\bbl@opt@safe -\ifin@ - \bbl@redefine\@citex[#1]#2{% - \@safe@activestrue\edef\@tempa{#2}\@safe@activesfalse - \org@@citex[#1]{\@tempa}} +% We first need a couple of macros for a simple BCP 47 look up. It also +% makes sure, with |\bbl@bcpcase|, casing is the correct one, so that +% sr-latn-ba becomes fr-Latn-BA. Note |#4| may contain some +% |\@empty|'s, but they are eventually removed. |\bbl@bcplookup| either +% returns the found |ini| or it is |\relax|. +% +% \begin{macrocode} +\def\bbl@bcpcase#1#2#3#4\@@#5{% + \ifx\@empty#3% + \uppercase{\def#5{#1#2}}% + \else + \uppercase{\def#5{#1}}% + \lowercase{\edef#5{#5#2#3#4}}% + \fi} +\def\bbl@bcplookup#1-#2-#3-#4\@@{% + \let\bbl@bcp\relax + \lowercase{\def\bbl@tempa{#1}}% + \ifx\@empty#2% + \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% + \else\ifx\@empty#3% + \bbl@bcpcase#2\@empty\@empty\@@\bbl@tempb + \IfFileExists{babel-\bbl@tempa-\bbl@tempb.ini}% + {\edef\bbl@bcp{\bbl@tempa-\bbl@tempb}}% + {}% + \ifx\bbl@bcp\relax + \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% + \fi + \else + \bbl@bcpcase#2\@empty\@empty\@@\bbl@tempb + \bbl@bcpcase#3\@empty\@empty\@@\bbl@tempc + \IfFileExists{babel-\bbl@tempa-\bbl@tempb-\bbl@tempc.ini}% + {\edef\bbl@bcp{\bbl@tempa-\bbl@tempb-\bbl@tempc}}% + {}% + \ifx\bbl@bcp\relax + \IfFileExists{babel-\bbl@tempa-\bbl@tempc.ini}% + {\edef\bbl@bcp{\bbl@tempa-\bbl@tempc}}% + {}% + \fi + \ifx\bbl@bcp\relax + \IfFileExists{babel-\bbl@tempa-\bbl@tempc.ini}% + {\edef\bbl@bcp{\bbl@tempa-\bbl@tempc}}% + {}% + \fi + \ifx\bbl@bcp\relax + \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% + \fi + \fi\fi} +\let\bbl@initoload\relax +\def\bbl@provide@locale{% + \ifx\babelprovide\@undefined + \bbl@error{For a language to be defined on the fly 'base'\\% + is not enough, and the whole package must be\\% + loaded. Either delete the 'base' option or\\% + request the languages explicitly}% + {See the manual for further details.}% + \fi +% TODO. Option to search if loaded, with \LocaleForEach + \let\bbl@auxname\languagename % Still necessary. TODO + \bbl@ifunset{bbl@bcp@map@\languagename}{}% Move uplevel?? + {\edef\languagename{\@nameuse{bbl@bcp@map@\languagename}}}% + \ifbbl@bcpallowed + \expandafter\ifx\csname date\languagename\endcsname\relax + \expandafter + \bbl@bcplookup\languagename-\@empty-\@empty-\@empty\@@ + \ifx\bbl@bcp\relax\else % Returned by \bbl@bcplookup + \edef\languagename{\bbl@bcp@prefix\bbl@bcp}% + \edef\localename{\bbl@bcp@prefix\bbl@bcp}% + \expandafter\ifx\csname date\languagename\endcsname\relax + \let\bbl@initoload\bbl@bcp + \bbl@exp{\\\babelprovide[\bbl@autoload@bcpoptions]{\languagename}}% + \let\bbl@initoload\relax + \fi + \bbl@csarg\xdef{bcp@map@\bbl@bcp}{\localename}% + \fi + \fi + \fi + \expandafter\ifx\csname date\languagename\endcsname\relax + \IfFileExists{babel-\languagename.tex}% + {\bbl@exp{\\\babelprovide[\bbl@autoload@options]{\languagename}}}% + {}% + \fi} % \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. +% \begin{macro}{\iflanguage} +% Users might want to test (in a private package for instance) +% which language is currently active. For this we provide a test +% macro, |\iflanguage|, that has three arguments. It checks +% whether the first argument is a known language. If so, it +% compares the first argument with the value of |\language|. Then, +% depending on the result of the comparison, it executes either the +% second or the third argument. % % \begin{macrocode} - \AtBeginDocument{% - \@ifpackageloaded{natbib}{% +\def\iflanguage#1{% + \bbl@iflanguage{#1}{% + \ifnum\csname l@#1\endcsname=\language + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi}} % \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). +% \end{macro} % -% (Recent versions of \pkg{natbib} change dynamically |\@citex|, so PR4087 -% doesn't seem fixable in a simple way. Just load \pkg{natbib} before.) +% \subsection{Selecting the language} % -% \begin{macrocode} - \def\@citex[#1][#2]#3{% - \@safe@activestrue\edef\@tempa{#3}\@safe@activesfalse - \org@@citex[#1][#2]{\@tempa}}% - }{}} -% \end{macrocode} +% \begin{macro}{\selectlanguage} % -% The package \pkg{cite} has a definition of |\@citex| where the -% shorthands need to be turned off in both arguments. +% The macro |\selectlanguage| checks whether the language is +% already defined before it performs its actual task, which is to +% update |\language| and activate language-specific definitions. % % \begin{macrocode} - \AtBeginDocument{% - \@ifpackageloaded{cite}{% - \def\@citex[#1]#2{% - \@safe@activestrue\org@@citex[#1]{#2}\@safe@activesfalse}% - }{}} +\let\bbl@select@type\z@ +\edef\selectlanguage{% + \noexpand\protect + \expandafter\noexpand\csname selectlanguage \endcsname} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\nocite} -% -% The macro |\nocite| which is used to instruct BiB\TeX\ to -% extract uncited references from the database. +% Because the command |\selectlanguage| could be used in a moving +% argument it expands to \verb*=\protect\selectlanguage =. +% Therefore, we have to make sure that a macro |\protect| exists. +% If it doesn't it is |\let| to |\relax|. % % \begin{macrocode} - \bbl@redefine\nocite#1{% - \@safe@activestrue\org@nocite{#1}\@safe@activesfalse} +\ifx\@undefined\protect\let\protect\relax\fi % \end{macrocode} % -% \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. +% The following definition is preserved for backwards compatibility +% (eg, \textsf{arabi}, \textsf{koma}). It is related to a trick for +% 2.09, now discarded. % % \begin{macrocode} - \bbl@redefine\bibcite{% - \bbl@cite@choice - \bibcite} +\let\xstring\string % \end{macrocode} % -% \end{macro} +% \end{macro} % -% \begin{macro}{\bbl@bibcite} +% Since version 3.5 \babel\ writes entries to the auxiliary files in +% order to typeset table of contents etc. in the correct language +% environment. % -% The macro |\bbl@bibcite| holds the definition of |\bibcite| -% needed when neither \pkg{natbib} nor \pkg{cite} is loaded. +% \begin{macro}{\bbl@pop@language} +% +% \emph{But} when the language change happens \emph{inside} a group +% the end of the group doesn't write anything to the auxiliary +% files. Therefore we need \TeX's |aftergroup| mechanism to help +% us. The command |\aftergroup| stores the token immediately +% following it to be executed when the current group is closed. So +% we define a temporary control sequence |\bbl@pop@language| to be +% executed at the end of the group. It calls |\bbl@set@language| +% with the name of the current language as its argument. +% +% \begin{macro}{\bbl@language@stack} +% The previous solution works for one level of nesting groups, but +% as soon as more levels are used it is no longer adequate. For +% that case we need to keep track of the nested languages using a +% stack mechanism. This stack is called |\bbl@language@stack| and +% initially empty. % % \begin{macrocode} - \def\bbl@bibcite#1#2{% - \org@bibcite{#1}{\@safe@activesfalse#2}} +\def\bbl@language@stack{} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\bbl@cite@choice} +% When using a stack we need a mechanism to push an element on the +% stack and to retrieve the information afterwards. % -% The macro |\bbl@cite@choice| determines which definition of -% |\bibcite| is needed. First we give |\bibcite| its default -% definition. +% \begin{macro}{\bbl@push@language} +% \begin{macro}{\bbl@pop@language} +% The stack is simply a list of languagenames, separated with a `+' +% sign; the push function can be simple: % % \begin{macrocode} - \def\bbl@cite@choice{% - \global\let\bibcite\bbl@bibcite - \@ifpackageloaded{natbib}{\global\let\bibcite\org@bibcite}{}% - \@ifpackageloaded{cite}{\global\let\bibcite\org@bibcite}{}% - \global\let\bbl@cite@choice\relax} +\def\bbl@push@language{% + \ifx\languagename\@undefined\else + \ifx\currentgrouplevel\@undefined + \xdef\bbl@language@stack{\languagename+\bbl@language@stack}% + \else + \ifnum\currentgrouplevel=\z@ + \xdef\bbl@language@stack{\languagename+}% + \else + \xdef\bbl@language@stack{\languagename+\bbl@language@stack}% + \fi + \fi + \fi} % \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. +% Retrieving information from the stack is a little bit less simple, as +% we need to remove the element from the stack while storing it in the +% macro |\languagename|. For this we first define a helper function. +% \begin{macro}{\bbl@pop@lang} +% This macro stores its first element (which is delimited by the +% `+'-sign) in |\languagename| and stores the rest of the string +% in |\bbl@language@stack|. % % \begin{macrocode} - \AtBeginDocument{\bbl@cite@choice} +\def\bbl@pop@lang#1+#2\@@{% + \edef\languagename{#1}% + \xdef\bbl@language@stack{#2}} % \end{macrocode} % % \end{macro} -% -% \begin{macro}{\@bibitem} -% -% One of the two internal \LaTeX\ macros called by |\bibitem| -% that write the citation label on the |.aux| file. +% The reason for the somewhat weird arrangement of arguments to the +% helper function is the fact it is called in the following way. +% This means that before |\bbl@pop@lang| is executed \TeX\ first +% \emph{expands} the stack, stored in |\bbl@language@stack|. The +% result of that is that the argument string of |\bbl@pop@lang| +% contains one or more language names, each followed by a `+'-sign +% (zero language names won't occur as this macro will only be +% called after something has been pushed on the stack). % % \begin{macrocode} - \bbl@redefine\@bibitem#1{% - \@safe@activestrue\org@@bibitem{#1}\@safe@activesfalse} -\else - \let\org@nocite\nocite - \let\org@@citex\@citex - \let\org@bibcite\bibcite - \let\org@@bibitem\@bibitem -\fi +\let\bbl@ifrestoring\@secondoftwo +\def\bbl@pop@language{% + \expandafter\bbl@pop@lang\bbl@language@stack\@@ + \let\bbl@ifrestoring\@firstoftwo + \expandafter\bbl@set@language\expandafter{\languagename}% + \let\bbl@ifrestoring\@secondoftwo} % \end{macrocode} % +% Once the name of the previous language is retrieved from the stack, +% it is fed to |\bbl@set@language| to do the actual work of +% switching everything that needs switching. +% \end{macro} +% \end{macro} % \end{macro} % -% \subsection{Marks} -% -% \begin{macro}{\markright} -% Because the output routine is asynchronous, we must pass the -% current language attribute to the head lines. To achieve this we -% need to adapt the definition of |\markright| and |\markboth| -% somewhat. However, headlines and footlines can contain text -% outside marks; for that we must take some actions in the output -% routine if the 'headfoot' options is used. -% -% We need to make some redefinitions to the output routine -% to avoid an endless loop and to correctly handle the page number -% in bidi documents. +% An alternative way to identify languages (in the \babel{} sense) +% with a numerical value is introduced in 3.30. This is one of the +% first steps for a new interface based on the concept of locale, +% which explains the name of |\localeid|. This means |\l@...| will be +% reserved for hyphenation patterns (so that two locales can share the +% same rules). % % \begin{macrocode} -\bbl@trace{Marks} -\IfBabelLayout{sectioning} - {\ifx\bbl@opt@headfoot\@nnil - \g@addto@macro\@resetactivechars{% - \set@typeset@protect - \expandafter\select@language@x\expandafter{\bbl@main@language}% - \let\protect\noexpand - \ifcase\bbl@bidimode\else % Only with bidi. See also above - \edef\thepage{% - \noexpand\babelsublr{\unexpanded\expandafter{\thepage}}}% - \fi}% - \fi} - {\ifbbl@single\else - \bbl@ifunset{markright }\bbl@redefine\bbl@redefinerobust - \markright#1{% - \bbl@ifblank{#1}% - {\org@markright{}}% - {\toks@{#1}% - \bbl@exp{% - \\\org@markright{\\\protect\\\foreignlanguage{\languagename}% - {\\\protect\\\bbl@restore@actives\the\toks@}}}}}% +\chardef\localeid\z@ +\def\bbl@id@last{0} % No real need for a new counter +\def\bbl@id@assign{% + \bbl@ifunset{bbl@id@@\languagename}% + {\count@\bbl@id@last\relax + \advance\count@\@ne + \bbl@csarg\chardef{id@@\languagename}\count@ + \edef\bbl@id@last{\the\count@}% + \ifcase\bbl@engine\or + \directlua{ + Babel = Babel or {} + Babel.locale_props = Babel.locale_props or {} + Babel.locale_props[\bbl@id@last] = {} + Babel.locale_props[\bbl@id@last].name = '\languagename' + }% + \fi}% + {}% + \chardef\localeid\bbl@cl{id@}} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\markboth} -% \begin{macro}{\@mkboth} -% The definition of |\markboth| is equivalent to that of -% |\markright|, except that we need two token registers. The -% documentclasses \cls{report} and \cls{book} define and set the -% headings for the page. While doing so they also store a copy of -% |\markboth| in |\@mkboth|. Therefore we need to check whether -% |\@mkboth| has already been set. If so we neeed to do that again -% with the new definition of |\markboth|. (As of Oct 2019, \LaTeX{} -% stores the definition in an intermediate macro, so it's not -% necessary anymore, but it's preserved for older versions.) +% The unprotected part of |\selectlanguage|. % % \begin{macrocode} - \ifx\@mkboth\markboth - \def\bbl@tempc{\let\@mkboth\markboth} - \else - \def\bbl@tempc{} - \fi - \bbl@ifunset{markboth }\bbl@redefine\bbl@redefinerobust - \markboth#1#2{% - \protected@edef\bbl@tempb##1{% - \protect\foreignlanguage - {\languagename}{\protect\bbl@restore@actives##1}}% - \bbl@ifblank{#1}% - {\toks@{}}% - {\toks@\expandafter{\bbl@tempb{#1}}}% - \bbl@ifblank{#2}% - {\@temptokena{}}% - {\@temptokena\expandafter{\bbl@tempb{#2}}}% - \bbl@exp{\\\org@markboth{\the\toks@}{\the\@temptokena}}} - \bbl@tempc - \fi} % end ifbbl@single, end \IfBabelLayout +\expandafter\def\csname selectlanguage \endcsname#1{% + \ifnum\bbl@hymapsel=\@cclv\let\bbl@hymapsel\tw@\fi + \bbl@push@language + \aftergroup\bbl@pop@language + \bbl@set@language{#1}} % \end{macrocode} % % \end{macro} -% \end{macro} % -% \subsection{Preventing clashes with other packages} +% \begin{macro}{\bbl@set@language} % -% \subsubsection{\pkg{ifthen}} +% The macro |\bbl@set@language| takes care of switching the language +% environment \emph{and} of writing entries on the auxiliary files. +% For historial reasons, language names can be either |language| of +% |\language|. To catch either form a trick is used, but +% unfortunately as a side effect the catcodes of letters in +% |\languagename| are messed up. This is a bug, but preserved for +% backwards compatibility. The list of auxiliary files can be +% extended by redefining |\BabelContentsFiles|, but make sure they +% are loaded inside a group (as |aux|, |toc|, |lof|, and |lot| do) +% or the last language of the document will remain active +% afterwards. % -% \begin{macro}{\ifthenelse} +% We also write a command to change the current language in the +% auxiliary files. % -% 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. +% |\bbl@savelastskip| is used to deal with skips before the write +% whatsit (as suggested by U Fischer). Adapted from \textsf{hyperref}, +% but it might fail, so I'll consider it a temporary hack, while I +% study other options (the ideal, but very likely unfeasible except +% perhaps in \luatex, is to avoid the |\write| altogether when not +% needed). % -% 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. +% \begin{macrocode} +\def\BabelContentsFiles{toc,lof,lot} +\def\bbl@set@language#1{% from selectlanguage, pop@ + % The old buggy way. Preserved for compatibility. + \edef\languagename{% + \ifnum\escapechar=\expandafter`\string#1\@empty + \else\string#1\@empty\fi}% + \ifcat\relax\noexpand#1% + \expandafter\ifx\csname date\languagename\endcsname\relax + \edef\languagename{#1}% + \let\localename\languagename + \else + \bbl@info{Using '\string\language' instead of 'language' is\\% + deprecated. If what you want is to use a\\% + macro containing the actual locale, make\\% + sure it does not not match any language.\\% + Reported}% + \ifx\scantokens\@undefined + \def\localename{??}% + \else + \scantokens\expandafter{\expandafter + \def\expandafter\localename\expandafter{\languagename}}% + \fi + \fi + \else + \def\localename{#1}% This one has the correct catcodes + \fi + \select@language{\languagename}% + % write to auxs + \expandafter\ifx\csname date\languagename\endcsname\relax\else + \if@filesw + \ifx\babel@aux\@gobbletwo\else % Set if single in the first, redundant + \bbl@savelastskip + \protected@write\@auxout{}{\string\babel@aux{\bbl@auxname}{}}% + \bbl@restorelastskip + \fi + \bbl@usehooks{write}{}% + \fi + \fi} % -% 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. +\let\bbl@restorelastskip\relax +\let\bbl@savelastskip\relax % -% \begin{macrocode} -\bbl@trace{Preventing clashes with other packages} -\bbl@xin@{R}\bbl@opt@safe -\ifin@ - \AtBeginDocument{% - \@ifpackageloaded{ifthen}{% - \bbl@redefine@long\ifthenelse#1#2#3{% - \let\bbl@temp@pref\pageref - \let\pageref\org@pageref - \let\bbl@temp@ref\ref - \let\ref\org@ref - \@safe@activestrue - \org@ifthenelse{#1}% - {\let\pageref\bbl@temp@pref - \let\ref\bbl@temp@ref - \@safe@activesfalse - #2}% - {\let\pageref\bbl@temp@pref - \let\ref\bbl@temp@ref - \@safe@activesfalse - #3}% - }% - }{}% - } +\newif\ifbbl@bcpallowed +\bbl@bcpallowedfalse +\def\select@language#1{% from set@, babel@aux + % set hymap + \ifnum\bbl@hymapsel=\@cclv\chardef\bbl@hymapsel4\relax\fi + % set name + \edef\languagename{#1}% + \bbl@fixname\languagename + % TODO. name@map must be here? + \bbl@provide@locale + \bbl@iflanguage\languagename{% + \expandafter\ifx\csname date\languagename\endcsname\relax + \bbl@error + {Unknown language '\languagename'. Either you have\\% + misspelled its name, it has not been installed,\\% + or you requested it in a previous run. Fix its name,\\% + install it or just rerun the file, respectively. In\\% + some cases, you may need to remove the aux file}% + {You may proceed, but expect wrong results}% + \else + % set type + \let\bbl@select@type\z@ + \expandafter\bbl@switch\expandafter{\languagename}% + \fi}} +\def\babel@aux#1#2{% + \select@language{#1}% + \bbl@foreach\BabelContentsFiles{% \relax -> don't assume vertical mode + \@writefile{##1}{\babel@toc{#1}{#2}\relax}}}% TODO - plain? +\def\babel@toc#1#2{% + \select@language{#1}} % \end{macrocode} % % \end{macro} % -% \subsubsection{\pkg{varioref}} -% -% \begin{macro}{\@@vpageref} -% \begin{macro}{\vrefpagenum} -% \begin{macro}{\Ref} +% First, check if the user asks for a known language. If so, +% update the value of |\language| and call |\originalTeX| +% to bring \TeX\ in a certain pre-defined state. % -% 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|. +% The name of the language is stored in the control sequence +% |\languagename|. % -% \begin{macrocode} - \AtBeginDocument{% - \@ifpackageloaded{varioref}{% - \bbl@redefine\@@vpageref#1[#2]#3{% - \@safe@activestrue - \org@@@vpageref{#1}[#2]{#3}% - \@safe@activesfalse}% - \bbl@redefine\vrefpagenum#1#2{% - \@safe@activestrue - \org@vrefpagenum{#1}{#2}% - \@safe@activesfalse}% -% \end{macrocode} +% Then we have to \emph{re}define |\originalTeX| to compensate for +% the things that have been activated. To save memory space for +% the macro definition of |\originalTeX|, we construct the control +% sequence name for the |\noextras|\langvar\ command at definition +% time by expanding the |\csname| primitive. % -% 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. +% Now activate the language-specific definitions. This is done by +% constructing the names of three macros by concatenating three +% words with the argument of |\selectlanguage|, and calling these +% macros. \nb{What if \cs{hyphenation} was used in |extras|? Patch +% temporarily |\set@hyphenmins| and hyphenation. It can be done in +% hooks if necessary.} +% +% The switching of the values of |\lefthyphenmin| and +% |\righthyphenmin| is somewhat different. First we save their +% current values, then we check if |\|\langvar|hyphenmins| is +% defined. If it is not, we set default values (2 and 3), otherwise +% the values in |\|\langvar|hyphenmins| will be used. % % \begin{macrocode} - \expandafter\def\csname Ref \endcsname#1{% - \protected@edef\@tempa{\org@ref{#1}}\expandafter\MakeUppercase\@tempa} - }{}% - } -\fi +\newif\ifbbl@usedategroup +\def\bbl@switch#1{% from select@, foreign@ + % make sure there is info for the language if so requested + \bbl@ensureinfo{#1}% + % restore + \originalTeX + \expandafter\def\expandafter\originalTeX\expandafter{% + \csname noextras#1\endcsname + \let\originalTeX\@empty + \babel@beginsave}% + \bbl@usehooks{afterreset}{}% + \languageshorthands{none}% + % set the locale id + \bbl@id@assign + % switch captions, date + % No text is supposed to be added here, so we remove any + % spurious spaces. + \bbl@bsphack + \ifcase\bbl@select@type + \csname captions#1\endcsname\relax + \csname date#1\endcsname\relax + \else + \bbl@xin@{,captions,}{,\bbl@select@opts,}% + \ifin@ + \csname captions#1\endcsname\relax + \fi + \bbl@xin@{,date,}{,\bbl@select@opts,}% + \ifin@ % if \foreign... within \date + \csname date#1\endcsname\relax + \fi + \fi + \bbl@esphack + % switch extras + \bbl@usehooks{beforeextras}{}% + \csname extras#1\endcsname\relax + \bbl@usehooks{afterextras}{}% + % > babel-ensure + % > babel-sh- + % > babel-bidi + % > babel-fontspec + % hyphenation - case mapping + \ifcase\bbl@opt@hyphenmap\or + \def\BabelLower##1##2{\lccode##1=##2\relax}% + \ifnum\bbl@hymapsel>4\else + \csname\languagename @bbl@hyphenmap\endcsname + \fi + \chardef\bbl@opt@hyphenmap\z@ + \else + \ifnum\bbl@hymapsel>\bbl@opt@hyphenmap\else + \csname\languagename @bbl@hyphenmap\endcsname + \fi + \fi + \let\bbl@hymapsel\@cclv + % hyphenation - select rules + \ifnum\csname l@\languagename\endcsname=\l@unhyphenated + \edef\bbl@tempa{u}% + \else + \edef\bbl@tempa{\bbl@cl{lnbrk}}% + \fi + % linebreaking - handle u, e, k (v in the future) + \bbl@xin@{/u}{/\bbl@tempa}% + \ifin@\else\bbl@xin@{/e}{/\bbl@tempa}\fi % elongated forms + \ifin@\else\bbl@xin@{/k}{/\bbl@tempa}\fi % only kashida + \ifin@\else\bbl@xin@{/v}{/\bbl@tempa}\fi % variable font + \ifin@ + % unhyphenated/kashida/elongated = allow stretching + \language\l@unhyphenated + \babel@savevariable\emergencystretch + \emergencystretch\maxdimen + \babel@savevariable\hbadness + \hbadness\@M + \else + % other = select patterns + \bbl@patterns{#1}% + \fi + % hyphenation - mins + \babel@savevariable\lefthyphenmin + \babel@savevariable\righthyphenmin + \expandafter\ifx\csname #1hyphenmins\endcsname\relax + \set@hyphenmins\tw@\thr@@\relax + \else + \expandafter\expandafter\expandafter\set@hyphenmins + \csname #1hyphenmins\endcsname\relax + \fi} % \end{macrocode} % -% \end{macro} -% \end{macro} -% \end{macro} +% \begin{environment}{otherlanguage} +% The \Lenv{otherlanguage} environment can be used as an +% alternative to using the |\selectlanguage| declarative +% command. When you are typesetting a document which mixes +% left-to-right and right-to-left typesetting you have to use this +% environment in order to let things work as you expect them to. % -% \subsubsection{\pkg{hhline}} +% The |\ignorespaces| command is necessary to hide the environment +% when it is entered in horizontal mode. % -% \begin{macro}{\hhline} +% \begin{macrocode} +\long\def\otherlanguage#1{% + \ifnum\bbl@hymapsel=\@cclv\let\bbl@hymapsel\thr@@\fi + \csname selectlanguage \endcsname{#1}% + \ignorespaces} +% \end{macrocode} % -% 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. +% The |\endotherlanguage| part of the environment tries to hide +% itself when it is called in horizontal mode. % % \begin{macrocode} -\AtEndOfPackage{% - \AtBeginDocument{% - \@ifpackageloaded{hhline}% - {\expandafter\ifx\csname normal@char\string:\endcsname\relax - \else - \makeatletter - \def\@currname{hhline}\input{hhline.sty}\makeatother - \fi}% - {}}} +\long\def\endotherlanguage{% + \global\@ignoretrue\ignorespaces} % \end{macrocode} % -% \end{macro} +% \end{environment} % -% \subsubsection{\pkg{hyperref}} +% \begin{environment}{otherlanguage*} +% The \Lenv{otherlanguage} environment is meant to be used when a +% large part of text from a different language needs to be typeset, +% but without changing the translation of words such as `figure'. +% This environment makes use of |\foreign@language|. % -% \begin{macro}{\pdfstringdefDisableCommands} +% \begin{macrocode} +\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 + \def\bbl@select@opts{#1}% + \foreign@language{#2}} +% \end{macrocode} % -% 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? Commented out in 2020/07/27. +% At the end of the environment we need to switch off the extra +% definitions. The grouping mechanism of the environment will take +% care of resetting the correct hyphenation rules and ``extras''. % % \begin{macrocode} -% \AtBeginDocument{% -% \ifx\pdfstringdefDisableCommands\@undefined\else -% \pdfstringdefDisableCommands{\languageshorthands{system}}% -% \fi} +\expandafter\let\csname endotherlanguage*\endcsname\relax % \end{macrocode} % -% \end{macro} +% \end{environment} % -% \subsubsection{\pkg{fancyhdr}} +% \begin{macro}{\foreignlanguage} % -% \begin{macro}{\FOREIGNLANGUAGE} +% The |\foreignlanguage| command is another substitute for the +% |\selectlanguage| command. This command takes two arguments, the +% first argument is the name of the language to use for typesetting +% the text specified in the second argument. % -% 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. +% Unlike |\selectlanguage| this command doesn't switch +% \emph{everything}, it only switches the hyphenation rules and the +% extra definitions for the language specified. It does this within +% a group and assumes the |\extras|\langvar\ command doesn't make +% any |\global| changes. The coding is very similar to part of +% |\selectlanguage|. % -% \begin{macrocode} -\DeclareRobustCommand{\FOREIGNLANGUAGE}[1]{% - \lowercase{\foreignlanguage{#1}}} -% \end{macrocode} +% |\bbl@beforeforeign| is a trick to fix a bug in bidi +% texts. |\foreignlanguage| is supposed to be a `text' command, and +% therefore it must emit a |\leavevmode|, but it does not, and +% therefore the indent is placed on the opposite margin. For +% backward compatibility, however, it is done only if a +% right-to-left script is requested; otherwise, it is no-op. % -% \end{macro} +% (3.11) |\foreignlanguage*| is a temporary, experimental macro for +% a few lines with a different script direction, while preserving +% the paragraph format (thank the braces around |\par|, things like +% |\hangindent| are not reset). Do not use it in production, +% because its semantics and its syntax may change (and very likely +% will, or even it could be removed altogether). Currently it +% enters in vmode and then selects the language (which in turn sets the +% paragraph direction). % -% \begin{macro}{\substitutefontfamily} +% (3.11) Also experimental are the hook |foreign| and |foreign*|. +% With them you can redefine |\BabelText| which by default does +% nothing. Its behavior is not well defined yet. So, use it in +% horizontal mode only if you do not want surprises. % -% 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. +% In other words, at the beginning of a paragraph |\foreignlanguage| +% enters into hmode with the surrounding lang, and with +% |\foreignlanguage*| with the new lang. % % \begin{macrocode} -\def\substitutefontfamily#1#2#3{% - \lowercase{\immediate\openout15=#1#2.fd\relax}% - \immediate\write15{% - \string\ProvidesFile{#1#2.fd}% - [\the\year/\two@digits{\the\month}/\two@digits{\the\day} - \space generated font description file]^^J - \string\DeclareFontFamily{#1}{#2}{}^^J - \string\DeclareFontShape{#1}{#2}{m}{n}{<->ssub * #3/m/n}{}^^J - \string\DeclareFontShape{#1}{#2}{m}{it}{<->ssub * #3/m/it}{}^^J - \string\DeclareFontShape{#1}{#2}{m}{sl}{<->ssub * #3/m/sl}{}^^J - \string\DeclareFontShape{#1}{#2}{m}{sc}{<->ssub * #3/m/sc}{}^^J - \string\DeclareFontShape{#1}{#2}{b}{n}{<->ssub * #3/bx/n}{}^^J - \string\DeclareFontShape{#1}{#2}{b}{it}{<->ssub * #3/bx/it}{}^^J - \string\DeclareFontShape{#1}{#2}{b}{sl}{<->ssub * #3/bx/sl}{}^^J - \string\DeclareFontShape{#1}{#2}{b}{sc}{<->ssub * #3/bx/sc}{}^^J - }% - \closeout15 - } -\@onlypreamble\substitutefontfamily -% \end{macrocode} -% -% \end{macro} -% -% \subsection{Encoding and fonts} +\providecommand\bbl@beforeforeign{} +\edef\foreignlanguage{% + \noexpand\protect + \expandafter\noexpand\csname foreignlanguage \endcsname} +\expandafter\def\csname foreignlanguage \endcsname{% + \@ifstar\bbl@foreign@s\bbl@foreign@x} +\providecommand\bbl@foreign@x[3][]{% + \begingroup + \def\bbl@select@opts{#1}% + \let\BabelText\@firstofone + \bbl@beforeforeign + \foreign@language{#2}% + \bbl@usehooks{foreign}{}% + \BabelText{#3}% Now in horizontal mode! + \endgroup} +\def\bbl@foreign@s#1#2{% TODO - \shapemode, \@setpar, ?\@@par + \begingroup + {\par}% + \let\bbl@select@opts\@empty + \let\BabelText\@firstofone + \foreign@language{#1}% + \bbl@usehooks{foreign*}{}% + \bbl@dirparastext + \BabelText{#2}% Still in vertical mode! + {\par}% + \endgroup} +% \end{macrocode} % -% Because documents may use non-ASCII font encodings, we make sure -% that the logos of \TeX\ and \LaTeX\ always come out in the right -% encoding. There is a list of non-ASCII encodings. Requested -% encodings are currently stored in |\@fontenc@load@list|. If a -% non-ASCII has been loaded, we define versions of |\TeX| and |\LaTeX| -% for them using |\ensureascii|. The default ASCII encoding is set, -% too (in reverse order): the ``main'' encoding (when the document -% begins), the last loaded, or |OT1|. +% \end{macro} % -% \begin{macro}{\ensureascii} +% \begin{macro}{\foreign@language} +% +% This macro does the work for |\foreignlanguage| and the +% \Lenv{otherlanguage*} environment. First we need to store the name +% of the language and check that it is a known language. Then it +% just calls |bbl@switch|. % % \begin{macrocode} -\bbl@trace{Encoding and fonts} -\newcommand\BabelNonASCII{LGR,X2,OT2,OT3,OT6,LHE,LWN,LMA,LMC,LMS,LMU} -\newcommand\BabelNonText{TS1,T3,TS3} -\let\org@TeX\TeX -\let\org@LaTeX\LaTeX -\let\ensureascii\@firstofone -\AtBeginDocument{% - \def\@elt#1{,#1,}% - \edef\bbl@tempa{\expandafter\@gobbletwo\@fontenc@load@list}% - \let\@elt\relax - \let\bbl@tempb\@empty - \def\bbl@tempc{OT1}% - \bbl@foreach\BabelNonASCII{% LGR loaded in a non-standard way - \bbl@ifunset{T@#1}{}{\def\bbl@tempb{#1}}}% - \bbl@foreach\bbl@tempa{% - \bbl@xin@{#1}{\BabelNonASCII}% - \ifin@ - \def\bbl@tempb{#1}% Store last non-ascii - \else\bbl@xin@{#1}{\BabelNonText}% Pass - \ifin@\else - \def\bbl@tempc{#1}% Store last ascii - \fi - \fi}% - \ifx\bbl@tempb\@empty\else - \bbl@xin@{,\cf@encoding,}{,\BabelNonASCII,\BabelNonText,}% - \ifin@\else - \edef\bbl@tempc{\cf@encoding}% The default if ascii wins +\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 + \bbl@iflanguage\languagename{% + \expandafter\ifx\csname date\languagename\endcsname\relax + \bbl@warning % TODO - why a warning, not an error? + {Unknown language '#1'. Either you have\\% + misspelled its name, it has not been installed,\\% + or you requested it in a previous run. Fix its name,\\% + install it or just rerun the file, respectively. In\\% + some cases, you may need to remove the aux file.\\% + I'll proceed, but expect wrong results.\\% + Reported}% \fi - \edef\ensureascii#1{% - {\noexpand\fontencoding{\bbl@tempc}\noexpand\selectfont#1}}% - \DeclareTextCommandDefault{\TeX}{\ensureascii{\org@TeX}}% - \DeclareTextCommandDefault{\LaTeX}{\ensureascii{\org@LaTeX}}% - \fi} + % set type + \let\bbl@select@type\@ne + \expandafter\bbl@switch\expandafter{\languagename}}} % \end{macrocode} % % \end{macro} % -% Now comes the old deprecated stuff (with a little change in 3.9l, -% for \textsf{fontspec}). The first thing we need to do is to -% determine, at |\begin{document}|, which latin fontencoding to use. -% -% \begin{macro}{\latinencoding} -% When text is being typeset in an encoding other than `latin' -% (\texttt{OT1} or \texttt{T1}), it would be nice to still have -% Roman numerals come out in the Latin encoding. -% So we first assume that the current encoding at the end -% of processing the package is the Latin encoding. +% \begin{macro}{\bbl@patterns} % -% \begin{macrocode} -\AtEndOfPackage{\edef\latinencoding{\cf@encoding}} -% \end{macrocode} +% This macro selects the hyphenation patterns by changing the +% \cs{language} register. If special hyphenation patterns +% are available specifically for the current font encoding, +% use them instead of the default. % -% But this might be overruled with a later loading of the package -% \pkg{fontenc}. Therefore we check at the execution of -% |\begin{document}| whether it was loaded with the \Lopt{T1} -% option. The normal way to do this (using |\@ifpackageloaded|) is -% disabled for this package. Now we have to revert to parsing the -% internal macro |\@filelist| which contains all the filenames -% loaded. +% It also sets hyphenation exceptions, but only once, because they +% are global (here language |\lccode|'s has been set, too). +% |\bbl@hyphenation@| is set to relax until the very first +% |\babelhyphenation|, so do nothing with this value. If the +% exceptions for a language (by its number, not its name, so that +% |:ENC| is taken into account) has been set, then use +% |\hyphenation| with both global and language exceptions and empty +% the latter to mark they must not be set again. % % \begin{macrocode} -\AtBeginDocument{% - \@ifpackageloaded{fontspec}% - {\xdef\latinencoding{% - \ifx\UTFencname\@undefined - EU\ifcase\bbl@engine\or2\or1\fi - \else - \UTFencname - \fi}}% - {\gdef\latinencoding{OT1}% - \ifx\cf@encoding\bbl@t@one - \xdef\latinencoding{\bbl@t@one}% - \else - \def\@elt#1{,#1,}% - \edef\bbl@tempa{\expandafter\@gobbletwo\@fontenc@load@list}% - \let\@elt\relax - \bbl@xin@{,T1,}\bbl@tempa - \ifin@ - \xdef\latinencoding{\bbl@t@one}% - \fi - \fi}} +\let\bbl@hyphlist\@empty +\let\bbl@hyphenation@\relax +\let\bbl@pttnlist\@empty +\let\bbl@patterns@\relax +\let\bbl@hymapsel=\@cclv +\def\bbl@patterns#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 + \@expandtwoargs\bbl@usehooks{patterns}{{#1}{\bbl@tempa}}% + % > luatex + \@ifundefined{bbl@hyphenation@}{}{% Can be \relax! + \begingroup + \bbl@xin@{,\number\language,}{,\bbl@hyphlist}% + \ifin@\else + \@expandtwoargs\bbl@usehooks{hyphenation}{{#1}{\bbl@tempa}}% + \hyphenation{% + \bbl@hyphenation@ + \@ifundefined{bbl@hyphenation@#1}% + \@empty + {\space\csname bbl@hyphenation@#1\endcsname}}% + \xdef\bbl@hyphlist{\bbl@hyphlist\number\language,}% + \fi + \endgroup}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\latintext} -% Then we can define the command |\latintext| which is a -% declarative switch to a latin font-encoding. Usage of this macro -% is deprecated. +% \begin{environment}{hyphenrules} +% +% The environment \Lenv{hyphenrules} can be used to select +% \emph{just} the hyphenation rules. This environment does +% \emph{not} change |\languagename| and when the hyphenation rules +% specified were not loaded it has no effect. Note however, +% |\lccode|'s and font encodings are not set at all, so in most +% cases you should use |otherlanguage*|. % % \begin{macrocode} -\DeclareRobustCommand{\latintext}{% - \fontencoding{\latinencoding}\selectfont - \def\encodingdefault{\latinencoding}} +\def\hyphenrules#1{% + \edef\bbl@tempf{#1}% + \bbl@fixname\bbl@tempf + \bbl@iflanguage\bbl@tempf{% + \expandafter\bbl@patterns\expandafter{\bbl@tempf}% + \ifx\languageshorthands\@undefined\else + \languageshorthands{none}% + \fi + \expandafter\ifx\csname\bbl@tempf hyphenmins\endcsname\relax + \set@hyphenmins\tw@\thr@@\relax + \else + \expandafter\expandafter\expandafter\set@hyphenmins + \csname\bbl@tempf hyphenmins\endcsname\relax + \fi}} +\let\endhyphenrules\@empty % \end{macrocode} % -% \end{macro} +% \end{environment} % -% \begin{macro}{\textlatin} -% This command takes an argument which is then typeset using the -% requested font encoding. In order to avoid many encoding switches -% it operates in a local scope. +% \begin{macro}{\providehyphenmins} +% The macro |\providehyphenmins| should be used in the language +% definition files to provide a \emph{default} setting for the +% hyphenation parameters |\lefthyphenmin| and |\righthyphenmin|. If +% the macro |\|\langvar|hyphenmins| is already defined this command +% has no effect. % % \begin{macrocode} -\ifx\@undefined\DeclareTextFontCommand - \DeclareRobustCommand{\textlatin}[1]{\leavevmode{\latintext #1}} -\else - \DeclareTextFontCommand{\textlatin}{\latintext} -\fi +\def\providehyphenmins#1#2{% + \expandafter\ifx\csname #1hyphenmins\endcsname\relax + \@namedef{#1hyphenmins}{#2}% + \fi} % \end{macrocode} % -% For several functions, we need to execute some code with -% |\selectfont|. With \LaTeX\ 2021-06-01, there is a hook for this -% purpose, but in older versions the \LaTeX{} command is patched (the -% latter solution will be eventually removed). +% \end{macro} +% +% \begin{macro}{\set@hyphenmins} +% This macro sets the values of |\lefthyphenmin| and +% |\righthyphenmin|. It expects two values as its argument. % % \begin{macrocode} -\bbl@ifformatlater{2021-06-01}% - {\def\bbl@patchfont#1{\AddToHook{selectfont}{#1}}} - {\def\bbl@patchfont#1{% - \expandafter\bbl@add\csname selectfont \endcsname{#1}% - \expandafter\bbl@toglobal\csname selectfont \endcsname}} +\def\set@hyphenmins#1#2{% + \lefthyphenmin#1\relax + \righthyphenmin#2\relax} % \end{macrocode} % % \end{macro} % -% \subsection{Basic bidi support} +% \begin{macro}{\ProvidesLanguage} +% The identification code for each file is something that was +% introduced in \LaTeXe. When the command |\ProvidesFile| does not +% exist, a dummy definition is provided temporarily. For use in the +% language definition file the command |\ProvidesLanguage| is +% defined by \babel. % -% \textbf{Work in progress.} This code is currently placed here for -% practical reasons. It will be moved to the correct place soon, I -% hope. -% -% It is loosely based on |rlbabel.def|, but most of it has been -% developed from scratch. This \babel{} module (by Johannes Braams and -% Boris Lavva) has served the purpose of typesetting R documents for -% two decades, and despite its flaws I think it is still a good starting -% point (some parts have been copied here almost verbatim), partly -% thanks to its simplicity. I've also looked at \textsc{arabi} (by -% Youssef Jabri), which is compatible with \babel{}. -% -% There are two ways of modifying macros to make them “bidi”, namely, -% by patching the internal low-level macros (which is what I have done -% with lists, columns, counters, tocs, much like |rlbabel| did), and -% 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} +% Depending on the format, ie, on if the former is defined, we use +% a similar definition or not. % % \begin{macrocode} -\bbl@trace{Loading basic (internal) bidi support} -\ifodd\bbl@engine -\else % TODO. Move to txtbabel - \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 - \bbl@loadfontspec % 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@loadxebidi{[rldocument]} - \or - \bbl@loadxebidi{} - \fi - \fi -\fi -% TODO? Separate: -\ifnum\bbl@bidimode=\@ne - \let\bbl@beforeforeign\leavevmode - \ifodd\bbl@engine - \newattribute\bbl@attr@dir - \directlua{ Babel.attr_dir = luatexbase.registernumber'bbl@attr@dir' } - \bbl@exp{\output{\bodydir\pagedir\the\output}} - \fi - \AtEndOfPackage{% - \EnableBabelHook{babel-bidi}% - \ifodd\bbl@engine\else - \bbl@xebidipar - \fi} +\ifx\ProvidesFile\@undefined + \def\ProvidesLanguage#1[#2 #3 #4]{% + \wlog{Language: #1 #4 #3 <#2>}% + } +\else + \def\ProvidesLanguage#1{% + \begingroup + \catcode`\ 10 % + \@makeother\/% + \@ifnextchar[%] + {\@provideslanguage{#1}}{\@provideslanguage{#1}[]}} + \def\@provideslanguage#1[#2]{% + \wlog{Language: #1 #2}% + \expandafter\xdef\csname ver@#1.ldf\endcsname{#2}% + \endgroup} \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{% TODO. Base on codes ?? - ,Imperial Aramaic,Avestan,Cypriot,Hatran,Hebrew,% - Old Hungarian,Old Hungarian,Lydian,Mandaean,Manichaean,% - Manichaean,Meroitic Cursive,Meroitic,Old North Arabian,% - Nabataean,N'Ko,Orkhon,Palmyrene,Inscriptional Pahlavi,% - Psalter Pahlavi,Phoenician,Inscriptional Parthian,Samaritan,% - Old South Arabian,}% -\def\bbl@provide@dirs#1{% - \bbl@xin@{\csname bbl@sname@#1\endcsname}{\bbl@alscripts\bbl@rscripts}% - \ifin@ - \global\bbl@csarg\chardef{wdir@#1}\@ne - \bbl@xin@{\csname bbl@sname@#1\endcsname}{\bbl@alscripts}% - \ifin@ - \global\bbl@csarg\chardef{wdir@#1}\tw@ % useless in xetex - \fi - \else - \global\bbl@csarg\chardef{wdir@#1}\z@ - \fi - \ifodd\bbl@engine - \bbl@csarg\ifcase{wdir@#1}% - \directlua{ Babel.locale_props[\the\localeid].textdir = 'l' }% - \or - \directlua{ Babel.locale_props[\the\localeid].textdir = 'r' }% - \or - \directlua{ Babel.locale_props[\the\localeid].textdir = 'al' }% - \fi - \fi} -\def\bbl@switchdir{% - \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% - \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% - \bbl@exp{\\\bbl@setdirs\bbl@cl{wdir}}} -\def\bbl@setdirs#1{% TODO - math - \ifcase\bbl@select@type % TODO - strictly, not the right test - \bbl@bodydir{#1}% - \bbl@pardir{#1}% - \fi - \bbl@textdir{#1}} -% TODO. Only if \bbl@bidimode > 0?: -\AddBabelHook{babel-bidi}{afterextras}{\bbl@switchdir} -\DisableBabelHook{babel-bidi} -% \end{macrocode} +% \end{macro} % -% Now the engine-dependent macros. TODO. Must be moved to the engine -% files. +% \begin{macro}{\originalTeX} +% The macro|\originalTeX| should be known to \TeX\ at this moment. +% As it has to be expandable we |\let| it to |\@empty| instead of +% |\relax|. % -% \begin{macrocode} -\ifodd\bbl@engine % luatex=1 -\else % pdftex=0, xetex=2 - \newcount\bbl@dirlevel - \chardef\bbl@thetextdir\z@ - \chardef\bbl@thepardir\z@ - \def\bbl@textdir#1{% - \ifcase#1\relax - \chardef\bbl@thetextdir\z@ - \bbl@textdir@i\beginL\endL - \else - \chardef\bbl@thetextdir\@ne - \bbl@textdir@i\beginR\endR - \fi} - \def\bbl@textdir@i#1#2{% - \ifhmode - \ifnum\currentgrouplevel>\z@ - \ifnum\currentgrouplevel=\bbl@dirlevel - \bbl@error{Multiple bidi settings inside a group}% - {I'll insert a new group, but expect wrong results.}% - \bgroup\aftergroup#2\aftergroup\egroup - \else - \ifcase\currentgrouptype\or % 0 bottom - \aftergroup#2% 1 simple {} - \or - \bgroup\aftergroup#2\aftergroup\egroup % 2 hbox - \or - \bgroup\aftergroup#2\aftergroup\egroup % 3 adj hbox - \or\or\or % vbox vtop align - \or - \bgroup\aftergroup#2\aftergroup\egroup % 7 noalign - \or\or\or\or\or\or % output math disc insert vcent mathchoice - \or - \aftergroup#2% 14 \begingroup - \else - \bgroup\aftergroup#2\aftergroup\egroup % 15 adj - \fi - \fi - \bbl@dirlevel\currentgrouplevel - \fi - #1% - \fi} - \def\bbl@pardir#1{\chardef\bbl@thepardir#1\relax} - \let\bbl@bodydir\@gobble - \let\bbl@pagedir\@gobble - \def\bbl@dirparastext{\chardef\bbl@thepardir\bbl@thetextdir} +% \begin{macrocode} +\ifx\originalTeX\@undefined\let\originalTeX\@empty\fi % \end{macrocode} % -% The following command is executed only if there is a right-to-left -% script (once). It activates the |\everypar| hack for \xetex, to -% properly handle the par direction. Note text and par dirs are -% decoupled to some extent (although not completely). +% Because this part of the code can be included in a format, we +% make sure that the macro which initializes the save mechanism, +% |\babel@beginsave|, is not considered to be undefined. % % \begin{macrocode} - \def\bbl@xebidipar{% - \let\bbl@xebidipar\relax - \TeXXeTstate\@ne - \def\bbl@xeeverypar{% - \ifcase\bbl@thepardir - \ifcase\bbl@thetextdir\else\beginR\fi - \else - {\setbox\z@\lastbox\beginR\box\z@}% - \fi}% - \let\bbl@severypar\everypar - \newtoks\everypar - \everypar=\bbl@severypar - \bbl@severypar{\bbl@xeeverypar\the\everypar}} - \ifnum\bbl@bidimode>200 - \let\bbl@textdir@i\@gobbletwo - \let\bbl@xebidipar\@empty - \AddBabelHook{bidi}{foreign}{% - \def\bbl@tempa{\def\BabelText####1}% - \ifcase\bbl@thetextdir - \expandafter\bbl@tempa\expandafter{\BabelText{\LR{##1}}}% - \else - \expandafter\bbl@tempa\expandafter{\BabelText{\RL{##1}}}% - \fi} - \def\bbl@pardir#1{\ifcase#1\relax\setLR\else\setRL\fi} - \fi -\fi +\ifx\babel@beginsave\@undefined\let\babel@beginsave\relax\fi % \end{macrocode} % -% A tool for weak L (mainly digits). We also disable warnings with -% \textsf{hyperref}. +% \end{macro} +% +% A few macro names are reserved for future releases of \babel, which +% will use the concept of `locale': % % \begin{macrocode} -\DeclareRobustCommand\babelsublr[1]{\leavevmode{\bbl@textdir\z@#1}} -\AtBeginDocument{% - \ifx\pdfstringdefDisableCommands\@undefined\else - \ifx\pdfstringdefDisableCommands\relax\else - \pdfstringdefDisableCommands{\let\babelsublr\@firstofone}% - \fi - \fi} +\providecommand\setlocale{% + \bbl@error + {Not yet available}% + {Find an armchair, sit down and wait}} +\let\uselocale\setlocale +\let\locale\setlocale +\let\selectlocale\setlocale +\let\localename\setlocale +\let\textlocale\setlocale +\let\textlanguage\setlocale +\let\languagetext\setlocale % \end{macrocode} % -% \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. -% -% For plain-based formats we don't want to override the definition -% of |\loadlocalcfg| from \file{plain.def}. +% \subsection{Errors} % -% \begin{macrocode} -\bbl@trace{Local Language Configuration} -\ifx\loadlocalcfg\@undefined - \@ifpackagewith{babel}{noconfigs}% - {\let\loadlocalcfg\@gobble}% - {\def\loadlocalcfg#1{% - \InputIfFileExists{#1.cfg}% - {\typeout{*************************************^^J% - * Local config file #1.cfg used^^J% - *}}% - \@empty}} -\fi -% \end{macrocode}% -% \end{macro} +% \begin{macro}{\@nolanerr} +% \begin{macro}{\@nopatterns} % -% \subsection{Language options} +% The \babel\ package will signal an error when a documents tries +% to select a language that hasn't been defined earlier. When a +% user selects a language for which no hyphenation patterns were +% loaded into the format he will be given a warning about that +% fact. We revert to the patterns for |\language|=0 in that case. +% In most formats that will be (US)english, but it might also be +% empty. % -% 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{macro}{\@noopterr} +% When the package was loaded without options not everything will +% work as expected. An error message is issued in that case. % -% \begin{macrocode} -\bbl@trace{Language options} -\let\bbl@afterlang\relax -\let\BabelModifiers\relax -\let\bbl@loaded\@empty -\def\bbl@load@language#1{% - \InputIfFileExists{#1.ldf}% - {\edef\bbl@loaded{\CurrentOption - \ifx\bbl@loaded\@empty\else,\bbl@loaded\fi}% - \expandafter\let\expandafter\bbl@afterlang - \csname\CurrentOption.ldf-h@@k\endcsname - \expandafter\let\expandafter\BabelModifiers - \csname bbl@mod@\CurrentOption\endcsname}% - {\bbl@error{% - Unknown option '\CurrentOption'. Either you misspelled it\\% - or the language definition file \CurrentOption.ldf was not found}{% - Valid options are, among others: shorthands=, KeepShorthandsActive,\\% - activeacute, activegrave, noconfigs, safe=, main=, math=\\% - headfoot=, strings=, config=, hyphenmap=, or a language name.}}} -% \end{macrocode} +% When the format knows about |\PackageError| it must be \LaTeXe, +% so we can safely use its error handling interface. Otherwise +% we'll have to `keep it simple'. % -% 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. +% Infos are not written to the console, but on the other hand many +% people think warnings are errors, so a further message type is +% defined: an important info which is sent to the console. % % \begin{macrocode} -\def\bbl@try@load@lang#1#2#3{% - \IfFileExists{\CurrentOption.ldf}% - {\bbl@load@language{\CurrentOption}}% - {#1\bbl@load@language{#2}#3}} -\DeclareOption{hebrew}{% - \input{rlbabel.def}% - \bbl@load@language{hebrew}} -\DeclareOption{hungarian}{\bbl@try@load@lang{}{magyar}{}} -\DeclareOption{lowersorbian}{\bbl@try@load@lang{}{lsorbian}{}} -\DeclareOption{nynorsk}{\bbl@try@load@lang{}{norsk}{}} -\DeclareOption{polutonikogreek}{% - \bbl@try@load@lang{}{greek}{\languageattribute{greek}{polutoniko}}} -\DeclareOption{russian}{\bbl@try@load@lang{}{russianb}{}} -\DeclareOption{ukrainian}{\bbl@try@load@lang{}{ukraineb}{}} -\DeclareOption{uppersorbian}{\bbl@try@load@lang{}{usorbian}{}} +\edef\bbl@nulllanguage{\string\language=0} +\def\bbl@nocaption{\protect\bbl@nocaption@i} +\def\bbl@nocaption@i#1#2{% 1: text to be printed 2: caption macro \langXname + \global\@namedef{#2}{\textbf{?#1?}}% + \@nameuse{#2}% + \edef\bbl@tempa{#1}% + \bbl@sreplace\bbl@tempa{name}{}% + \bbl@warning{% TODO. + \@backslashchar#1 not set for '\languagename'. Please,\\% + define it after the language has been loaded\\% + (typically in the preamble) with:\\% + \string\setlocalecaption{\languagename}{\bbl@tempa}{..}\\% + Reported}} +\def\bbl@tentative{\protect\bbl@tentative@i} +\def\bbl@tentative@i#1{% + \bbl@warning{% + Some functions for '#1' are tentative.\\% + They might not work as expected and their behavior\\% + could change in the future.\\% + Reported}} +\def\@nolanerr#1{% + \bbl@error + {You haven't defined the language '#1' yet.\\% + Perhaps you misspelled it or your installation\\% + is not complete}% + {Your command will be ignored, type to proceed}} +\def\@nopatterns#1{% + \bbl@warning + {No hyphenation patterns were preloaded for\\% + the language '#1' into the format.\\% + Please, configure your TeX system to add them and\\% + rebuild the format. Now I will use the patterns\\% + preloaded for \bbl@nulllanguage\space instead}} +\let\bbl@usehooks\@gobbletwo +\ifx\bbl@onlyswitch\@empty\endinput\fi + % Here ended switch.def % \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=|, which will -% load |.cfg| instead. +% Here ended the now discarded |switch.def|. Here also (currently) ends +% the \textsf{base} option. % % \begin{macrocode} -\ifx\bbl@opt@config\@nnil - \@ifpackagewith{babel}{noconfigs}{}% - {\InputIfFileExists{bblopts.cfg}% - {\typeout{*************************************^^J% - * Local config file bblopts.cfg used^^J% - *}}% - {}}% -\else - \InputIfFileExists{\bbl@opt@config.cfg}% - {\typeout{*************************************^^J% - * Local config file \bbl@opt@config.cfg used^^J% - *}}% - {\bbl@error{% - Local config file '\bbl@opt@config.cfg' not found}{% - Perhaps you misspelled it.}}% +\ifx\directlua\@undefined\else + \ifx\bbl@luapatterns\@undefined + \input luababel.def + \fi +\fi +<@Basic macros@> +\bbl@trace{Compatibility with language.def} +\ifx\bbl@languages\@undefined + \ifx\directlua\@undefined + \openin1 = language.def % TODO. Remove hardcoded number + \ifeof1 + \closein1 + \message{I couldn't find the file language.def} + \else + \closein1 + \begingroup + \def\addlanguage#1#2#3#4#5{% + \expandafter\ifx\csname lang@#1\endcsname\relax\else + \global\expandafter\let\csname l@#1\expandafter\endcsname + \csname lang@#1\endcsname + \fi}% + \def\uselanguage#1{}% + \input language.def + \endgroup + \fi + \fi + \chardef\l@english\z@ \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. +% \begin{macro}{\addto} +% It takes two arguments, a \meta{control sequence} and \TeX-code to +% be added to the \meta{control sequence}. +% +% If the \meta{control sequence} has not been defined before it is +% defined now. The control sequence could also expand to |\relax|, +% in which case a circular definition results. The net result is a +% stack overflow. Note there is an inconsistency, because the +% assignment in the last branch is global. % % \begin{macrocode} -\let\bbl@tempc\relax -\bbl@foreach\bbl@language@opts{% - \ifcase\bbl@iniflag % Default - \bbl@ifunset{ds@#1}% - {\DeclareOption{#1}{\bbl@load@language{#1}}}% - {}% - \or % provide=* - \@gobble % case 2 same as 1 - \or % provide+=* - \bbl@ifunset{ds@#1}% - {\IfFileExists{#1.ldf}{}% - {\IfFileExists{babel-#1.tex}{}{\@namedef{ds@#1}{}}}}% - {}% - \bbl@ifunset{ds@#1}% - {\def\bbl@tempc{#1}% - \DeclareOption{#1}{% - \ifnum\bbl@iniflag>\@ne - \bbl@ldfinit - \babelprovide[import]{#1}% - \bbl@afterldf{}% - \else - \bbl@load@language{#1}% - \fi}}% - {}% - \or % provide*=* - \def\bbl@tempc{#1}% - \bbl@ifunset{ds@#1}% - {\DeclareOption{#1}{% - \bbl@ldfinit - \babelprovide[import]{#1}% - \bbl@afterldf{}}}% - {}% +\def\addto#1#2{% + \ifx#1\@undefined + \def#1{#2}% + \else + \ifx#1\relax + \def#1{#2}% + \else + {\toks@\expandafter{#1#2}% + \xdef#1{\the\toks@}}% + \fi \fi} % \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 -% accessing the file system just to see if the option could be a -% language. +% \end{macro} +% +% The macro |\initiate@active@char| below takes all the necessary +% actions to make its argument a shorthand character. The real work +% is performed once for each character. But first we define a little +% tool. TODO. Always used with additional expansions. Move them here? +% Move the macro to basic? % % \begin{macrocode} -\let\bbl@tempb\@nnil -\bbl@foreach\@classoptionslist{% - \bbl@ifunset{ds@#1}% - {\IfFileExists{#1.ldf}% - {\def\bbl@tempb{#1}% - \DeclareOption{#1}{% - \ifnum\bbl@iniflag>\@ne - \bbl@ldfinit - \babelprovide[import]{#1}% - \bbl@afterldf{}% - \else - \bbl@load@language{#1}% - \fi}}% - {\IfFileExists{babel-#1.tex}% TODO. Copypaste pattern - {\def\bbl@tempb{#1}% - \DeclareOption{#1}{% - \ifnum\bbl@iniflag>\@ne - \bbl@ldfinit - \babelprovide[import]{#1}% - \bbl@afterldf{}% - \else - \bbl@load@language{#1}% - \fi}}% - {}}}% - {}} +\def\bbl@withactive#1#2{% + \begingroup + \lccode`~=`#2\relax + \lowercase{\endgroup#1~}} % \end{macrocode} % -% If a main language has been set, store it for the third pass. +% \begin{macro}{\bbl@redefine} +% +% To redefine a command, we save the old meaning of the macro. Then +% we redefine it to call the original macro with the `sanitized' +% argument. The reason why we do it this way is that we don't want +% to redefine the \LaTeX\ macros completely in case their +% definitions change (they have changed in the past). A macro named +% |\macro| will be saved new control sequences named |\org@macro|. % % \begin{macrocode} -\ifnum\bbl@iniflag=\z@\else - \ifx\bbl@opt@main\@nnil - \ifx\bbl@tempc\relax - \let\bbl@opt@main\bbl@tempb - \else - \let\bbl@opt@main\bbl@tempc - \fi - \fi -\fi -\ifx\bbl@opt@main\@nnil\else - \expandafter - \let\expandafter\bbl@loadmain\csname ds@\bbl@opt@main\endcsname - \expandafter\let\csname ds@\bbl@opt@main\endcsname\@empty -\fi +\def\bbl@redefine#1{% + \edef\bbl@tempa{\bbl@stripslash#1}% + \expandafter\let\csname org@\bbl@tempa\endcsname#1% + \expandafter\def\csname\bbl@tempa\endcsname} +\@onlypreamble\bbl@redefine % \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. +% \end{macro} % -% 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{macro}{\bbl@redefine@long} +% This version of |\babel@redefine| can be used to redefine |\long| +% commands such as |\ifthenelse|. % % \begin{macrocode} -\def\AfterBabelLanguage#1{% - \bbl@ifsamestring\CurrentOption{#1}{\global\bbl@add\bbl@afterlang}{}} -\DeclareOption*{} -\ProcessOptions* +\def\bbl@redefine@long#1{% + \edef\bbl@tempa{\bbl@stripslash#1}% + \expandafter\let\csname org@\bbl@tempa\endcsname#1% + \expandafter\long\expandafter\def\csname\bbl@tempa\endcsname} +\@onlypreamble\bbl@redefine@long % \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|. +% \end{macro} % -% \begin{macrocode} -\bbl@trace{Option 'main'} -\ifx\bbl@opt@main\@nnil - \edef\bbl@tempa{\@classoptionslist,\bbl@language@opts} - \let\bbl@tempc\@empty - \bbl@for\bbl@tempb\bbl@tempa{% - \bbl@xin@{,\bbl@tempb,}{,\bbl@loaded,}% - \ifin@\edef\bbl@tempc{\bbl@tempb}\fi} - \def\bbl@tempa#1,#2\@nnil{\def\bbl@tempb{#1}} - \expandafter\bbl@tempa\bbl@loaded,\@nnil - \ifx\bbl@tempb\bbl@tempc\else - \bbl@warning{% - Last declared language option is '\bbl@tempc',\\% - but the last processed one was '\bbl@tempb'.\\% - The main language can't be set as both a global\\% - and a package option. Use 'main=\bbl@tempc' as\\% - option. Reported}% - \fi -\else - \ifodd\bbl@iniflag % case 1,3 - \bbl@ldfinit - \let\CurrentOption\bbl@opt@main - \ifx\bbl@opt@provide\@nnil - \bbl@exp{\\\babelprovide[import,main]{\bbl@opt@main}}% - \else - \bbl@exp{\\\bbl@forkv{\@nameuse{@raw@opt@babel.sty}}}{% - \bbl@xin@{,provide,}{,#1,}% - \ifin@ - \def\bbl@opt@provide{#2}% - \bbl@replace\bbl@opt@provide{;}{,}% - \fi}% - \bbl@exp{% - \\\babelprovide[\bbl@opt@provide,import,main]{\bbl@opt@main}}% - \fi - \bbl@afterldf{}% - \else % case 0,2 - \chardef\bbl@iniflag\z@ % Force ldf - \expandafter\let\csname ds@\bbl@opt@main\endcsname\bbl@loadmain - \ExecuteOptions{\bbl@opt@main} - \DeclareOption*{}% - \ProcessOptions* - \fi -\fi -\def\AfterBabelLanguage{% - \bbl@error - {Too late for \string\AfterBabelLanguage}% - {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. +% \begin{macro}{\bbl@redefinerobust} +% For commands that are redefined, but which \textit{might} be +% robust we need a slightly more intelligent macro. A robust +% command |foo| is defined to expand to |\protect|\verb*|\foo |. So +% it is necessary to check whether \verb*|\foo | exists. The result +% is that the command that is being redefined is always robust +% afterwards. Therefore all we need to do now is define \verb*|\foo |. % % \begin{macrocode} -\ifx\bbl@main@language\@undefined - \bbl@info{% - You haven't specified a language. I'll use 'nil'\\% - as the main language. Reported} - \bbl@load@language{nil} -\fi -% -%<*core> +\def\bbl@redefinerobust#1{% + \edef\bbl@tempa{\bbl@stripslash#1}% + \bbl@ifunset{\bbl@tempa\space}% + {\expandafter\let\csname org@\bbl@tempa\endcsname#1% + \bbl@exp{\def\\#1{\\\protect\<\bbl@tempa\space>}}}% + {\bbl@exp{\let\\<\bbl@tempa\space>}}% + \@namedef{\bbl@tempa\space}} +\@onlypreamble\bbl@redefinerobust % \end{macrocode} % -% \section{The kernel of Babel (\texttt{babel.def}, common)} -% -% The kernel of the \babel\ system is currently stored in -% \file{babel.def}. The file \file{babel.def} contains most of the -% code. The file \file{hyphen.cfg} is a file that can be loaded into -% the format, which is necessary when you want to be able to switch -% hyphenation patterns. -% -% Because plain \TeX\ users might want to use some of the features of -% the \babel{} system too, care has to be taken that plain \TeX\ can -% process the files. For this reason the current format will have to -% be checked in a number of places. Some of the code below is common -% to plain \TeX\ and \LaTeX, some of it is for the \LaTeX\ case only. +% \end{macro} % -% Plain formats based on etex (etex, xetex, luatex) don't load -% |hyphen.cfg| but |etex.src|, which follows a different naming -% convention, so we need to define the babel names. It presumes -% |language.def| exists and it is the same file used when formats were -% created. +% \subsection{Hooks} % -% \subsection{Tools} +% Admittedly, the current implementation is a somewhat simplistic and +% does very little to catch errors, but it is meant for developers, +% after all. |\bbl@usehooks| is the commands used by \babel{} to execute +% hooks defined for an event. % % \begin{macrocode} -\ifx\ldf@quit\@undefined\else -\endinput\fi % Same line! -<@Make sure ProvidesFile is defined@> -\ProvidesFile{babel.def}[<@date@> <@version@> Babel common definitions] +\bbl@trace{Hooks} +\newcommand\AddBabelHook[3][]{% + \bbl@ifunset{bbl@hk@#2}{\EnableBabelHook{#2}}{}% + \def\bbl@tempa##1,#3=##2,##3\@empty{\def\bbl@tempb{##2}}% + \expandafter\bbl@tempa\bbl@evargs,#3=,\@empty + \bbl@ifunset{bbl@ev@#2@#3@#1}% + {\bbl@csarg\bbl@add{ev@#3@#1}{\bbl@elth{#2}}}% + {\bbl@csarg\let{ev@#2@#3@#1}\relax}% + \bbl@csarg\newcommand{ev@#2@#3@#1}[\bbl@tempb]} +\newcommand\EnableBabelHook[1]{\bbl@csarg\let{hk@#1}\@firstofone} +\newcommand\DisableBabelHook[1]{\bbl@csarg\let{hk@#1}\@gobble} +\def\bbl@usehooks#1#2{% + \ifx\UseHook\@undefined\else\UseHook{babel/*/#1}\fi + \def\bbl@elth##1{% + \bbl@cs{hk@##1}{\bbl@cs{ev@##1@#1@}#2}}% + \bbl@cs{ev@#1@}% + \ifx\languagename\@undefined\else % Test required for Plain (?) + \ifx\UseHook\@undefined\else\UseHook{babel/\languagename/#1}\fi + \def\bbl@elth##1{% + \bbl@cs{hk@##1}{\bbl@cl{ev@##1@#1}#2}}% + \bbl@cl{ev@#1}% + \fi} % \end{macrocode} % -% The file |babel.def| expects some definitions made in the \LaTeXe{} -% style file. So, in Plain{} we must provide at least -% some predefined values as well some tools to set them (even if not -% all options are available). There are no package options, and -% therefore and alternative mechanism is provided. For the moment, -% only |\babeloptionstrings| and |\babeloptionmath| are provided, -% which can be defined before loading \babel. |\BabelModifiers| can be -% set too (but not sure it works). +% To ensure forward compatibility, arguments in hooks are set +% implicitly. So, if a further argument is added in the future, +% there is no need to change the existing code. Note events +% intended for \textsf{hyphen.cfg} are also loaded (just in +% case you need them for some reason). % % \begin{macrocode} -\ifx\AtBeginDocument\@undefined % TODO. change test. - <@Emulate LaTeX@> - \def\languagename{english}% - \let\bbl@opt@shorthands\@nnil - \def\bbl@ifshorthand#1#2#3{#2}% - \let\bbl@language@opts\@empty - \ifx\babeloptionstrings\@undefined - \let\bbl@opt@strings\@nnil - \else - \let\bbl@opt@strings\babeloptionstrings - \fi - \def\BabelStringsDefault{generic} - \def\bbl@tempa{normal} - \ifx\babeloptionmath\bbl@tempa - \def\bbl@mathnormal{\noexpand\textormath} - \fi - \def\AfterBabelLanguage#1#2{} - \ifx\BabelModifiers\@undefined\let\BabelModifiers\relax\fi - \let\bbl@afterlang\relax - \def\bbl@opt@safe{BR} - \ifx\@uclclist\@undefined\let\@uclclist\@empty\fi - \ifx\bbl@trace\@undefined\def\bbl@trace#1{}\fi - \expandafter\newif\csname ifbbl@single\endcsname - \chardef\bbl@bidimode\z@ +\def\bbl@evargs{,% <- don't delete this comma + everylanguage=1,loadkernel=1,loadpatterns=1,loadexceptions=1,% + adddialect=2,patterns=2,defaultcommands=0,encodedcommands=2,write=0,% + beforeextras=0,afterextras=0,stopcommands=0,stringprocess=0,% + hyphenation=2,initiateactive=3,afterreset=0,foreign=0,foreign*=0,% + beforestart=0,languagename=2} +\ifx\NewHook\@undefined\else + \def\bbl@tempa#1=#2\@@{\NewHook{babel/#1}} + \bbl@foreach\bbl@evargs{\bbl@tempa#1\@@} \fi % \end{macrocode} % -% And continue. -% -% \section{Multiple languages} +% \begin{macro}{\babelensure} % -% This is not a separate file (\texttt{switch.def}) anymore. +% The user command just parses the optional argument and creates a +% new macro named |\bbl@e@|\m{language}. We register a hook at the +% |afterextras| event which just executes this macro in a +% ``complete'' selection (which, if undefined, is |\relax| and does +% nothing). This part is somewhat involved because we have to make +% sure things are expanded the correct number of times. % -% 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 macro |\bbl@e@|\m{language} contains +% |\bbl@ensure|\marg{include}\marg{exclude}\marg{fontenc}, which in in +% turn loops over the macros names in |\bbl@captionslist|, excluding +% (with the help of |\in@|) those in the |exclude| list. If the +% |fontenc| is given (and not |\relax|), the |\fontencoding| is also +% added. Then we loop over the |include| list, but if the macro +% already contains |\foreignlanguage|, nothing is done. Note this +% macro (1) is not restricted to the preamble, and (2) changes are +% local. % % \begin{macrocode} -<@Define core switching macros@> +\bbl@trace{Defining babelensure} +\newcommand\babelensure[2][]{% TODO - revise test files + \AddBabelHook{babel-ensure}{afterextras}{% + \ifcase\bbl@select@type + \bbl@cl{e}% + \fi}% + \begingroup + \let\bbl@ens@include\@empty + \let\bbl@ens@exclude\@empty + \def\bbl@ens@fontenc{\relax}% + \def\bbl@tempb##1{% + \ifx\@empty##1\else\noexpand##1\expandafter\bbl@tempb\fi}% + \edef\bbl@tempa{\bbl@tempb#1\@empty}% + \def\bbl@tempb##1=##2\@@{\@namedef{bbl@ens@##1}{##2}}% + \bbl@foreach\bbl@tempa{\bbl@tempb##1\@@}% + \def\bbl@tempc{\bbl@ensure}% + \expandafter\bbl@add\expandafter\bbl@tempc\expandafter{% + \expandafter{\bbl@ens@include}}% + \expandafter\bbl@add\expandafter\bbl@tempc\expandafter{% + \expandafter{\bbl@ens@exclude}}% + \toks@\expandafter{\bbl@tempc}% + \bbl@exp{% + \endgroup + \def\{\the\toks@{\bbl@ens@fontenc}}}} +\def\bbl@ensure#1#2#3{% 1: include 2: exclude 3: fontenc + \def\bbl@tempb##1{% elt for (excluding) \bbl@captionslist list + \ifx##1\@undefined % 3.32 - Don't assume the macro exists + \edef##1{\noexpand\bbl@nocaption + {\bbl@stripslash##1}{\languagename\bbl@stripslash##1}}% + \fi + \ifx##1\@empty\else + \in@{##1}{#2}% + \ifin@\else + \bbl@ifunset{bbl@ensure@\languagename}% + {\bbl@exp{% + \\\DeclareRobustCommand\[1]{% + \\\foreignlanguage{\languagename}% + {\ifx\relax#3\else + \\\fontencoding{#3}\\\selectfont + \fi + ########1}}}}% + {}% + \toks@\expandafter{##1}% + \edef##1{% + \bbl@csarg\noexpand{ensure@\languagename}% + {\the\toks@}}% + \fi + \expandafter\bbl@tempb + \fi}% + \expandafter\bbl@tempb\bbl@captionslist\today\@empty + \def\bbl@tempa##1{% elt for include list + \ifx##1\@empty\else + \bbl@csarg\in@{ensure@\languagename\expandafter}\expandafter{##1}% + \ifin@\else + \bbl@tempb##1\@empty + \fi + \expandafter\bbl@tempa + \fi}% + \bbl@tempa#1\@empty} +\def\bbl@captionslist{% + \prefacename\refname\abstractname\bibname\chaptername\appendixname + \contentsname\listfigurename\listtablename\indexname\figurename + \tablename\partname\enclname\ccname\headtoname\pagename\seename + \alsoname\proofname\glossaryname} % \end{macrocode} % -% \begin{macro}{\adddialect} -% The macro |\adddialect| can be used to add the name of a dialect -% or variant language, for which an already defined hyphenation -% table can be used. +% \end{macro} % -% \begin{macrocode} -\def\bbl@version{<@version@>} -\def\bbl@date{<@date@>} -\def\adddialect#1#2{% - \global\chardef#1#2\relax - \bbl@usehooks{adddialect}{{#1}{#2}}% - \begingroup - \count@#1\relax - \def\bbl@elt##1##2##3##4{% - \ifnum\count@=##2\relax - \edef\bbl@tempa{\expandafter\@gobbletwo\string#1}% - \bbl@info{Hyphen rules for '\expandafter\@gobble\bbl@tempa' - set to \expandafter\string\csname l@##1\endcsname\\% - (\string\language\the\count@). Reported}% - \def\bbl@elt####1####2####3####4{}% - \fi}% - \bbl@cs{languages}% - \endgroup} -% \end{macrocode} +% \subsection{Setting up language files} % -% \end{macro} +% \begin{macro}{\LdfInit} % -% |\bbl@iflanguage| executes code only if the language |l@| -% exists. Otherwise raises and error. +% |\LdfInit| macro takes two arguments. The first +% argument is the name of the language that will be defined in the +% language definition file; the second argument is either a control +% sequence or a string from which a control sequence should be +% constructed. The existence of the control sequence indicates that +% the file has been processed before. % -% The argument of |\bbl@fixname| has to be a macro name, as it may get -% ``fixed'' if casing (lc/uc) is wrong. It's an attempt to fix a -% long-standing bug when |\foreignlanguage| and the like appear in -% a |\MakeXXXcase|. However, a lowercase form is not imposed to -% improve backward compatibility (perhaps you defined a language -% named |MYLANG|, but unfortunately mixed case names cannot be -% trapped). Note |l@| is encapsulated, so that its case does not -% change. +% At the start of processing a language definition file we always +% check the category code of the at-sign. We make sure that it is +% a `letter' during the processing of the file. We also save its +% name as the last called option, even if not loaded. % -% \begin{macrocode} -\def\bbl@fixname#1{% - \begingroup - \def\bbl@tempe{l@}% - \edef\bbl@tempd{\noexpand\@ifundefined{\noexpand\bbl@tempe#1}}% - \bbl@tempd - {\lowercase\expandafter{\bbl@tempd}% - {\uppercase\expandafter{\bbl@tempd}% - \@empty - {\edef\bbl@tempd{\def\noexpand#1{#1}}% - \uppercase\expandafter{\bbl@tempd}}}% - {\edef\bbl@tempd{\def\noexpand#1{#1}}% - \lowercase\expandafter{\bbl@tempd}}}% - \@empty - \edef\bbl@tempd{\endgroup\def\noexpand#1{#1}}% - \bbl@tempd - \bbl@exp{\\\bbl@usehooks{languagename}{{\languagename}{#1}}}} -\def\bbl@iflanguage#1{% - \@ifundefined{l@#1}{\@nolanerr{#1}\@gobble}\@firstofone} -% \end{macrocode} +% Another character that needs to have the correct category code +% during processing of language definition files is the equals sign, +% `=', because it is sometimes used in constructions with the +% |\let| primitive. Therefore we store its current catcode and +% restore it later on. % -% After a name has been ‘fixed’, the selectors will try to load the -% language. If even the fixed name is not defined, will load it on the -% fly, either based on its name, or if activated, its BCP47 code. +% Now we check whether we should perhaps stop the processing of +% this file. To do this we first need to check whether the second +% argument that is passed to |\LdfInit| is a control sequence. We +% do that by looking at the first token after passing |#2| through +% |string|. When it is equal to |\@backslashchar| we are dealing +% with a control sequence which we can compare with |\@undefined|. +% +% If so, we call |\ldf@quit| to set the main language, restore the +% category code of the @-sign and call |\endinput| +% +% When |#2| was \emph{not} a control sequence we construct one and +% compare it with |\relax|. +% +% Finally we check |\originalTeX|. % -% We first need a couple of macros for a simple BCP 47 look up. It also -% makes sure, with |\bbl@bcpcase|, casing is the correct one, so that -% sr-latn-ba becomes fr-Latn-BA. Note |#4| may contain some -% |\@empty|'s, but they are eventually removed. |\bbl@bcplookup| either -% returns the found |ini| or it is |\relax|. -% % \begin{macrocode} -\def\bbl@bcpcase#1#2#3#4\@@#5{% - \ifx\@empty#3% - \uppercase{\def#5{#1#2}}% +\bbl@trace{Macros for setting language files up} +\def\bbl@ldfinit{% + \let\bbl@screset\@empty + \let\BabelStrings\bbl@opt@string + \let\BabelOptions\@empty + \let\BabelLanguages\relax + \ifx\originalTeX\@undefined + \let\originalTeX\@empty \else - \uppercase{\def#5{#1}}% - \lowercase{\edef#5{#5#2#3#4}}% + \originalTeX \fi} -\def\bbl@bcplookup#1-#2-#3-#4\@@{% - \let\bbl@bcp\relax - \lowercase{\def\bbl@tempa{#1}}% - \ifx\@empty#2% - \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% - \else\ifx\@empty#3% - \bbl@bcpcase#2\@empty\@empty\@@\bbl@tempb - \IfFileExists{babel-\bbl@tempa-\bbl@tempb.ini}% - {\edef\bbl@bcp{\bbl@tempa-\bbl@tempb}}% - {}% - \ifx\bbl@bcp\relax - \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% +\def\LdfInit#1#2{% + \chardef\atcatcode=\catcode`\@ + \catcode`\@=11\relax + \chardef\eqcatcode=\catcode`\= + \catcode`\==12\relax + \expandafter\if\expandafter\@backslashchar + \expandafter\@car\string#2\@nil + \ifx#2\@undefined\else + \ldf@quit{#1}% \fi \else - \bbl@bcpcase#2\@empty\@empty\@@\bbl@tempb - \bbl@bcpcase#3\@empty\@empty\@@\bbl@tempc - \IfFileExists{babel-\bbl@tempa-\bbl@tempb-\bbl@tempc.ini}% - {\edef\bbl@bcp{\bbl@tempa-\bbl@tempb-\bbl@tempc}}% - {}% - \ifx\bbl@bcp\relax - \IfFileExists{babel-\bbl@tempa-\bbl@tempc.ini}% - {\edef\bbl@bcp{\bbl@tempa-\bbl@tempc}}% - {}% - \fi - \ifx\bbl@bcp\relax - \IfFileExists{babel-\bbl@tempa-\bbl@tempc.ini}% - {\edef\bbl@bcp{\bbl@tempa-\bbl@tempc}}% - {}% - \fi - \ifx\bbl@bcp\relax - \IfFileExists{babel-\bbl@tempa.ini}{\let\bbl@bcp\bbl@tempa}{}% - \fi - \fi\fi} -\let\bbl@initoload\relax -\def\bbl@provide@locale{% - \ifx\babelprovide\@undefined - \bbl@error{For a language to be defined on the fly 'base'\\% - is not enough, and the whole package must be\\% - loaded. Either delete the 'base' option or\\% - request the languages explicitly}% - {See the manual for further details.}% - \fi -% TODO. Option to search if loaded, with \LocaleForEach - \let\bbl@auxname\languagename % Still necessary. TODO - \bbl@ifunset{bbl@bcp@map@\languagename}{}% Move uplevel?? - {\edef\languagename{\@nameuse{bbl@bcp@map@\languagename}}}% - \ifbbl@bcpallowed - \expandafter\ifx\csname date\languagename\endcsname\relax - \expandafter - \bbl@bcplookup\languagename-\@empty-\@empty-\@empty\@@ - \ifx\bbl@bcp\relax\else % Returned by \bbl@bcplookup - \edef\languagename{\bbl@bcp@prefix\bbl@bcp}% - \edef\localename{\bbl@bcp@prefix\bbl@bcp}% - \expandafter\ifx\csname date\languagename\endcsname\relax - \let\bbl@initoload\bbl@bcp - \bbl@exp{\\\babelprovide[\bbl@autoload@bcpoptions]{\languagename}}% - \let\bbl@initoload\relax - \fi - \bbl@csarg\xdef{bcp@map@\bbl@bcp}{\localename}% - \fi + \expandafter\ifx\csname#2\endcsname\relax\else + \ldf@quit{#1}% \fi \fi - \expandafter\ifx\csname date\languagename\endcsname\relax - \IfFileExists{babel-\languagename.tex}% - {\bbl@exp{\\\babelprovide[\bbl@autoload@options]{\languagename}}}% - {}% - \fi} + \bbl@ldfinit} % \end{macrocode} % -% \begin{macro}{\iflanguage} -% Users might want to test (in a private package for instance) -% which language is currently active. For this we provide a test -% macro, |\iflanguage|, that has three arguments. It checks -% whether the first argument is a known language. If so, it -% compares the first argument with the value of |\language|. Then, -% depending on the result of the comparison, it executes either the -% second or the third argument. +% \end{macro} +% +% \begin{macro}{\ldf@quit} +% This macro interrupts the processing of a language definition file. % % \begin{macrocode} -\def\iflanguage#1{% - \bbl@iflanguage{#1}{% - \ifnum\csname l@#1\endcsname=\language - \expandafter\@firstoftwo - \else - \expandafter\@secondoftwo - \fi}} +\def\ldf@quit#1{% + \expandafter\main@language\expandafter{#1}% + \catcode`\@=\atcatcode \let\atcatcode\relax + \catcode`\==\eqcatcode \let\eqcatcode\relax + \endinput} % \end{macrocode} % % \end{macro} % -% \subsection{Selecting the language} -% -% \begin{macro}{\selectlanguage} +% \begin{macro}{\ldf@finish} +% This macro takes one argument. It is the name of the language +% that was defined in the language definition file. % -% The macro |\selectlanguage| checks whether the language is -% already defined before it performs its actual task, which is to -% update |\language| and activate language-specific definitions. +% We load the local configuration file if one is present, we set +% the main language (taking into account that the argument might be +% a control sequence that needs to be expanded) and reset the +% category code of the @-sign. % % \begin{macrocode} -\let\bbl@select@type\z@ -\edef\selectlanguage{% - \noexpand\protect - \expandafter\noexpand\csname selectlanguage \endcsname} +\def\bbl@afterldf#1{% TODO. Merge into the next macro? Unused elsewhere + \bbl@afterlang + \let\bbl@afterlang\relax + \let\BabelModifiers\relax + \let\bbl@screset\relax}% +\def\ldf@finish#1{% + \loadlocalcfg{#1}% + \bbl@afterldf{#1}% + \expandafter\main@language\expandafter{#1}% + \catcode`\@=\atcatcode \let\atcatcode\relax + \catcode`\==\eqcatcode \let\eqcatcode\relax} % \end{macrocode} % -% Because the command |\selectlanguage| could be used in a moving -% argument it expands to \verb*=\protect\selectlanguage =. -% Therefore, we have to make sure that a macro |\protect| exists. -% If it doesn't it is |\let| to |\relax|. +% \end{macro} +% +% After the preamble of the document the commands |\LdfInit|, +% |\ldf@quit| and |\ldf@finish| are no longer needed. Therefore +% they are turned into warning messages in \LaTeX. % % \begin{macrocode} -\ifx\@undefined\protect\let\protect\relax\fi +\@onlypreamble\LdfInit +\@onlypreamble\ldf@quit +\@onlypreamble\ldf@finish % \end{macrocode} % -% The following definition is preserved for backwards compatibility -% (eg, \textsf{arabi}, \textsf{koma}). It is related to a trick for -% 2.09, now discarded. +% \begin{macro}{\main@language} +% \begin{macro}{\bbl@main@language} +% This command should be used in the various language definition +% files. It stores its argument in |\bbl@main@language|; to be used +% to switch to the correct language at the beginning of the +% document. % % \begin{macrocode} -\let\xstring\string +\def\main@language#1{% + \def\bbl@main@language{#1}% + \let\languagename\bbl@main@language % TODO. Set localename + \bbl@id@assign + \bbl@patterns{\languagename}} % \end{macrocode} % -% \end{macro} +% We also have to make sure that some code gets executed at the +% beginning of the document, either when the |aux| file is read or, +% if it does not exist, when the |\AtBeginDocument| is executed. +% Languages do not set |\pagedir|, so we set here for the whole +% document to the main |\bodydir|. % -% Since version 3.5 \babel\ writes entries to the auxiliary files in -% order to typeset table of contents etc. in the correct language -% environment. -% -% \begin{macro}{\bbl@pop@language} +% \begin{macrocode} +\def\bbl@beforestart{% + \def\@nolanerr##1{% + \bbl@warning{Undefined language '##1' in aux.\\Reported}}% + \bbl@usehooks{beforestart}{}% + \global\let\bbl@beforestart\relax} +\AtBeginDocument{% + {\@nameuse{bbl@beforestart}}% Group! + \if@filesw + \providecommand\babel@aux[2]{}% + \immediate\write\@mainaux{% + \string\providecommand\string\babel@aux[2]{}}% + \immediate\write\@mainaux{\string\@nameuse{bbl@beforestart}}% + \fi + \expandafter\selectlanguage\expandafter{\bbl@main@language}% + \ifbbl@single % must go after the line above. + \renewcommand\selectlanguage[1]{}% + \renewcommand\foreignlanguage[2]{#2}% + \global\let\babel@aux\@gobbletwo % Also as flag + \fi + \ifcase\bbl@engine\or\pagedir\bodydir\fi} % TODO - a better place +% \end{macrocode} % -% \emph{But} when the language change happens \emph{inside} a group -% the end of the group doesn't write anything to the auxiliary -% files. Therefore we need \TeX's |aftergroup| mechanism to help -% us. The command |\aftergroup| stores the token immediately -% following it to be executed when the current group is closed. So -% we define a temporary control sequence |\bbl@pop@language| to be -% executed at the end of the group. It calls |\bbl@set@language| -% with the name of the current language as its argument. +% \end{macro} +% \end{macro} % -% \begin{macro}{\bbl@language@stack} -% The previous solution works for one level of nesting groups, but -% as soon as more levels are used it is no longer adequate. For -% that case we need to keep track of the nested languages using a -% stack mechanism. This stack is called |\bbl@language@stack| and -% initially empty. +% A bit of optimization. Select in heads/foots the language only if +% necessary. % % \begin{macrocode} -\def\bbl@language@stack{} +\def\select@language@x#1{% + \ifcase\bbl@select@type + \bbl@ifsamestring\languagename{#1}{}{\select@language{#1}}% + \else + \select@language{#1}% + \fi} % \end{macrocode} % -% When using a stack we need a mechanism to push an element on the -% stack and to retrieve the information afterwards. +% \subsection{Shorthands} % -% \begin{macro}{\bbl@push@language} -% \begin{macro}{\bbl@pop@language} -% The stack is simply a list of languagenames, separated with a `+' -% sign; the push function can be simple: +% \begin{macro}{\bbl@add@special} +% The macro |\bbl@add@special| is used to add a new character (or +% single character control sequence) to the macro |\dospecials| +% (and |\@sanitize| if \LaTeX\ is used). It is used only at one +% place, namely when |\initiate@active@char| is called (which is +% ignored if the char has been made active before). Because +% |\@sanitize| can be undefined, we put the definition inside a +% conditional. +% +% Items are added to the lists without checking its existence or +% the original catcode. It does not hurt, but should be fixed. It's +% already done with |\nfss@catcodes|, added in 3.10. % % \begin{macrocode} -\def\bbl@push@language{% - \ifx\languagename\@undefined\else - \ifx\currentgrouplevel\@undefined - \xdef\bbl@language@stack{\languagename+\bbl@language@stack}% - \else - \ifnum\currentgrouplevel=\z@ - \xdef\bbl@language@stack{\languagename+}% +\bbl@trace{Shorhands} +\def\bbl@add@special#1{% 1:a macro like \", \?, etc. + \bbl@add\dospecials{\do#1}% test @sanitize = \relax, for back. compat. + \bbl@ifunset{@sanitize}{}{\bbl@add\@sanitize{\@makeother#1}}% + \ifx\nfss@catcodes\@undefined\else % TODO - same for above + \begingroup + \catcode`#1\active + \nfss@catcodes + \ifnum\catcode`#1=\active + \endgroup + \bbl@add\nfss@catcodes{\@makeother#1}% \else - \xdef\bbl@language@stack{\languagename+\bbl@language@stack}% - \fi - \fi + \endgroup + \fi \fi} % \end{macrocode} % -% Retrieving information from the stack is a little bit less simple, as -% we need to remove the element from the stack while storing it in the -% macro |\languagename|. For this we first define a helper function. -% \begin{macro}{\bbl@pop@lang} -% This macro stores its first element (which is delimited by the -% `+'-sign) in |\languagename| and stores the rest of the string -% in |\bbl@language@stack|. +% \end{macro} % -% \begin{macrocode} -\def\bbl@pop@lang#1+#2\@@{% - \edef\languagename{#1}% - \xdef\bbl@language@stack{#2}} -% \end{macrocode} +% \begin{macro}{\bbl@remove@special} % -% \end{macro} -% The reason for the somewhat weird arrangement of arguments to the -% helper function is the fact it is called in the following way. -% This means that before |\bbl@pop@lang| is executed \TeX\ first -% \emph{expands} the stack, stored in |\bbl@language@stack|. The -% result of that is that the argument string of |\bbl@pop@lang| -% contains one or more language names, each followed by a `+'-sign -% (zero language names won't occur as this macro will only be -% called after something has been pushed on the stack). +% The companion of the former macro is |\bbl@remove@special|. It +% removes a character from the set macros |\dospecials| and +% |\@sanitize|, but it is not used at all in the \babel{} core. % % \begin{macrocode} -\let\bbl@ifrestoring\@secondoftwo -\def\bbl@pop@language{% - \expandafter\bbl@pop@lang\bbl@language@stack\@@ - \let\bbl@ifrestoring\@firstoftwo - \expandafter\bbl@set@language\expandafter{\languagename}% - \let\bbl@ifrestoring\@secondoftwo} +\def\bbl@remove@special#1{% + \begingroup + \def\x##1##2{\ifnum`#1=`##2\noexpand\@empty + \else\noexpand##1\noexpand##2\fi}% + \def\do{\x\do}% + \def\@makeother{\x\@makeother}% + \edef\x{\endgroup + \def\noexpand\dospecials{\dospecials}% + \expandafter\ifx\csname @sanitize\endcsname\relax\else + \def\noexpand\@sanitize{\@sanitize}% + \fi}% + \x} % \end{macrocode} % -% Once the name of the previous language is retrieved from the stack, -% it is fed to |\bbl@set@language| to do the actual work of -% switching everything that needs switching. -% \end{macro} -% \end{macro} % \end{macro} % -% An alternative way to identify languages (in the \babel{} sense) -% with a numerical value is introduced in 3.30. This is one of the -% first steps for a new interface based on the concept of locale, -% which explains the name of |\localeid|. This means |\l@...| will be -% reserved for hyphenation patterns (so that two locales can share the -% same rules). +% \begin{macro}{\initiate@active@char} +% A language definition file can call this macro to make a +% character active. This macro takes one argument, the character +% that is to be made active. When the character was already active +% this macro does nothing. Otherwise, this macro defines the +% control sequence |\normal@char|\m{char} to expand to the +% character in its `normal state' and it defines the active +% character to expand to |\normal@char|\m{char} by default +% (\m{char} being the character to be made active). Later its +% definition can be changed to expand to |\active@char|\m{char} +% by calling |\bbl@activate{|\m{char}|}|. % -% \begin{macrocode} -\chardef\localeid\z@ -\def\bbl@id@last{0} % No real need for a new counter -\def\bbl@id@assign{% - \bbl@ifunset{bbl@id@@\languagename}% - {\count@\bbl@id@last\relax - \advance\count@\@ne - \bbl@csarg\chardef{id@@\languagename}\count@ - \edef\bbl@id@last{\the\count@}% - \ifcase\bbl@engine\or - \directlua{ - Babel = Babel or {} - Babel.locale_props = Babel.locale_props or {} - Babel.locale_props[\bbl@id@last] = {} - Babel.locale_props[\bbl@id@last].name = '\languagename' - }% - \fi}% - {}% - \chardef\localeid\bbl@cl{id@}} -% \end{macrocode} +% For example, to make the double quote character active one could +% have |\initiate@active@char{"}| in a language definition file. +% This defines |"| as |\active@prefix "\active@char"| (where the +% first |"| is the character with its original catcode, when the +% shorthand is created, and |\active@char"| is a single token). In +% protected contexts, it expands to |\protect "| or |\noexpand "| +% (ie, with the original |"|); otherwise |\active@char"| is +% executed. This macro in turn expands to |\normal@char"| in +% ``safe'' contexts (eg, |\label|), but |\user@active"| in normal +% ``unsafe'' ones. The latter search a definition in the user, +% language and system levels, in this order, but if none is found, +% |\normal@char"| is used. However, a deactivated shorthand (with +% |\bbl@deactivate| is defined as |\active@prefix "\normal@char"|. % -% The unprotected part of |\selectlanguage|. +% The following macro is used to define shorthands in the three +% levels. It takes 4 arguments: the (string'ed) character, +% |\@group|, |@active| and |@active| +% (except in |system|). % % \begin{macrocode} -\expandafter\def\csname selectlanguage \endcsname#1{% - \ifnum\bbl@hymapsel=\@cclv\let\bbl@hymapsel\tw@\fi - \bbl@push@language - \aftergroup\bbl@pop@language - \bbl@set@language{#1}} +\def\bbl@active@def#1#2#3#4{% + \@namedef{#3#1}{% + \expandafter\ifx\csname#2@sh@#1@\endcsname\relax + \bbl@afterelse\bbl@sh@select#2#1{#3@arg#1}{#4#1}% + \else + \bbl@afterfi\csname#2@sh@#1@\endcsname + \fi}% % \end{macrocode} % -% \end{macro} +% When there is also no current-level shorthand with an argument we +% will check whether there is a next-level defined shorthand for +% this active character. % -% \begin{macro}{\bbl@set@language} +% \begin{macrocode} + \long\@namedef{#3@arg#1}##1{% + \expandafter\ifx\csname#2@sh@#1@\string##1@\endcsname\relax + \bbl@afterelse\csname#4#1\endcsname##1% + \else + \bbl@afterfi\csname#2@sh@#1@\string##1@\endcsname + \fi}}% +% \end{macrocode} % -% The macro |\bbl@set@language| takes care of switching the language -% environment \emph{and} of writing entries on the auxiliary files. -% For historial reasons, language names can be either |language| of -% |\language|. To catch either form a trick is used, but -% unfortunately as a side effect the catcodes of letters in -% |\languagename| are messed up. This is a bug, but preserved for -% backwards compatibility. The list of auxiliary files can be -% extended by redefining |\BabelContentsFiles|, but make sure they -% are loaded inside a group (as |aux|, |toc|, |lof|, and |lot| do) -% or the last language of the document will remain active -% afterwards. +% |\initiate@active@char| calls |\@initiate@active@char| with 3 +% arguments. All of them are the same character with different +% catcodes: active, other (|\string|'ed) and the original one. +% This trick simplifies the code a lot. % -% We also write a command to change the current language in the -% auxiliary files. +% \begin{macrocode} +\def\initiate@active@char#1{% + \bbl@ifunset{active@char\string#1}% + {\bbl@withactive + {\expandafter\@initiate@active@char\expandafter}#1\string#1#1}% + {}} +% \end{macrocode} % -% |\bbl@savelastskip| is used to deal with skips before the write -% whatsit (as suggested by U Fischer). Adapted from \textsf{hyperref}, -% but it might fail, so I'll consider it a temporary hack, while I -% study other options (the ideal, but very likely unfeasible except -% perhaps in \luatex, is to avoid the |\write| altogether when not -% needed). +% The very first thing to do is saving the original catcode and the +% original definition, even if not active, which is possible +% (undefined characters require a special treatement to avoid +% making them |\relax| and preserving some degree of protection). % % \begin{macrocode} -\def\BabelContentsFiles{toc,lof,lot} -\def\bbl@set@language#1{% from selectlanguage, pop@ - % The old buggy way. Preserved for compatibility. - \edef\languagename{% - \ifnum\escapechar=\expandafter`\string#1\@empty - \else\string#1\@empty\fi}% - \ifcat\relax\noexpand#1% - \expandafter\ifx\csname date\languagename\endcsname\relax - \edef\languagename{#1}% - \let\localename\languagename - \else - \bbl@info{Using '\string\language' instead of 'language' is\\% - deprecated. If what you want is to use a\\% - macro containing the actual locale, make\\% - sure it does not not match any language.\\% - Reported}% - \ifx\scantokens\@undefined - \def\localename{??}% - \else - \scantokens\expandafter{\expandafter - \def\expandafter\localename\expandafter{\languagename}}% - \fi - \fi +\def\@initiate@active@char#1#2#3{% + \bbl@csarg\edef{oricat@#2}{\catcode`#2=\the\catcode`#2\relax}% + \ifx#1\@undefined + \bbl@csarg\def{oridef@#2}{\def#1{\active@prefix#1\@undefined}}% \else - \def\localename{#1}% This one has the correct catcodes + \bbl@csarg\let{oridef@@#2}#1% + \bbl@csarg\edef{oridef@#2}{% + \let\noexpand#1% + \expandafter\noexpand\csname bbl@oridef@@#2\endcsname}% \fi - \select@language{\languagename}% - % write to auxs - \expandafter\ifx\csname date\languagename\endcsname\relax\else - \if@filesw - \ifx\babel@aux\@gobbletwo\else % Set if single in the first, redundant - \bbl@savelastskip - \protected@write\@auxout{}{\string\babel@aux{\bbl@auxname}{}}% - \bbl@restorelastskip - \fi - \bbl@usehooks{write}{}% - \fi - \fi} -% -\let\bbl@restorelastskip\relax -\def\bbl@savelastskip{% - \let\bbl@restorelastskip\relax - \ifvmode - \ifdim\lastskip=\z@ - \let\bbl@restorelastskip\nobreak - \else - \bbl@exp{% - \def\\\bbl@restorelastskip{% - \skip@=\the\lastskip - \\\nobreak \vskip-\skip@ \vskip\skip@}}% - \fi - \fi} -% -\newif\ifbbl@bcpallowed -\bbl@bcpallowedfalse -\def\select@language#1{% from set@, babel@aux - % set hymap - \ifnum\bbl@hymapsel=\@cclv\chardef\bbl@hymapsel4\relax\fi - % set name - \edef\languagename{#1}% - \bbl@fixname\languagename - % TODO. name@map must be here? - \bbl@provide@locale - \bbl@iflanguage\languagename{% - \expandafter\ifx\csname date\languagename\endcsname\relax - \bbl@error - {Unknown language '\languagename'. Either you have\\% - misspelled its name, it has not been installed,\\% - or you requested it in a previous run. Fix its name,\\% - install it or just rerun the file, respectively. In\\% - some cases, you may need to remove the aux file}% - {You may proceed, but expect wrong results}% - \else - % set type - \let\bbl@select@type\z@ - \expandafter\bbl@switch\expandafter{\languagename}% - \fi}} -\def\babel@aux#1#2{% - \select@language{#1}% - \bbl@foreach\BabelContentsFiles{% \relax -> don't assume vertical mode - \@writefile{##1}{\babel@toc{#1}{#2}\relax}}}% TODO - plain? -\def\babel@toc#1#2{% - \select@language{#1}} % \end{macrocode} % -% \end{macro} -% -% First, check if the user asks for a known language. If so, -% update the value of |\language| and call |\originalTeX| -% to bring \TeX\ in a certain pre-defined state. -% -% The name of the language is stored in the control sequence -% |\languagename|. -% -% Then we have to \emph{re}define |\originalTeX| to compensate for -% the things that have been activated. To save memory space for -% the macro definition of |\originalTeX|, we construct the control -% sequence name for the |\noextras|\langvar\ command at definition -% time by expanding the |\csname| primitive. -% -% Now activate the language-specific definitions. This is done by -% constructing the names of three macros by concatenating three -% words with the argument of |\selectlanguage|, and calling these -% macros. \nb{What if \cs{hyphenation} was used in |extras|? Patch -% temporarily |\set@hyphenmins| and hyphenation. It can be done in -% hooks if necessary.} -% -% The switching of the values of |\lefthyphenmin| and -% |\righthyphenmin| is somewhat different. First we save their -% current values, then we check if |\|\langvar|hyphenmins| is -% defined. If it is not, we set default values (2 and 3), otherwise -% the values in |\|\langvar|hyphenmins| will be used. +% If the character is already active we provide the default +% expansion under this shorthand mechanism. Otherwise we write a +% message in the transcript file, and define |\normal@char|\m{char} +% to expand to the character in its default state. If the character +% is mathematically active when \babel{} is loaded (for example +% |'|) the normal expansion is somewhat different to avoid an +% infinite loop (but it does not prevent the loop if the mathcode +% is set to |"8000| \textit{a posteriori}). % % \begin{macrocode} -\newif\ifbbl@usedategroup -\def\bbl@switch#1{% from select@, foreign@ - % make sure there is info for the language if so requested - \bbl@ensureinfo{#1}% - % restore - \originalTeX - \expandafter\def\expandafter\originalTeX\expandafter{% - \csname noextras#1\endcsname - \let\originalTeX\@empty - \babel@beginsave}% - \bbl@usehooks{afterreset}{}% - \languageshorthands{none}% - % set the locale id - \bbl@id@assign - % switch captions, date - % No text is supposed to be added here, so we remove any - % spurious spaces. - \bbl@bsphack - \ifcase\bbl@select@type - \csname captions#1\endcsname\relax - \csname date#1\endcsname\relax - \else - \bbl@xin@{,captions,}{,\bbl@select@opts,}% - \ifin@ - \csname captions#1\endcsname\relax - \fi - \bbl@xin@{,date,}{,\bbl@select@opts,}% - \ifin@ % if \foreign... within \date - \csname date#1\endcsname\relax - \fi - \fi - \bbl@esphack - % switch extras - \bbl@usehooks{beforeextras}{}% - \csname extras#1\endcsname\relax - \bbl@usehooks{afterextras}{}% - % > babel-ensure - % > babel-sh- - % > babel-bidi - % > babel-fontspec - % hyphenation - case mapping - \ifcase\bbl@opt@hyphenmap\or - \def\BabelLower##1##2{\lccode##1=##2\relax}% - \ifnum\bbl@hymapsel>4\else - \csname\languagename @bbl@hyphenmap\endcsname - \fi - \chardef\bbl@opt@hyphenmap\z@ + \ifx#1#3\relax + \expandafter\let\csname normal@char#2\endcsname#3% \else - \ifnum\bbl@hymapsel>\bbl@opt@hyphenmap\else - \csname\languagename @bbl@hyphenmap\endcsname + \bbl@info{Making #2 an active character}% + \ifnum\mathcode`#2=\ifodd\bbl@engine"1000000 \else"8000 \fi + \@namedef{normal@char#2}{% + \textormath{#3}{\csname bbl@oridef@@#2\endcsname}}% + \else + \@namedef{normal@char#2}{#3}% \fi - \fi - \let\bbl@hymapsel\@cclv - % hyphenation - select rules - \ifnum\csname l@\languagename\endcsname=\l@unhyphenated - \edef\bbl@tempa{u}% - \else - \edef\bbl@tempa{\bbl@cl{lnbrk}}% - \fi - % linebreaking - handle u, e, k (v in the future) - \bbl@xin@{/u}{/\bbl@tempa}% - \ifin@\else\bbl@xin@{/e}{/\bbl@tempa}\fi % elongated forms - \ifin@\else\bbl@xin@{/k}{/\bbl@tempa}\fi % only kashida - \ifin@\else\bbl@xin@{/v}{/\bbl@tempa}\fi % variable font - \ifin@ - % unhyphenated/kashida/elongated = allow stretching - \language\l@unhyphenated - \babel@savevariable\emergencystretch - \emergencystretch\maxdimen - \babel@savevariable\hbadness - \hbadness\@M - \else - % other = select patterns - \bbl@patterns{#1}% - \fi - % hyphenation - mins - \babel@savevariable\lefthyphenmin - \babel@savevariable\righthyphenmin - \expandafter\ifx\csname #1hyphenmins\endcsname\relax - \set@hyphenmins\tw@\thr@@\relax - \else - \expandafter\expandafter\expandafter\set@hyphenmins - \csname #1hyphenmins\endcsname\relax - \fi} % \end{macrocode} % -% \begin{environment}{otherlanguage} -% The \Lenv{otherlanguage} environment can be used as an -% alternative to using the |\selectlanguage| declarative -% command. When you are typesetting a document which mixes -% left-to-right and right-to-left typesetting you have to use this -% environment in order to let things work as you expect them to. -% -% The |\ignorespaces| command is necessary to hide the environment -% when it is entered in horizontal mode. +% To prevent problems with the loading of other packages after +% \babel\ we reset the catcode of the character to the original one +% at the end of the package and of each language file (except with +% \textsf{KeepShorthandsActive}). It is re-activate again at +% |\begin{document}|. We also need to make sure that the +% shorthands are active during the processing of the \file{.aux} +% file. Otherwise some citations may give unexpected results in +% the printout when a shorthand was used in the optional argument +% of |\bibitem| for example. Then we make it active (not strictly +% necessary, but done for backward compatibility). % % \begin{macrocode} -\long\def\otherlanguage#1{% - \ifnum\bbl@hymapsel=\@cclv\let\bbl@hymapsel\thr@@\fi - \csname selectlanguage \endcsname{#1}% - \ignorespaces} + \bbl@restoreactive{#2}% + \AtBeginDocument{% + \catcode`#2\active + \if@filesw + \immediate\write\@mainaux{\catcode`\string#2\active}% + \fi}% + \expandafter\bbl@add@special\csname#2\endcsname + \catcode`#2\active + \fi % \end{macrocode} % -% The |\endotherlanguage| part of the environment tries to hide -% itself when it is called in horizontal mode. +% Now we have set |\normal@char|\m{char}, we must define +% |\active@char|\m{char}, to be executed when the character is +% activated. We define the first level expansion of +% |\active@char|\m{char} to check the status of the |@safe@actives| +% flag. If it is set to true we expand to the `normal' version of +% this character, otherwise we call |\user@active|\m{char} to start +% the search of a definition in the user, language and system +% levels (or eventually |normal@char|\m{char}). % % \begin{macrocode} -\long\def\endotherlanguage{% - \global\@ignoretrue\ignorespaces} -% \end{macrocode} -% -% \end{environment} -% -% \begin{environment}{otherlanguage*} -% The \Lenv{otherlanguage} environment is meant to be used when a -% large part of text from a different language needs to be typeset, -% but without changing the translation of words such as `figure'. -% This environment makes use of |\foreign@language|. -% -% \begin{macrocode} -\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 - \def\bbl@select@opts{#1}% - \foreign@language{#2}} + \let\bbl@tempa\@firstoftwo + \if\string^#2% + \def\bbl@tempa{\noexpand\textormath}% + \else + \ifx\bbl@mathnormal\@undefined\else + \let\bbl@tempa\bbl@mathnormal + \fi + \fi + \expandafter\edef\csname active@char#2\endcsname{% + \bbl@tempa + {\noexpand\if@safe@actives + \noexpand\expandafter + \expandafter\noexpand\csname normal@char#2\endcsname + \noexpand\else + \noexpand\expandafter + \expandafter\noexpand\csname bbl@doactive#2\endcsname + \noexpand\fi}% + {\expandafter\noexpand\csname normal@char#2\endcsname}}% + \bbl@csarg\edef{doactive#2}{% + \expandafter\noexpand\csname user@active#2\endcsname}% % \end{macrocode} % -% At the end of the environment we need to switch off the extra -% definitions. The grouping mechanism of the environment will take -% care of resetting the correct hyphenation rules and ``extras''. +% We now define the default values which the shorthand is set to +% when activated or deactivated. It is set to the deactivated form +% (globally), so that the character expands to +% \begin{center} +% |\active@prefix| \m{char} |\normal@char|\m{char} +% \end{center} +% (where |\active@char|\m{char} is \emph{one} control sequence!). % % \begin{macrocode} -\expandafter\let\csname endotherlanguage*\endcsname\relax + \bbl@csarg\edef{active@#2}{% + \noexpand\active@prefix\noexpand#1% + \expandafter\noexpand\csname active@char#2\endcsname}% + \bbl@csarg\edef{normal@#2}{% + \noexpand\active@prefix\noexpand#1% + \expandafter\noexpand\csname normal@char#2\endcsname}% + \expandafter\let\expandafter#1\csname bbl@normal@#2\endcsname % \end{macrocode} % -% \end{environment} -% -% \begin{macro}{\foreignlanguage} -% -% The |\foreignlanguage| command is another substitute for the -% |\selectlanguage| command. This command takes two arguments, the -% first argument is the name of the language to use for typesetting -% the text specified in the second argument. -% -% Unlike |\selectlanguage| this command doesn't switch -% \emph{everything}, it only switches the hyphenation rules and the -% extra definitions for the language specified. It does this within -% a group and assumes the |\extras|\langvar\ command doesn't make -% any |\global| changes. The coding is very similar to part of -% |\selectlanguage|. +% The next level of the code checks whether a user has defined a +% shorthand for himself with this character. First we check for a +% single character shorthand. If that doesn't exist we check for a +% shorthand with an argument. % -% |\bbl@beforeforeign| is a trick to fix a bug in bidi -% texts. |\foreignlanguage| is supposed to be a `text' command, and -% therefore it must emit a |\leavevmode|, but it does not, and -% therefore the indent is placed on the opposite margin. For -% backward compatibility, however, it is done only if a -% right-to-left script is requested; otherwise, it is no-op. +% \begin{macrocode} + \bbl@active@def#2\user@group{user@active}{language@active}% + \bbl@active@def#2\language@group{language@active}{system@active}% + \bbl@active@def#2\system@group{system@active}{normal@char}% +% \end{macrocode} % -% (3.11) |\foreignlanguage*| is a temporary, experimental macro for -% a few lines with a different script direction, while preserving -% the paragraph format (thank the braces around |\par|, things like -% |\hangindent| are not reset). Do not use it in production, -% because its semantics and its syntax may change (and very likely -% will, or even it could be removed altogether). Currently it -% enters in vmode and then selects the language (which in turn sets the -% paragraph direction). +% In order to do the right thing when a shorthand with an argument +% is used by itself at the end of the line we provide a definition +% for the case of an empty argument. For that case we let the +% shorthand character expand to its non-active self. Also, When a +% shorthand combination such as |''| ends up in a heading \TeX\ +% would see |\protect'\protect'|. To prevent this from happening a +% couple of shorthand needs to be defined at user level. % -% (3.11) Also experimental are the hook |foreign| and |foreign*|. -% With them you can redefine |\BabelText| which by default does -% nothing. Its behavior is not well defined yet. So, use it in -% horizontal mode only if you do not want surprises. +% \begin{macrocode} + \expandafter\edef\csname\user@group @sh@#2@@\endcsname + {\expandafter\noexpand\csname normal@char#2\endcsname}% + \expandafter\edef\csname\user@group @sh@#2@\string\protect@\endcsname + {\expandafter\noexpand\csname user@active#2\endcsname}% +% \end{macrocode} % -% In other words, at the beginning of a paragraph |\foreignlanguage| -% enters into hmode with the surrounding lang, and with -% |\foreignlanguage*| with the new lang. +% Finally, a couple of special cases are taken care of. (1) If we +% are making the right quote (|'|) active we need to change |\pr@m@s| as +% well. Also, make sure that a single |'| in math mode `does the +% right thing'. (2) If we are using the caret (|^|) as a shorthand +% character special care should be taken to make sure math still +% works. Therefore an extra level of expansion is introduced with a +% check for math mode on the upper level. % % \begin{macrocode} -\providecommand\bbl@beforeforeign{} -\edef\foreignlanguage{% - \noexpand\protect - \expandafter\noexpand\csname foreignlanguage \endcsname} -\expandafter\def\csname foreignlanguage \endcsname{% - \@ifstar\bbl@foreign@s\bbl@foreign@x} -\providecommand\bbl@foreign@x[3][]{% - \begingroup - \def\bbl@select@opts{#1}% - \let\BabelText\@firstofone - \bbl@beforeforeign - \foreign@language{#2}% - \bbl@usehooks{foreign}{}% - \BabelText{#3}% Now in horizontal mode! - \endgroup} -\def\bbl@foreign@s#1#2{% TODO - \shapemode, \@setpar, ?\@@par - \begingroup - {\par}% - \let\bbl@select@opts\@empty - \let\BabelText\@firstofone - \foreign@language{#1}% - \bbl@usehooks{foreign*}{}% - \bbl@dirparastext - \BabelText{#2}% Still in vertical mode! - {\par}% - \endgroup} + \if\string'#2% + \let\prim@s\bbl@prim@s + \let\active@math@prime#1% + \fi + \bbl@usehooks{initiateactive}{{#1}{#2}{#3}}} % \end{macrocode} % -% \end{macro} +% The following package options control the behavior of shorthands +% in math mode. % -% \begin{macro}{\foreign@language} +% \begin{macrocode} +%<<*More package options>> +\DeclareOption{math=active}{} +\DeclareOption{math=normal}{\def\bbl@mathnormal{\noexpand\textormath}} +%<> +% \end{macrocode} % -% This macro does the work for |\foreignlanguage| and the -% \Lenv{otherlanguage*} environment. First we need to store the name -% of the language and check that it is a known language. Then it -% just calls |bbl@switch|. +% Initiating a shorthand makes active the char. That is not +% strictly necessary but it is still done for backward +% compatibility. So we need to restore the original catcode at the +% end of package \textit{and} and the end of the |ldf|. % % \begin{macrocode} -\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 - \bbl@iflanguage\languagename{% - \expandafter\ifx\csname date\languagename\endcsname\relax - \bbl@warning % TODO - why a warning, not an error? - {Unknown language '#1'. Either you have\\% - misspelled its name, it has not been installed,\\% - or you requested it in a previous run. Fix its name,\\% - install it or just rerun the file, respectively. In\\% - some cases, you may need to remove the aux file.\\% - I'll proceed, but expect wrong results.\\% - Reported}% - \fi - % set type - \let\bbl@select@type\@ne - \expandafter\bbl@switch\expandafter{\languagename}}} +\@ifpackagewith{babel}{KeepShorthandsActive}% + {\let\bbl@restoreactive\@gobble}% + {\def\bbl@restoreactive#1{% + \bbl@exp{% + \\\AfterBabelLanguage\\\CurrentOption + {\catcode`#1=\the\catcode`#1\relax}% + \\\AtEndOfPackage + {\catcode`#1=\the\catcode`#1\relax}}}% + \AtEndOfPackage{\let\bbl@restoreactive\@gobble}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@patterns} -% -% This macro selects the hyphenation patterns by changing the -% \cs{language} register. If special hyphenation patterns -% are available specifically for the current font encoding, -% use them instead of the default. +% \begin{macro}{\bbl@sh@select} +% This command helps the shorthand supporting macros to select how +% to proceed. Note that this macro needs to be expandable as do all +% the shorthand macros in order for them to work in expansion-only +% environments such as the argument of |\hyphenation|. % -% It also sets hyphenation exceptions, but only once, because they -% are global (here language |\lccode|'s has been set, too). -% |\bbl@hyphenation@| is set to relax until the very first -% |\babelhyphenation|, so do nothing with this value. If the -% exceptions for a language (by its number, not its name, so that -% |:ENC| is taken into account) has been set, then use -% |\hyphenation| with both global and language exceptions and empty -% the latter to mark they must not be set again. +% This macro expects the name of a group of shorthands in its first +% argument and a shorthand character in its second argument. It +% will expand to either |\bbl@firstcs| or |\bbl@scndcs|. Hence two +% more arguments need to follow it. % % \begin{macrocode} -\let\bbl@hyphlist\@empty -\let\bbl@hyphenation@\relax -\let\bbl@pttnlist\@empty -\let\bbl@patterns@\relax -\let\bbl@hymapsel=\@cclv -\def\bbl@patterns#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 - \@expandtwoargs\bbl@usehooks{patterns}{{#1}{\bbl@tempa}}% - % > luatex - \@ifundefined{bbl@hyphenation@}{}{% Can be \relax! - \begingroup - \bbl@xin@{,\number\language,}{,\bbl@hyphlist}% - \ifin@\else - \@expandtwoargs\bbl@usehooks{hyphenation}{{#1}{\bbl@tempa}}% - \hyphenation{% - \bbl@hyphenation@ - \@ifundefined{bbl@hyphenation@#1}% - \@empty - {\space\csname bbl@hyphenation@#1\endcsname}}% - \xdef\bbl@hyphlist{\bbl@hyphlist\number\language,}% - \fi - \endgroup}} +\def\bbl@sh@select#1#2{% + \expandafter\ifx\csname#1@sh@#2@sel\endcsname\relax + \bbl@afterelse\bbl@scndcs + \else + \bbl@afterfi\csname#1@sh@#2@sel\endcsname + \fi} % \end{macrocode} % % \end{macro} % -% \begin{environment}{hyphenrules} -% -% The environment \Lenv{hyphenrules} can be used to select -% \emph{just} the hyphenation rules. This environment does -% \emph{not} change |\languagename| and when the hyphenation rules -% specified were not loaded it has no effect. Note however, -% |\lccode|'s and font encodings are not set at all, so in most -% cases you should use |otherlanguage*|. +% \begin{macro}{\active@prefix} +% The command |\active@prefix| which is used in the expansion of +% active characters has a function similar to |\OT1-cmd| in that it +% |\protect|s the active character whenever |\protect| is +% \emph{not} |\@typeset@protect|. The |\@gobble| is needed to remove +% a token such as |\activechar:| (when the double colon was the +% active character to be dealt with). There are two definitions, +% depending of |\ifincsname| is available. If there is, the +% expansion will be more robust. % % \begin{macrocode} -\def\hyphenrules#1{% - \edef\bbl@tempf{#1}% - \bbl@fixname\bbl@tempf - \bbl@iflanguage\bbl@tempf{% - \expandafter\bbl@patterns\expandafter{\bbl@tempf}% - \ifx\languageshorthands\@undefined\else - \languageshorthands{none}% - \fi - \expandafter\ifx\csname\bbl@tempf hyphenmins\endcsname\relax - \set@hyphenmins\tw@\thr@@\relax - \else - \expandafter\expandafter\expandafter\set@hyphenmins - \csname\bbl@tempf hyphenmins\endcsname\relax - \fi}} -\let\endhyphenrules\@empty +\begingroup +\bbl@ifunset{ifincsname}% TODO. Ugly. Correct? Only Plain? + {\gdef\active@prefix#1{% + \ifx\protect\@typeset@protect + \else + \ifx\protect\@unexpandable@protect + \noexpand#1% + \else + \protect#1% + \fi + \expandafter\@gobble + \fi}} + {\gdef\active@prefix#1{% + \ifincsname + \string#1% + \expandafter\@gobble + \else + \ifx\protect\@typeset@protect + \else + \ifx\protect\@unexpandable@protect + \noexpand#1% + \else + \protect#1% + \fi + \expandafter\expandafter\expandafter\@gobble + \fi + \fi}} +\endgroup % \end{macrocode} % -% \end{environment} +% \end{macro} % -% \begin{macro}{\providehyphenmins} -% The macro |\providehyphenmins| should be used in the language -% definition files to provide a \emph{default} setting for the -% hyphenation parameters |\lefthyphenmin| and |\righthyphenmin|. If -% the macro |\|\langvar|hyphenmins| is already defined this command -% has no effect. +% \begin{macro}{\if@safe@actives} +% In some circumstances it is necessary to be able to change the +% expansion of an active character on the fly. For this purpose the +% switch |@safe@actives| is available. The setting of this switch +% should be checked in the first level expansion of +% |\active@char|\m{char}. % % \begin{macrocode} -\def\providehyphenmins#1#2{% - \expandafter\ifx\csname #1hyphenmins\endcsname\relax - \@namedef{#1hyphenmins}{#2}% - \fi} +\newif\if@safe@actives +\@safe@activesfalse % \end{macrocode} % % \end{macro} % -% \begin{macro}{\set@hyphenmins} -% This macro sets the values of |\lefthyphenmin| and -% |\righthyphenmin|. It expects two values as its argument. +% \begin{macro}{\bbl@restore@actives} +% When the output routine kicks in while the +% active characters were made ``safe'' this must be undone in +% the headers to prevent unexpected typeset results. For this +% situation we define a command to make them ``unsafe'' again. % % \begin{macrocode} -\def\set@hyphenmins#1#2{% - \lefthyphenmin#1\relax - \righthyphenmin#2\relax} +\def\bbl@restore@actives{\if@safe@actives\@safe@activesfalse\fi} % \end{macrocode} % -% \end{macro} +% \end{macro} % -% \begin{macro}{\ProvidesLanguage} -% The identification code for each file is something that was -% introduced in \LaTeXe. When the command |\ProvidesFile| does not -% exist, a dummy definition is provided temporarily. For use in the -% language definition file the command |\ProvidesLanguage| is -% defined by \babel. +% \begin{macro}{\bbl@activate} +% \begin{macro}{\bbl@deactivate} % -% Depending on the format, ie, on if the former is defined, we use -% a similar definition or not. +% Both macros take one argument, like |\initiate@active@char|. The +% macro is used to change the definition of an active character to +% expand to |\active@char|\m{char} in the case of |\bbl@activate|, +% or |\normal@char|\m{char} in the case of |\bbl@deactivate|. % % \begin{macrocode} -\ifx\ProvidesFile\@undefined - \def\ProvidesLanguage#1[#2 #3 #4]{% - \wlog{Language: #1 #4 #3 <#2>}% - } -\else - \def\ProvidesLanguage#1{% - \begingroup - \catcode`\ 10 % - \@makeother\/% - \@ifnextchar[%] - {\@provideslanguage{#1}}{\@provideslanguage{#1}[]}} - \def\@provideslanguage#1[#2]{% - \wlog{Language: #1 #2}% - \expandafter\xdef\csname ver@#1.ldf\endcsname{#2}% - \endgroup} -\fi +\chardef\bbl@activated\z@ +\def\bbl@activate#1{% + \chardef\bbl@activated\@ne + \bbl@withactive{\expandafter\let\expandafter}#1% + \csname bbl@active@\string#1\endcsname} +\def\bbl@deactivate#1{% + \chardef\bbl@activated\tw@ + \bbl@withactive{\expandafter\let\expandafter}#1% + \csname bbl@normal@\string#1\endcsname} % \end{macrocode} % % \end{macro} +% \end{macro} % -% \begin{macro}{\originalTeX} -% The macro|\originalTeX| should be known to \TeX\ at this moment. -% As it has to be expandable we |\let| it to |\@empty| instead of -% |\relax|. +% \begin{macro}{\bbl@firstcs} +% \begin{macro}{\bbl@scndcs} +% +% These macros are used only as a trick when declaring shorthands. % % \begin{macrocode} -\ifx\originalTeX\@undefined\let\originalTeX\@empty\fi +\def\bbl@firstcs#1#2{\csname#1\endcsname} +\def\bbl@scndcs#1#2{\csname#2\endcsname} % \end{macrocode} % -% Because this part of the code can be included in a format, we -% make sure that the macro which initializes the save mechanism, -% |\babel@beginsave|, is not considered to be undefined. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\declare@shorthand} +% The command |\declare@shorthand| is used to declare a shorthand +% on a certain level. It takes three arguments: +% \begin{enumerate} +% \item a name for the collection of shorthands, i.e. `system', or +% `dutch'; +% \item the character (sequence) that makes up the shorthand, +% i.e. |~| or |"a|; +% \item the code to be executed when the shorthand is encountered. +% \end{enumerate} % +% The auxiliary macro |\babel@texpdf| improves the interoperativity with +% \textsf{hyperref} and takes 4 arguments: (1) The \TeX{} code in text +% mode, (2) the string for \textsf{hyperref}, (3) the \TeX{} code in +% math mode, and (4), which is currently ignored, but it's meant for a +% string in math mode, like a minus sign instead of an hyphen +% (currently \textsf{hyperref} doesn't discriminate the mode). This +% macro may be used in |ldf| files. + % \begin{macrocode} -\ifx\babel@beginsave\@undefined\let\babel@beginsave\relax\fi +\def\babel@texpdf#1#2#3#4{% + \ifx\texorpdfstring\@undefined + \textormath{#1}{#3}% + \else + \texorpdfstring{\textormath{#1}{#3}}{#2}% + % \texorpdfstring{\textormath{#1}{#3}}{\textormath{#2}{#4}}% + \fi} +% +\def\declare@shorthand#1#2{\@decl@short{#1}#2\@nil} +\def\@decl@short#1#2#3\@nil#4{% + \def\bbl@tempa{#3}% + \ifx\bbl@tempa\@empty + \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@scndcs + \bbl@ifunset{#1@sh@\string#2@}{}% + {\def\bbl@tempa{#4}% + \expandafter\ifx\csname#1@sh@\string#2@\endcsname\bbl@tempa + \else + \bbl@info + {Redefining #1 shorthand \string#2\\% + in language \CurrentOption}% + \fi}% + \@namedef{#1@sh@\string#2@}{#4}% + \else + \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@firstcs + \bbl@ifunset{#1@sh@\string#2@\string#3@}{}% + {\def\bbl@tempa{#4}% + \expandafter\ifx\csname#1@sh@\string#2@\string#3@\endcsname\bbl@tempa + \else + \bbl@info + {Redefining #1 shorthand \string#2\string#3\\% + in language \CurrentOption}% + \fi}% + \@namedef{#1@sh@\string#2@\string#3@}{#4}% + \fi} % \end{macrocode} % % \end{macro} % -% A few macro names are reserved for future releases of \babel, which -% will use the concept of `locale': +% \begin{macro}{\textormath} +% Some of the shorthands that will be declared by the language +% definition files have to be usable in both text and mathmode. To +% achieve this the helper macro |\textormath| is provided. % % \begin{macrocode} -\providecommand\setlocale{% - \bbl@error - {Not yet available}% - {Find an armchair, sit down and wait}} -\let\uselocale\setlocale -\let\locale\setlocale -\let\selectlocale\setlocale -\let\localename\setlocale -\let\textlocale\setlocale -\let\textlanguage\setlocale -\let\languagetext\setlocale +\def\textormath{% + \ifmmode + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} % \end{macrocode} % -% \subsection{Errors} +% \end{macro} % -% \begin{macro}{\@nolanerr} -% \begin{macro}{\@nopatterns} +% \begin{macro}{\user@group} +% \begin{macro}{\language@group} +% \begin{macro}{\system@group} +% The current concept of `shorthands' supports three levels or +% groups of shorthands. For each level the name of the level or +% group is stored in a macro. The default is to have a user group; +% use language group `english' and have a system group called +% `system'. % -% The \babel\ package will signal an error when a documents tries -% to select a language that hasn't been defined earlier. When a -% user selects a language for which no hyphenation patterns were -% loaded into the format he will be given a warning about that -% fact. We revert to the patterns for |\language|=0 in that case. -% In most formats that will be (US)english, but it might also be -% empty. +% \begin{macrocode} +\def\user@group{user} +\def\language@group{english} % TODO. I don't like defaults +\def\system@group{system} +% \end{macrocode} % -% \begin{macro}{\@noopterr} -% When the package was loaded without options not everything will -% work as expected. An error message is issued in that case. +% \end{macro} +% \end{macro} +% \end{macro} % -% When the format knows about |\PackageError| it must be \LaTeXe, -% so we can safely use its error handling interface. Otherwise -% we'll have to `keep it simple'. +% \begin{macro}{\useshorthands} % -% Infos are not written to the console, but on the other hand many -% people think warnings are errors, so a further message type is -% defined: an important info which is sent to the console. +% This is the user level macro. It initializes and activates the +% character for use as a shorthand character (ie, it's active in the +% preamble). Languages can deactivate shorthands, so a starred +% version is also provided which activates them always after the +% language has been switched. % % \begin{macrocode} -\edef\bbl@nulllanguage{\string\language=0} -\ifx\PackageError\@undefined % TODO. Move to Plain - \def\bbl@error#1#2{% - \begingroup - \newlinechar=`\^^J - \def\\{^^J(babel) }% - \errhelp{#2}\errmessage{\\#1}% - \endgroup} - \def\bbl@warning#1{% - \begingroup - \newlinechar=`\^^J - \def\\{^^J(babel) }% - \message{\\#1}% - \endgroup} - \let\bbl@infowarn\bbl@warning - \def\bbl@info#1{% - \begingroup - \newlinechar=`\^^J - \def\\{^^J}% - \wlog{#1}% - \endgroup} -\fi -\def\bbl@nocaption{\protect\bbl@nocaption@i} -\def\bbl@nocaption@i#1#2{% 1: text to be printed 2: caption macro \langXname - \global\@namedef{#2}{\textbf{?#1?}}% - \@nameuse{#2}% - \edef\bbl@tempa{#1}% - \bbl@sreplace\bbl@tempa{name}{}% - \bbl@warning{% TODO. - \@backslashchar#1 not set for '\languagename'. Please,\\% - define it after the language has been loaded\\% - (typically in the preamble) with:\\% - \string\setlocalecaption{\languagename}{\bbl@tempa}{..}\\% - Reported}} -\def\bbl@tentative{\protect\bbl@tentative@i} -\def\bbl@tentative@i#1{% - \bbl@warning{% - Some functions for '#1' are tentative.\\% - They might not work as expected and their behavior\\% - could change in the future.\\% - Reported}} -\def\@nolanerr#1{% - \bbl@error - {You haven't defined the language '#1' yet.\\% - Perhaps you misspelled it or your installation\\% - is not complete}% - {Your command will be ignored, type to proceed}} -\def\@nopatterns#1{% - \bbl@warning - {No hyphenation patterns were preloaded for\\% - the language '#1' into the format.\\% - Please, configure your TeX system to add them and\\% - rebuild the format. Now I will use the patterns\\% - preloaded for \bbl@nulllanguage\space instead}} -\let\bbl@usehooks\@gobbletwo -\ifx\bbl@onlyswitch\@empty\endinput\fi - % Here ended switch.def +\def\useshorthands{% + \@ifstar\bbl@usesh@s{\bbl@usesh@x{}}} +\def\bbl@usesh@s#1{% + \bbl@usesh@x + {\AddBabelHook{babel-sh-\string#1}{afterextras}{\bbl@activate{#1}}}% + {#1}} +\def\bbl@usesh@x#1#2{% + \bbl@ifshorthand{#2}% + {\def\user@group{user}% + \initiate@active@char{#2}% + #1% + \bbl@activate{#2}}% + {\bbl@error + {I can't declare a shorthand turned off (\string#2)} + {Sorry, but you can't use shorthands which have been\\% + turned off in the package options}}} % \end{macrocode} % -% Here ended |switch.def|. -% -% \begin{macrocode} -\ifx\directlua\@undefined\else - \ifx\bbl@luapatterns\@undefined - \input luababel.def - \fi -\fi -<@Basic macros@> -\bbl@trace{Compatibility with language.def} -\ifx\bbl@languages\@undefined - \ifx\directlua\@undefined - \openin1 = language.def % TODO. Remove hardcoded number - \ifeof1 - \closein1 - \message{I couldn't find the file language.def} - \else - \closein1 - \begingroup - \def\addlanguage#1#2#3#4#5{% - \expandafter\ifx\csname lang@#1\endcsname\relax\else - \global\expandafter\let\csname l@#1\expandafter\endcsname - \csname lang@#1\endcsname - \fi}% - \def\uselanguage#1{}% - \input language.def - \endgroup - \fi - \fi - \chardef\l@english\z@ -\fi -% \end{macrocode} +% \end{macro} % -% \begin{macro}{\addto} -% It takes two arguments, a \meta{control sequence} and \TeX-code to -% be added to the \meta{control sequence}. +% \begin{macro}{\defineshorthand} % -% If the \meta{control sequence} has not been defined before it is -% defined now. The control sequence could also expand to |\relax|, -% in which case a circular definition results. The net result is a -% stack overflow. Note there is an inconsistency, because the -% assignment in the last branch is global. +% Currently we only support two groups of user level shorthands, +% named internally |user| and |user@| (language-dependent +% user shorthands). By default, only the first one is taken into +% account, but if the former is also used (in the optional argument +% of |\defineshorthand|) a new level is inserted for it +% (|user@generic|, done by |\bbl@set@user@generic|); we make also +% sure |{}| and |\protect| are taken into account in this new top +% level. % % \begin{macrocode} -\def\addto#1#2{% - \ifx#1\@undefined - \def#1{#2}% - \else - \ifx#1\relax - \def#1{#2}% - \else - {\toks@\expandafter{#1#2}% - \xdef#1{\the\toks@}}% +\def\user@language@group{user@\language@group} +\def\bbl@set@user@generic#1#2{% + \bbl@ifunset{user@generic@active#1}% + {\bbl@active@def#1\user@language@group{user@active}{user@generic@active}% + \bbl@active@def#1\user@group{user@generic@active}{language@active}% + \expandafter\edef\csname#2@sh@#1@@\endcsname{% + \expandafter\noexpand\csname normal@char#1\endcsname}% + \expandafter\edef\csname#2@sh@#1@\string\protect@\endcsname{% + \expandafter\noexpand\csname user@active#1\endcsname}}% + \@empty} +\newcommand\defineshorthand[3][user]{% + \edef\bbl@tempa{\zap@space#1 \@empty}% + \bbl@for\bbl@tempb\bbl@tempa{% + \if*\expandafter\@car\bbl@tempb\@nil + \edef\bbl@tempb{user@\expandafter\@gobble\bbl@tempb}% + \@expandtwoargs + \bbl@set@user@generic{\expandafter\string\@car#2\@nil}\bbl@tempb \fi - \fi} + \declare@shorthand{\bbl@tempb}{#2}{#3}}} % \end{macrocode} % % \end{macro} % -% The macro |\initiate@active@char| below takes all the necessary -% actions to make its argument a shorthand character. The real work -% is performed once for each character. But first we define a little -% tool. TODO. Always used with additional expansions. Move them here? -% Move the macro to basic? +% \begin{macro}{\languageshorthands} +% +% A user level command to change the language from which shorthands +% are used. Unfortunately, \babel{} currently does not keep track +% of defined groups, and therefore there is no way to catch a +% possible change in casing to fix it in the same way languages names +% are fixed. [TODO]. % % \begin{macrocode} -\def\bbl@withactive#1#2{% - \begingroup - \lccode`~=`#2\relax - \lowercase{\endgroup#1~}} +\def\languageshorthands#1{\def\language@group{#1}} % \end{macrocode} % -% \begin{macro}{\bbl@redefine} +% \end{macro} +% +% \begin{macro}{\aliasshorthand} +% First the new shorthand needs to be initialized. Then, we define +% the new shorthand in terms of the original one, but note with +% |\aliasshorthands{"}{/}| is |\active@prefix /\active@char/|, so we +% still need to let the lattest to |\active@char"|. % -% To redefine a command, we save the old meaning of the macro. Then -% we redefine it to call the original macro with the `sanitized' -% argument. The reason why we do it this way is that we don't want -% to redefine the \LaTeX\ macros completely in case their -% definitions change (they have changed in the past). A macro named -% |\macro| will be saved new control sequences named |\org@macro|. % % \begin{macrocode} -\def\bbl@redefine#1{% - \edef\bbl@tempa{\bbl@stripslash#1}% - \expandafter\let\csname org@\bbl@tempa\endcsname#1% - \expandafter\def\csname\bbl@tempa\endcsname} -\@onlypreamble\bbl@redefine +\def\aliasshorthand#1#2{% + \bbl@ifshorthand{#2}% + {\expandafter\ifx\csname active@char\string#2\endcsname\relax + \ifx\document\@notprerr + \@notshorthand{#2}% + \else + \initiate@active@char{#2}% + \expandafter\let\csname active@char\string#2\expandafter\endcsname + \csname active@char\string#1\endcsname + \expandafter\let\csname normal@char\string#2\expandafter\endcsname + \csname normal@char\string#1\endcsname + \bbl@activate{#2}% + \fi + \fi}% + {\bbl@error + {Cannot declare a shorthand turned off (\string#2)} + {Sorry, but you cannot use shorthands which have been\\% + turned off in the package options}}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@redefine@long} -% This version of |\babel@redefine| can be used to redefine |\long| -% commands such as |\ifthenelse|. +% \begin{macro}{\@notshorthand} % % \begin{macrocode} -\def\bbl@redefine@long#1{% - \edef\bbl@tempa{\bbl@stripslash#1}% - \expandafter\let\csname org@\bbl@tempa\endcsname#1% - \expandafter\long\expandafter\def\csname\bbl@tempa\endcsname} -\@onlypreamble\bbl@redefine@long +\def\@notshorthand#1{% + \bbl@error{% + The character '\string #1' should be made a shorthand character;\\% + add the command \string\useshorthands\string{#1\string} to + the preamble.\\% + I will ignore your instruction}% + {You may proceed, but expect unexpected results}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@redefinerobust} -% For commands that are redefined, but which \textit{might} be -% robust we need a slightly more intelligent macro. A robust -% command |foo| is defined to expand to |\protect|\verb*|\foo |. So -% it is necessary to check whether \verb*|\foo | exists. The result -% is that the command that is being redefined is always robust -% afterwards. Therefore all we need to do now is define \verb*|\foo |. +% \begin{macro}{\shorthandon} +% \begin{macro}{\shorthandoff} +% The first level definition of these macros just passes the +% argument on to |\bbl@switch@sh|, adding |\@nil| at the end to +% denote the end of the list of characters. % % \begin{macrocode} -\def\bbl@redefinerobust#1{% - \edef\bbl@tempa{\bbl@stripslash#1}% - \bbl@ifunset{\bbl@tempa\space}% - {\expandafter\let\csname org@\bbl@tempa\endcsname#1% - \bbl@exp{\def\\#1{\\\protect\<\bbl@tempa\space>}}}% - {\bbl@exp{\let\\<\bbl@tempa\space>}}% - \@namedef{\bbl@tempa\space}} -\@onlypreamble\bbl@redefinerobust +\newcommand*\shorthandon[1]{\bbl@switch@sh\@ne#1\@nnil} +\DeclareRobustCommand*\shorthandoff{% + \@ifstar{\bbl@shorthandoff\tw@}{\bbl@shorthandoff\z@}} +\def\bbl@shorthandoff#1#2{\bbl@switch@sh#1#2\@nnil} % \end{macrocode} % -% \end{macro} +% \begin{macro}{\bbl@switch@sh} % -% \subsection{Hooks} +% The macro |\bbl@switch@sh| takes the list of characters apart one +% by one and subsequently switches the category code of the +% shorthand character according to the first argument of +% |\bbl@switch@sh|. % -% Admittedly, the current implementation is a somewhat simplistic and -% does very little to catch errors, but it is meant for developers, -% after all. |\bbl@usehooks| is the commands used by \babel{} to execute -% hooks defined for an event. +% But before any of this switching takes place we make sure that the +% character we are dealing with is known as a shorthand character. +% If it is, a macro such as |\active@char"| should exist. % -% \begin{macrocode} -\bbl@trace{Hooks} -\newcommand\AddBabelHook[3][]{% - \bbl@ifunset{bbl@hk@#2}{\EnableBabelHook{#2}}{}% - \def\bbl@tempa##1,#3=##2,##3\@empty{\def\bbl@tempb{##2}}% - \expandafter\bbl@tempa\bbl@evargs,#3=,\@empty - \bbl@ifunset{bbl@ev@#2@#3@#1}% - {\bbl@csarg\bbl@add{ev@#3@#1}{\bbl@elth{#2}}}% - {\bbl@csarg\let{ev@#2@#3@#1}\relax}% - \bbl@csarg\newcommand{ev@#2@#3@#1}[\bbl@tempb]} -\newcommand\EnableBabelHook[1]{\bbl@csarg\let{hk@#1}\@firstofone} -\newcommand\DisableBabelHook[1]{\bbl@csarg\let{hk@#1}\@gobble} -\def\bbl@usehooks#1#2{% - \ifx\UseHook\@undefined\else\UseHook{babel/#1}\fi - \def\bbl@elth##1{% - \bbl@cs{hk@##1}{\bbl@cs{ev@##1@#1@}#2}}% - \bbl@cs{ev@#1@}% - \ifx\languagename\@undefined\else % Test required for Plain (?) - \ifx\UseHook\@undefined\else\UseHook{babel/#1/\languagename}\fi - \def\bbl@elth##1{% - \bbl@cs{hk@##1}{\bbl@cl{ev@##1@#1}#2}}% - \bbl@cl{ev@#1}% +% Switching off and on is easy -- we just set the category code to +% `other' (12) and |\active|. With the starred version, the original +% catcode and the original definition, saved in +% |@initiate@active@char|, are restored. +% +% \begin{macrocode} +\def\bbl@switch@sh#1#2{% + \ifx#2\@nnil\else + \bbl@ifunset{bbl@active@\string#2}% + {\bbl@error + {I can't switch '\string#2' on or off--not a shorthand}% + {This character is not a shorthand. Maybe you made\\% + a typing mistake? I will ignore your instruction.}}% + {\ifcase#1% off, on, off* + \catcode`#212\relax + \or + \catcode`#2\active + \bbl@ifunset{bbl@shdef@\string#2}% + {}% + {\bbl@withactive{\expandafter\let\expandafter}#2% + \csname bbl@shdef@\string#2\endcsname + \bbl@csarg\let{shdef@\string#2}\relax}% + \ifcase\bbl@activated\or + \bbl@activate{#2}% + \else + \bbl@deactivate{#2}% + \fi + \or + \bbl@ifunset{bbl@shdef@\string#2}% + {\bbl@withactive{\bbl@csarg\let{shdef@\string#2}}#2}% + {}% + \csname bbl@oricat@\string#2\endcsname + \csname bbl@oridef@\string#2\endcsname + \fi}% + \bbl@afterfi\bbl@switch@sh#1% \fi} % \end{macrocode} % -% To ensure forward compatibility, arguments in hooks are set -% implicitly. So, if a further argument is added in the future, -% there is no need to change the existing code. Note events -% intended for \textsf{hyphen.cfg} are also loaded (just in -% case you need them for some reason). +% \end{macro} +% \end{macro} +% \end{macro} +% +% Note the value is that at the expansion time; eg, in the preample +% shorhands are usually deactivated. % % \begin{macrocode} -\def\bbl@evargs{,% <- don't delete this comma - everylanguage=1,loadkernel=1,loadpatterns=1,loadexceptions=1,% - adddialect=2,patterns=2,defaultcommands=0,encodedcommands=2,write=0,% - beforeextras=0,afterextras=0,stopcommands=0,stringprocess=0,% - hyphenation=2,initiateactive=3,afterreset=0,foreign=0,foreign*=0,% - beforestart=0,languagename=2} -\ifx\NewHook\@undefined\else - \def\bbl@tempa#1=#2\@@{\NewHook{babel/#1}} - \bbl@foreach\bbl@evargs{\bbl@tempa#1\@@} +\def\babelshorthand{\active@prefix\babelshorthand\bbl@putsh} +\def\bbl@putsh#1{% + \bbl@ifunset{bbl@active@\string#1}% + {\bbl@putsh@i#1\@empty\@nnil}% + {\csname bbl@active@\string#1\endcsname}} +\def\bbl@putsh@i#1#2\@nnil{% + \csname\language@group @sh@\string#1@% + \ifx\@empty#2\else\string#2@\fi\endcsname} +\ifx\bbl@opt@shorthands\@nnil\else + \let\bbl@s@initiate@active@char\initiate@active@char + \def\initiate@active@char#1{% + \bbl@ifshorthand{#1}{\bbl@s@initiate@active@char{#1}}{}} + \let\bbl@s@switch@sh\bbl@switch@sh + \def\bbl@switch@sh#1#2{% + \ifx#2\@nnil\else + \bbl@afterfi + \bbl@ifshorthand{#2}{\bbl@s@switch@sh#1{#2}}{\bbl@switch@sh#1}% + \fi} + \let\bbl@s@activate\bbl@activate + \def\bbl@activate#1{% + \bbl@ifshorthand{#1}{\bbl@s@activate{#1}}{}} + \let\bbl@s@deactivate\bbl@deactivate + \def\bbl@deactivate#1{% + \bbl@ifshorthand{#1}{\bbl@s@deactivate{#1}}{}} \fi % \end{macrocode} % -% \begin{macro}{\babelensure} +% You may want to test if a character is a shorthand. Note it does not +% test whether the shorthand is on or off. % -% The user command just parses the optional argument and creates a -% new macro named |\bbl@e@|\m{language}. We register a hook at the -% |afterextras| event which just executes this macro in a -% ``complete'' selection (which, if undefined, is |\relax| and does -% nothing). This part is somewhat involved because we have to make -% sure things are expanded the correct number of times. +% \begin{macrocode} +\newcommand\ifbabelshorthand[3]{\bbl@ifunset{bbl@active@\string#1}{#3}{#2}} +% \end{macrocode} % -% The macro |\bbl@e@|\m{language} contains -% |\bbl@ensure|\marg{include}\marg{exclude}\marg{fontenc}, which in in -% turn loops over the macros names in |\bbl@captionslist|, excluding -% (with the help of |\in@|) those in the |exclude| list. If the -% |fontenc| is given (and not |\relax|), the |\fontencoding| is also -% added. Then we loop over the |include| list, but if the macro -% already contains |\foreignlanguage|, nothing is done. Note this -% macro (1) is not restricted to the preamble, and (2) changes are -% local. +% \begin{macro}{\bbl@prim@s} +% \begin{macro}{\bbl@pr@m@s} +% +% One of the internal macros that are involved in substituting |\prime| +% for each right quote in mathmode is |\prim@s|. This checks if the +% next character is a right quote. When the right quote is active, the +% definition of this macro needs to be adapted to look also for an +% active right quote; the hat could be active, too. % % \begin{macrocode} -\bbl@trace{Defining babelensure} -\newcommand\babelensure[2][]{% TODO - revise test files - \AddBabelHook{babel-ensure}{afterextras}{% - \ifcase\bbl@select@type - \bbl@cl{e}% - \fi}% - \begingroup - \let\bbl@ens@include\@empty - \let\bbl@ens@exclude\@empty - \def\bbl@ens@fontenc{\relax}% - \def\bbl@tempb##1{% - \ifx\@empty##1\else\noexpand##1\expandafter\bbl@tempb\fi}% - \edef\bbl@tempa{\bbl@tempb#1\@empty}% - \def\bbl@tempb##1=##2\@@{\@namedef{bbl@ens@##1}{##2}}% - \bbl@foreach\bbl@tempa{\bbl@tempb##1\@@}% - \def\bbl@tempc{\bbl@ensure}% - \expandafter\bbl@add\expandafter\bbl@tempc\expandafter{% - \expandafter{\bbl@ens@include}}% - \expandafter\bbl@add\expandafter\bbl@tempc\expandafter{% - \expandafter{\bbl@ens@exclude}}% - \toks@\expandafter{\bbl@tempc}% - \bbl@exp{% - \endgroup - \def\{\the\toks@{\bbl@ens@fontenc}}}} -\def\bbl@ensure#1#2#3{% 1: include 2: exclude 3: fontenc - \def\bbl@tempb##1{% elt for (excluding) \bbl@captionslist list - \ifx##1\@undefined % 3.32 - Don't assume the macro exists - \edef##1{\noexpand\bbl@nocaption - {\bbl@stripslash##1}{\languagename\bbl@stripslash##1}}% - \fi - \ifx##1\@empty\else - \in@{##1}{#2}% - \ifin@\else - \bbl@ifunset{bbl@ensure@\languagename}% - {\bbl@exp{% - \\\DeclareRobustCommand\[1]{% - \\\foreignlanguage{\languagename}% - {\ifx\relax#3\else - \\\fontencoding{#3}\\\selectfont - \fi - ########1}}}}% - {}% - \toks@\expandafter{##1}% - \edef##1{% - \bbl@csarg\noexpand{ensure@\languagename}% - {\the\toks@}}% - \fi - \expandafter\bbl@tempb - \fi}% - \expandafter\bbl@tempb\bbl@captionslist\today\@empty - \def\bbl@tempa##1{% elt for include list - \ifx##1\@empty\else - \bbl@csarg\in@{ensure@\languagename\expandafter}\expandafter{##1}% - \ifin@\else - \bbl@tempb##1\@empty - \fi - \expandafter\bbl@tempa - \fi}% - \bbl@tempa#1\@empty} -\def\bbl@captionslist{% - \prefacename\refname\abstractname\bibname\chaptername\appendixname - \contentsname\listfigurename\listtablename\indexname\figurename - \tablename\partname\enclname\ccname\headtoname\pagename\seename - \alsoname\proofname\glossaryname} +\def\bbl@prim@s{% + \prime\futurelet\@let@token\bbl@pr@m@s} +\def\bbl@if@primes#1#2{% + \ifx#1\@let@token + \expandafter\@firstoftwo + \else\ifx#2\@let@token + \bbl@afterelse\expandafter\@firstoftwo + \else + \bbl@afterfi\expandafter\@secondoftwo + \fi\fi} +\begingroup + \catcode`\^=7 \catcode`\*=\active \lccode`\*=`\^ + \catcode`\'=12 \catcode`\"=\active \lccode`\"=`\' + \lowercase{% + \gdef\bbl@pr@m@s{% + \bbl@if@primes"'% + \pr@@@s + {\bbl@if@primes*^\pr@@@t\egroup}}} +\endgroup % \end{macrocode} % -% \end{macro} +% \end{macro} +% \end{macro} % -% \subsection{Setting up language files} +% Usually the |~| is active and expands to \verb*=\penalty\@M\ =. +% When it is written to the \file{.aux} file it is written +% expanded. To prevent that and to be able to use the character |~| +% as a start character for a shorthand, it is redefined here as a +% one character shorthand on system level. The system declaration +% is in most cases redundant (when |~| is still a non-break space), +% and in some cases is inconvenient (if |~| has been redefined); +% however, for backward compatibility it is maintained (some +% existing documents may rely on the \babel{} value). % -% \begin{macro}{\LdfInit} +% \begin{macrocode} +\initiate@active@char{~} +\declare@shorthand{system}{~}{\leavevmode\nobreak\ } +\bbl@activate{~} +% \end{macrocode} % -% |\LdfInit| macro takes two arguments. The first -% argument is the name of the language that will be defined in the -% language definition file; the second argument is either a control -% sequence or a string from which a control sequence should be -% constructed. The existence of the control sequence indicates that -% the file has been processed before. +% \begin{macro}{\OT1dqpos} +% \begin{macro}{\T1dqpos} +% The position of the double quote character is different for the +% OT1 and T1 encodings. It will later be selected using the +% |\f@encoding| macro. Therefore we define two macros here to store +% the position of the character in these encodings. % -% At the start of processing a language definition file we always -% check the category code of the at-sign. We make sure that it is -% a `letter' during the processing of the file. We also save its -% name as the last called option, even if not loaded. +% \begin{macrocode} +\expandafter\def\csname OT1dqpos\endcsname{127} +\expandafter\def\csname T1dqpos\endcsname{4} +% \end{macrocode} % -% Another character that needs to have the correct category code -% during processing of language definition files is the equals sign, -% `=', because it is sometimes used in constructions with the -% |\let| primitive. Therefore we store its current catcode and -% restore it later on. -% -% Now we check whether we should perhaps stop the processing of -% this file. To do this we first need to check whether the second -% argument that is passed to |\LdfInit| is a control sequence. We -% do that by looking at the first token after passing |#2| through -% |string|. When it is equal to |\@backslashchar| we are dealing -% with a control sequence which we can compare with |\@undefined|. -% -% If so, we call |\ldf@quit| to set the main language, restore the -% category code of the @-sign and call |\endinput| -% -% When |#2| was \emph{not} a control sequence we construct one and -% compare it with |\relax|. -% -% Finally we check |\originalTeX|. +% When the macro |\f@encoding| is undefined (as it is in plain +% \TeX) we define it here to expand to \texttt{OT1} % % \begin{macrocode} -\bbl@trace{Macros for setting language files up} -\def\bbl@ldfinit{% - \let\bbl@screset\@empty - \let\BabelStrings\bbl@opt@string - \let\BabelOptions\@empty - \let\BabelLanguages\relax - \ifx\originalTeX\@undefined - \let\originalTeX\@empty - \else - \originalTeX - \fi} -\def\LdfInit#1#2{% - \chardef\atcatcode=\catcode`\@ - \catcode`\@=11\relax - \chardef\eqcatcode=\catcode`\= - \catcode`\==12\relax - \expandafter\if\expandafter\@backslashchar - \expandafter\@car\string#2\@nil - \ifx#2\@undefined\else - \ldf@quit{#1}% - \fi - \else - \expandafter\ifx\csname#2\endcsname\relax\else - \ldf@quit{#1}% - \fi - \fi - \bbl@ldfinit} +\ifx\f@encoding\@undefined + \def\f@encoding{OT1} +\fi % \end{macrocode} % % \end{macro} +% \end{macro} % -% \begin{macro}{\ldf@quit} -% This macro interrupts the processing of a language definition file. +% \subsection{Language attributes} % -% \begin{macrocode} -\def\ldf@quit#1{% - \expandafter\main@language\expandafter{#1}% - \catcode`\@=\atcatcode \let\atcatcode\relax - \catcode`\==\eqcatcode \let\eqcatcode\relax - \endinput} -% \end{macrocode} +% Language attributes provide a means to give the user control over +% which features of the language definition files he wants to +% enable. +% \begin{macro}{\languageattribute} % -% \end{macro} +% The macro |\languageattribute| checks whether its arguments are +% valid and then activates the selected language attribute. +% First check whether the language is known, and then process each +% attribute in the list. % -% \begin{macro}{\ldf@finish} -% This macro takes one argument. It is the name of the language -% that was defined in the language definition file. +% \begin{macrocode} +\bbl@trace{Language attributes} +\newcommand\languageattribute[2]{% + \def\bbl@tempc{#1}% + \bbl@fixname\bbl@tempc + \bbl@iflanguage\bbl@tempc{% + \bbl@vforeach{#2}{% +% \end{macrocode} % -% We load the local configuration file if one is present, we set -% the main language (taking into account that the argument might be -% a control sequence that needs to be expanded) and reset the -% category code of the @-sign. +% We want to make sure that each attribute is selected only once; +% therefore we store the already selected attributes in +% |\bbl@known@attribs|. When that control sequence is not yet +% defined this attribute is certainly not selected before. % % \begin{macrocode} -\def\bbl@afterldf#1{% TODO. Merge into the next macro? Unused elsewhere - \bbl@afterlang - \let\bbl@afterlang\relax - \let\BabelModifiers\relax - \let\bbl@screset\relax}% -\def\ldf@finish#1{% - \loadlocalcfg{#1}% - \bbl@afterldf{#1}% - \expandafter\main@language\expandafter{#1}% - \catcode`\@=\atcatcode \let\atcatcode\relax - \catcode`\==\eqcatcode \let\eqcatcode\relax} + \ifx\bbl@known@attribs\@undefined + \in@false + \else + \bbl@xin@{,\bbl@tempc-##1,}{,\bbl@known@attribs,}% + \fi + \ifin@ + \bbl@warning{% + You have more than once selected the attribute '##1'\\% + for language #1. Reported}% + \else % \end{macrocode} % -% \end{macro} -% -% After the preamble of the document the commands |\LdfInit|, -% |\ldf@quit| and |\ldf@finish| are no longer needed. Therefore -% they are turned into warning messages in \LaTeX. +% When we end up here the attribute is not selected before. So, we +% add it to the list of selected attributes and execute the +% associated \TeX-code. % % \begin{macrocode} -\@onlypreamble\LdfInit -\@onlypreamble\ldf@quit -\@onlypreamble\ldf@finish + \bbl@exp{% + \\\bbl@add@list\\\bbl@known@attribs{\bbl@tempc-##1}}% + \edef\bbl@tempa{\bbl@tempc-##1}% + \expandafter\bbl@ifknown@ttrib\expandafter{\bbl@tempa}\bbl@attributes% + {\csname\bbl@tempc @attr@##1\endcsname}% + {\@attrerr{\bbl@tempc}{##1}}% + \fi}}} +\@onlypreamble\languageattribute % \end{macrocode} % -% \begin{macro}{\main@language} -% \begin{macro}{\bbl@main@language} -% This command should be used in the various language definition -% files. It stores its argument in |\bbl@main@language|; to be used -% to switch to the correct language at the beginning of the -% document. +% The error text to be issued when an unknown attribute is +% selected. % % \begin{macrocode} -\def\main@language#1{% - \def\bbl@main@language{#1}% - \let\languagename\bbl@main@language % TODO. Set localename - \bbl@id@assign - \bbl@patterns{\languagename}} +\newcommand*{\@attrerr}[2]{% + \bbl@error + {The attribute #2 is unknown for language #1.}% + {Your command will be ignored, type to proceed}} % \end{macrocode} % -% We also have to make sure that some code gets executed at the -% beginning of the document, either when the |aux| file is read or, -% if it does not exist, when the |\AtBeginDocument| is executed. -% Languages do not set |\pagedir|, so we set here for the whole -% document to the main |\bodydir|. +% \end{macro} +% +% \begin{macro}{\bbl@declare@ttribute} +% This command adds the new language/attribute combination to the +% list of known attributes. +% +% Then it defines a control sequence to be executed when the +% attribute is used in a document. The result of this should be +% that the macro |\extras...| for the current language is extended, +% otherwise the attribute will not work as its code is removed from +% memory at |\begin{document}|. % % \begin{macrocode} -\def\bbl@beforestart{% - \def\@nolanerr##1{% - \bbl@warning{Undefined language '##1' in aux.\\Reported}}% - \bbl@usehooks{beforestart}{}% - \global\let\bbl@beforestart\relax} -\AtBeginDocument{% - {\@nameuse{bbl@beforestart}}% Group! - \if@filesw - \providecommand\babel@aux[2]{}% - \immediate\write\@mainaux{% - \string\providecommand\string\babel@aux[2]{}}% - \immediate\write\@mainaux{\string\@nameuse{bbl@beforestart}}% - \fi - \expandafter\selectlanguage\expandafter{\bbl@main@language}% - \ifbbl@single % must go after the line above. - \renewcommand\selectlanguage[1]{}% - \renewcommand\foreignlanguage[2]{#2}% - \global\let\babel@aux\@gobbletwo % Also as flag +\def\bbl@declare@ttribute#1#2#3{% + \bbl@xin@{,#2,}{,\BabelModifiers,}% + \ifin@ + \AfterBabelLanguage{#1}{\languageattribute{#1}{#2}}% \fi - \ifcase\bbl@engine\or\pagedir\bodydir\fi} % TODO - a better place + \bbl@add@list\bbl@attributes{#1-#2}% + \expandafter\def\csname#1@attr@#2\endcsname{#3}} % \end{macrocode} % % \end{macro} -% \end{macro} % -% A bit of optimization. Select in heads/foots the language only if -% necessary. +% \begin{macro}{\bbl@ifattributeset} +% This internal macro has 4 arguments. It can be used to interpret +% \TeX\ code based on whether a certain attribute was set. This +% command should appear inside the argument to |\AtBeginDocument| +% because the attributes are set in the document preamble, +% \emph{after} \babel\ is loaded. +% +% The first argument is the language, the second argument the +% attribute being checked, and the third and fourth arguments are +% the true and false clauses. % % \begin{macrocode} -\def\select@language@x#1{% - \ifcase\bbl@select@type - \bbl@ifsamestring\languagename{#1}{}{\select@language{#1}}% +\def\bbl@ifattributeset#1#2#3#4{% + \ifx\bbl@known@attribs\@undefined + \in@false \else - \select@language{#1}% + \bbl@xin@{,#1-#2,}{,\bbl@known@attribs,}% + \fi + \ifin@ + \bbl@afterelse#3% + \else + \bbl@afterfi#4% \fi} % \end{macrocode} % -% \subsection{Shorthands} +% \end{macro} % -% \begin{macro}{\bbl@add@special} -% The macro |\bbl@add@special| is used to add a new character (or -% single character control sequence) to the macro |\dospecials| -% (and |\@sanitize| if \LaTeX\ is used). It is used only at one -% place, namely when |\initiate@active@char| is called (which is -% ignored if the char has been made active before). Because -% |\@sanitize| can be undefined, we put the definition inside a -% conditional. +% \begin{macro}{\bbl@ifknown@ttrib} +% An internal macro to check whether a given language/attribute is +% known. The macro takes 4 arguments, the language/attribute, the +% attribute list, the \TeX-code to be executed when the attribute +% is known and the \TeX-code to be executed otherwise. % -% Items are added to the lists without checking its existence or -% the original catcode. It does not hurt, but should be fixed. It's -% already done with |\nfss@catcodes|, added in 3.10. +% We first assume the attribute is unknown. Then we loop over the +% list of known attributes, trying to find a match. % % \begin{macrocode} -\bbl@trace{Shorhands} -\def\bbl@add@special#1{% 1:a macro like \", \?, etc. - \bbl@add\dospecials{\do#1}% test @sanitize = \relax, for back. compat. - \bbl@ifunset{@sanitize}{}{\bbl@add\@sanitize{\@makeother#1}}% - \ifx\nfss@catcodes\@undefined\else % TODO - same for above - \begingroup - \catcode`#1\active - \nfss@catcodes - \ifnum\catcode`#1=\active - \endgroup - \bbl@add\nfss@catcodes{\@makeother#1}% - \else - \endgroup - \fi - \fi} +\def\bbl@ifknown@ttrib#1#2{% + \let\bbl@tempa\@secondoftwo + \bbl@loopx\bbl@tempb{#2}{% + \expandafter\in@\expandafter{\expandafter,\bbl@tempb,}{,#1,}% + \ifin@ + \let\bbl@tempa\@firstoftwo + \else + \fi}% + \bbl@tempa} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@remove@special} -% -% The companion of the former macro is |\bbl@remove@special|. It -% removes a character from the set macros |\dospecials| and -% |\@sanitize|, but it is not used at all in the \babel{} core. +% \begin{macro}{\bbl@clear@ttribs} +% This macro removes all the attribute code from \LaTeX's memory at +% |\begin{document}| time (if any is present). % % \begin{macrocode} -\def\bbl@remove@special#1{% - \begingroup - \def\x##1##2{\ifnum`#1=`##2\noexpand\@empty - \else\noexpand##1\noexpand##2\fi}% - \def\do{\x\do}% - \def\@makeother{\x\@makeother}% - \edef\x{\endgroup - \def\noexpand\dospecials{\dospecials}% - \expandafter\ifx\csname @sanitize\endcsname\relax\else - \def\noexpand\@sanitize{\@sanitize}% - \fi}% - \x} +\def\bbl@clear@ttribs{% + \ifx\bbl@attributes\@undefined\else + \bbl@loopx\bbl@tempa{\bbl@attributes}{% + \expandafter\bbl@clear@ttrib\bbl@tempa. + }% + \let\bbl@attributes\@undefined + \fi} +\def\bbl@clear@ttrib#1-#2.{% + \expandafter\let\csname#1@attr@#2\endcsname\@undefined} +\AtBeginDocument{\bbl@clear@ttribs} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\initiate@active@char} -% A language definition file can call this macro to make a -% character active. This macro takes one argument, the character -% that is to be made active. When the character was already active -% this macro does nothing. Otherwise, this macro defines the -% control sequence |\normal@char|\m{char} to expand to the -% character in its `normal state' and it defines the active -% character to expand to |\normal@char|\m{char} by default -% (\m{char} being the character to be made active). Later its -% definition can be changed to expand to |\active@char|\m{char} -% by calling |\bbl@activate{|\m{char}|}|. +% \subsection{Support for saving macro definitions} % -% For example, to make the double quote character active one could -% have |\initiate@active@char{"}| in a language definition file. -% This defines |"| as |\active@prefix "\active@char"| (where the -% first |"| is the character with its original catcode, when the -% shorthand is created, and |\active@char"| is a single token). In -% protected contexts, it expands to |\protect "| or |\noexpand "| -% (ie, with the original |"|); otherwise |\active@char"| is -% executed. This macro in turn expands to |\normal@char"| in -% ``safe'' contexts (eg, |\label|), but |\user@active"| in normal -% ``unsafe'' ones. The latter search a definition in the user, -% language and system levels, in this order, but if none is found, -% |\normal@char"| is used. However, a deactivated shorthand (with -% |\bbl@deactivate| is defined as |\active@prefix "\normal@char"|. +% To save the meaning of control sequences using |\babel@save|, we +% use temporary control sequences. To save hash table entries for +% these control sequences, we don't use the name of the control +% sequence to be saved to construct the temporary name. Instead we +% simply use the value of a counter, which is reset to zero each time +% we begin to save new values. This works well because we release +% the saved meanings before we begin to save a new set of control +% sequence meanings (see |\selectlanguage| and |\originalTeX|). Note +% undefined macros are not undefined any more when saved -- they are +% |\relax|'ed. % -% The following macro is used to define shorthands in the three -% levels. It takes 4 arguments: the (string'ed) character, -% |\@group|, |@active| and |@active| -% (except in |system|). +% \begin{macro}{\babel@savecnt} +% \begin{macro}{\babel@beginsave} +% The initialization of a new save cycle: reset the counter to +% zero. % % \begin{macrocode} -\def\bbl@active@def#1#2#3#4{% - \@namedef{#3#1}{% - \expandafter\ifx\csname#2@sh@#1@\endcsname\relax - \bbl@afterelse\bbl@sh@select#2#1{#3@arg#1}{#4#1}% - \else - \bbl@afterfi\csname#2@sh@#1@\endcsname - \fi}% +\bbl@trace{Macros for saving definitions} +\def\babel@beginsave{\babel@savecnt\z@} % \end{macrocode} % -% When there is also no current-level shorthand with an argument we -% will check whether there is a next-level defined shorthand for -% this active character. +% Before it's forgotten, allocate the counter and initialize all. % % \begin{macrocode} - \long\@namedef{#3@arg#1}##1{% - \expandafter\ifx\csname#2@sh@#1@\string##1@\endcsname\relax - \bbl@afterelse\csname#4#1\endcsname##1% - \else - \bbl@afterfi\csname#2@sh@#1@\string##1@\endcsname - \fi}}% +\newcount\babel@savecnt +\babel@beginsave % \end{macrocode} % -% |\initiate@active@char| calls |\@initiate@active@char| with 3 -% arguments. All of them are the same character with different -% catcodes: active, other (|\string|'ed) and the original one. -% This trick simplifies the code a lot. +% \end{macro} +% \end{macro} % -% \begin{macrocode} -\def\initiate@active@char#1{% - \bbl@ifunset{active@char\string#1}% - {\bbl@withactive - {\expandafter\@initiate@active@char\expandafter}#1\string#1#1}% - {}} -% \end{macrocode} +% \begin{macro}{\babel@save} +% \begin{macro}{\babel@savevariable} % -% The very first thing to do is saving the original catcode and the -% original definition, even if not active, which is possible -% (undefined characters require a special treatement to avoid -% making them |\relax| and preserving some degree of protection). +% The macro |\babel@save|\meta{csname} saves the current meaning of the +% control sequence \meta{csname} to +% |\originalTeX|\footnote{\cs{originalTeX} has to be expandable, +% i.\,e.\ you shouldn't let it to \cs{relax}.}. To do this, we let the +% current meaning to a temporary control sequence, the restore commands +% are appended to |\originalTeX| and the counter is incremented. The +% macro |\babel@savevariable|\meta{variable} saves the value of the +% variable. \meta{variable} can be anything allowed after the |\the| +% primitive. % % \begin{macrocode} -\def\@initiate@active@char#1#2#3{% - \bbl@csarg\edef{oricat@#2}{\catcode`#2=\the\catcode`#2\relax}% - \ifx#1\@undefined - \bbl@csarg\def{oridef@#2}{\def#1{\active@prefix#1\@undefined}}% - \else - \bbl@csarg\let{oridef@@#2}#1% - \bbl@csarg\edef{oridef@#2}{% - \let\noexpand#1% - \expandafter\noexpand\csname bbl@oridef@@#2\endcsname}% - \fi +\def\babel@save#1{% + \expandafter\let\csname babel@\number\babel@savecnt\endcsname#1\relax + \toks@\expandafter{\originalTeX\let#1=}% + \bbl@exp{% + \def\\\originalTeX{\the\toks@\\relax}}% + \advance\babel@savecnt\@ne} +\def\babel@savevariable#1{% + \toks@\expandafter{\originalTeX #1=}% + \bbl@exp{\def\\\originalTeX{\the\toks@\the#1\relax}}} % \end{macrocode} % -% If the character is already active we provide the default -% expansion under this shorthand mechanism. Otherwise we write a -% message in the transcript file, and define |\normal@char|\m{char} -% to expand to the character in its default state. If the character -% is mathematically active when \babel{} is loaded (for example -% |'|) the normal expansion is somewhat different to avoid an -% infinite loop (but it does not prevent the loop if the mathcode -% is set to |"8000| \textit{a posteriori}). +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bbl@frenchspacing} +% \begin{macro}{\bbl@nonfrenchspacing} +% Some languages need to have |\frenchspacing| in effect. Others +% don't want that. The command |\bbl@frenchspacing| switches it on +% when it isn't already in effect and |\bbl@nonfrenchspacing| +% switches it off if necessary. A more refined way to switch the +% catcodes is done with |ini| files. Here an auxiliary macro is +% defined, but the main part is in |\babelprovide|. This new method +% should be ideally the default one. % % \begin{macrocode} - \ifx#1#3\relax - \expandafter\let\csname normal@char#2\endcsname#3% +\def\bbl@frenchspacing{% + \ifnum\the\sfcode`\.=\@m + \let\bbl@nonfrenchspacing\relax \else - \bbl@info{Making #2 an active character}% - \ifnum\mathcode`#2=\ifodd\bbl@engine"1000000 \else"8000 \fi - \@namedef{normal@char#2}{% - \textormath{#3}{\csname bbl@oridef@@#2\endcsname}}% - \else - \@namedef{normal@char#2}{#3}% - \fi + \frenchspacing + \let\bbl@nonfrenchspacing\nonfrenchspacing + \fi} +\let\bbl@nonfrenchspacing\nonfrenchspacing +\let\bbl@elt\relax +\edef\bbl@fs@chars{% + \bbl@elt{\string.}\@m{3000}\bbl@elt{\string?}\@m{3000}% + \bbl@elt{\string!}\@m{3000}\bbl@elt{\string:}\@m{2000}% + \bbl@elt{\string;}\@m{1500}\bbl@elt{\string,}\@m{1250}} +\def\bbl@pre@fs{% + \def\bbl@elt##1##2##3{\sfcode`##1=\the\sfcode`##1\relax}% + \edef\bbl@save@sfcodes{\bbl@fs@chars}}% +\def\bbl@post@fs{% + \bbl@save@sfcodes + \edef\bbl@tempa{\bbl@cl{frspc}}% + \edef\bbl@tempa{\expandafter\@car\bbl@tempa\@nil}% + \if u\bbl@tempa % do nothing + \else\if n\bbl@tempa % non french + \def\bbl@elt##1##2##3{% + \ifnum\sfcode`##1=##2\relax + \babel@savevariable{\sfcode`##1}% + \sfcode`##1=##3\relax + \fi}% + \bbl@fs@chars + \else\if y\bbl@tempa % french + \def\bbl@elt##1##2##3{% + \ifnum\sfcode`##1=##3\relax + \babel@savevariable{\sfcode`##1}% + \sfcode`##1=##2\relax + \fi}% + \bbl@fs@chars + \fi\fi\fi} % \end{macrocode} % -% To prevent problems with the loading of other packages after -% \babel\ we reset the catcode of the character to the original one -% at the end of the package and of each language file (except with -% \textsf{KeepShorthandsActive}). It is re-activate again at -% |\begin{document}|. We also need to make sure that the -% shorthands are active during the processing of the \file{.aux} -% file. Otherwise some citations may give unexpected results in -% the printout when a shorthand was used in the optional argument -% of |\bibitem| for example. Then we make it active (not strictly -% necessary, but done for backward compatibility). +% \end{macro} +% \end{macro} % -% \begin{macrocode} - \bbl@restoreactive{#2}% - \AtBeginDocument{% - \catcode`#2\active - \if@filesw - \immediate\write\@mainaux{\catcode`\string#2\active}% - \fi}% - \expandafter\bbl@add@special\csname#2\endcsname - \catcode`#2\active - \fi +% \subsection{Short tags} +% +% \begin{macro}{\babeltags} +% This macro is straightforward. After zapping spaces, we +% loop over the list and define the macros |\text|\m{tag} and +% |\|\m{tag}. Definitions are first expanded so that they don't +% contain |\csname| but the actual macro. +% +% \begin{macrocode} +\bbl@trace{Short tags} +\def\babeltags#1{% + \edef\bbl@tempa{\zap@space#1 \@empty}% + \def\bbl@tempb##1=##2\@@{% + \edef\bbl@tempc{% + \noexpand\newcommand + \expandafter\noexpand\csname ##1\endcsname{% + \noexpand\protect + \expandafter\noexpand\csname otherlanguage*\endcsname{##2}} + \noexpand\newcommand + \expandafter\noexpand\csname text##1\endcsname{% + \noexpand\foreignlanguage{##2}}} + \bbl@tempc}% + \bbl@for\bbl@tempa\bbl@tempa{% + \expandafter\bbl@tempb\bbl@tempa\@@}} % \end{macrocode} % -% Now we have set |\normal@char|\m{char}, we must define -% |\active@char|\m{char}, to be executed when the character is -% activated. We define the first level expansion of -% |\active@char|\m{char} to check the status of the |@safe@actives| -% flag. If it is set to true we expand to the `normal' version of -% this character, otherwise we call |\user@active|\m{char} to start -% the search of a definition in the user, language and system -% levels (or eventually |normal@char|\m{char}). +% \end{macro} % -% \begin{macrocode} - \let\bbl@tempa\@firstoftwo - \if\string^#2% - \def\bbl@tempa{\noexpand\textormath}% - \else - \ifx\bbl@mathnormal\@undefined\else - \let\bbl@tempa\bbl@mathnormal - \fi - \fi - \expandafter\edef\csname active@char#2\endcsname{% - \bbl@tempa - {\noexpand\if@safe@actives - \noexpand\expandafter - \expandafter\noexpand\csname normal@char#2\endcsname - \noexpand\else - \noexpand\expandafter - \expandafter\noexpand\csname bbl@doactive#2\endcsname - \noexpand\fi}% - {\expandafter\noexpand\csname normal@char#2\endcsname}}% - \bbl@csarg\edef{doactive#2}{% - \expandafter\noexpand\csname user@active#2\endcsname}% -% \end{macrocode} +% \subsection{Hyphens} % -% We now define the default values which the shorthand is set to -% when activated or deactivated. It is set to the deactivated form -% (globally), so that the character expands to -% \begin{center} -% |\active@prefix| \m{char} |\normal@char|\m{char} -% \end{center} -% (where |\active@char|\m{char} is \emph{one} control sequence!). +% \begin{macro}{\babelhyphenation} +% +% This macro saves hyphenation exceptions. Two macros are used to +% store them: |\bbl@hyphenation@| for the global ones and +% |\bbl@hyphenation| for language ones. See |\bbl@patterns| +% above for further details. We make sure there is a space between +% words when multiple commands are used. % % \begin{macrocode} - \bbl@csarg\edef{active@#2}{% - \noexpand\active@prefix\noexpand#1% - \expandafter\noexpand\csname active@char#2\endcsname}% - \bbl@csarg\edef{normal@#2}{% - \noexpand\active@prefix\noexpand#1% - \expandafter\noexpand\csname normal@char#2\endcsname}% - \expandafter\let\expandafter#1\csname bbl@normal@#2\endcsname +\bbl@trace{Hyphens} +\@onlypreamble\babelhyphenation +\AtEndOfPackage{% + \newcommand\babelhyphenation[2][\@empty]{% + \ifx\bbl@hyphenation@\relax + \let\bbl@hyphenation@\@empty + \fi + \ifx\bbl@hyphlist\@empty\else + \bbl@warning{% + You must not intermingle \string\selectlanguage\space and\\% + \string\babelhyphenation\space or some exceptions will not\\% + be taken into account. Reported}% + \fi + \ifx\@empty#1% + \protected@edef\bbl@hyphenation@{\bbl@hyphenation@\space#2}% + \else + \bbl@vforeach{#1}{% + \def\bbl@tempa{##1}% + \bbl@fixname\bbl@tempa + \bbl@iflanguage\bbl@tempa{% + \bbl@csarg\protected@edef{hyphenation@\bbl@tempa}{% + \bbl@ifunset{bbl@hyphenation@\bbl@tempa}% + {}% + {\csname bbl@hyphenation@\bbl@tempa\endcsname\space}% + #2}}}% + \fi}} % \end{macrocode} % -% The next level of the code checks whether a user has defined a -% shorthand for himself with this character. First we check for a -% single character shorthand. If that doesn't exist we check for a -% shorthand with an argument. +% \end{macro} % -% \begin{macrocode} - \bbl@active@def#2\user@group{user@active}{language@active}% - \bbl@active@def#2\language@group{language@active}{system@active}% - \bbl@active@def#2\system@group{system@active}{normal@char}% -% \end{macrocode} +% \begin{macro}{\bbl@allowhyphens} % -% In order to do the right thing when a shorthand with an argument -% is used by itself at the end of the line we provide a definition -% for the case of an empty argument. For that case we let the -% shorthand character expand to its non-active self. Also, When a -% shorthand combination such as |''| ends up in a heading \TeX\ -% would see |\protect'\protect'|. To prevent this from happening a -% couple of shorthand needs to be defined at user level. +% This macro makes hyphenation possible. Basically its definition +% is nothing more than |\nobreak| |\hskip| \texttt{0pt plus +% 0pt}\footnote{\TeX\ begins and ends a word for hyphenation at a +% glue node. The penalty prevents a linebreak at this glue node.}. % % \begin{macrocode} - \expandafter\edef\csname\user@group @sh@#2@@\endcsname - {\expandafter\noexpand\csname normal@char#2\endcsname}% - \expandafter\edef\csname\user@group @sh@#2@\string\protect@\endcsname - {\expandafter\noexpand\csname user@active#2\endcsname}% +\def\bbl@allowhyphens{\ifvmode\else\nobreak\hskip\z@skip\fi} +\def\bbl@t@one{T1} +\def\allowhyphens{\ifx\cf@encoding\bbl@t@one\else\bbl@allowhyphens\fi} % \end{macrocode} % -% Finally, a couple of special cases are taken care of. (1) If we -% are making the right quote (|'|) active we need to change |\pr@m@s| as -% well. Also, make sure that a single |'| in math mode `does the -% right thing'. (2) If we are using the caret (|^|) as a shorthand -% character special care should be taken to make sure math still -% works. Therefore an extra level of expansion is introduced with a -% check for math mode on the upper level. +% \end{macro} % -% \begin{macrocode} - \if\string'#2% - \let\prim@s\bbl@prim@s - \let\active@math@prime#1% - \fi - \bbl@usehooks{initiateactive}{{#1}{#2}{#3}}} -% \end{macrocode} +% \begin{macro}{\babelhyphen} % -% The following package options control the behavior of shorthands -% in math mode. +% Macros to insert common hyphens. Note the space before |@| in +% |\babelhyphen|. Instead of protecting it with +% |\DeclareRobustCommand|, which could insert a |\relax|, we use +% the same procedure as shorthands, with |\active@prefix|. % % \begin{macrocode} -%<<*More package options>> -\DeclareOption{math=active}{} -\DeclareOption{math=normal}{\def\bbl@mathnormal{\noexpand\textormath}} -%<> +\newcommand\babelnullhyphen{\char\hyphenchar\font} +\def\babelhyphen{\active@prefix\babelhyphen\bbl@hyphen} +\def\bbl@hyphen{% + \@ifstar{\bbl@hyphen@i @}{\bbl@hyphen@i\@empty}} +\def\bbl@hyphen@i#1#2{% + \bbl@ifunset{bbl@hy@#1#2\@empty}% + {\csname bbl@#1usehyphen\endcsname{\discretionary{#2}{}{#2}}}% + {\csname bbl@hy@#1#2\@empty\endcsname}} % \end{macrocode} % -% Initiating a shorthand makes active the char. That is not -% strictly necessary but it is still done for backward -% compatibility. So we need to restore the original catcode at the -% end of package \textit{and} and the end of the |ldf|. +% The following two commands are used to wrap the ``hyphen'' and +% set the behavior of the rest of the word -- the version with a +% single |@| is used when further hyphenation is allowed, while +% that with |@@| if no more hyphens are allowed. In both cases, if +% the hyphen is preceded by a positive space, breaking after the +% hyphen is disallowed. +% +% There should not be a discretionary after a hyphen at the +% beginning of a word, so it is prevented if preceded by a +% skip. Unfortunately, this does handle cases like ``(-suffix)''. +% |\nobreak| is always preceded by |\leavevmode|, in case the +% shorthand starts a paragraph. % % \begin{macrocode} -\@ifpackagewith{babel}{KeepShorthandsActive}% - {\let\bbl@restoreactive\@gobble}% - {\def\bbl@restoreactive#1{% - \bbl@exp{% - \\\AfterBabelLanguage\\\CurrentOption - {\catcode`#1=\the\catcode`#1\relax}% - \\\AtEndOfPackage - {\catcode`#1=\the\catcode`#1\relax}}}% - \AtEndOfPackage{\let\bbl@restoreactive\@gobble}} +\def\bbl@usehyphen#1{% + \leavevmode + \ifdim\lastskip>\z@\mbox{#1}\else\nobreak#1\fi + \nobreak\hskip\z@skip} +\def\bbl@@usehyphen#1{% + \leavevmode\ifdim\lastskip>\z@\mbox{#1}\else#1\fi} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\bbl@sh@select} -% This command helps the shorthand supporting macros to select how -% to proceed. Note that this macro needs to be expandable as do all -% the shorthand macros in order for them to work in expansion-only -% environments such as the argument of |\hyphenation|. -% -% This macro expects the name of a group of shorthands in its first -% argument and a shorthand character in its second argument. It -% will expand to either |\bbl@firstcs| or |\bbl@scndcs|. Hence two -% more arguments need to follow it. +% The following macro inserts the hyphen char. % % \begin{macrocode} -\def\bbl@sh@select#1#2{% - \expandafter\ifx\csname#1@sh@#2@sel\endcsname\relax - \bbl@afterelse\bbl@scndcs +\def\bbl@hyphenchar{% + \ifnum\hyphenchar\font=\m@ne + \babelnullhyphen \else - \bbl@afterfi\csname#1@sh@#2@sel\endcsname + \char\hyphenchar\font \fi} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\active@prefix} -% The command |\active@prefix| which is used in the expansion of -% active characters has a function similar to |\OT1-cmd| in that it -% |\protect|s the active character whenever |\protect| is -% \emph{not} |\@typeset@protect|. The |\@gobble| is needed to remove -% a token such as |\activechar:| (when the double colon was the -% active character to be dealt with). There are two definitions, -% depending of |\ifincsname| is available. If there is, the -% expansion will be more robust. +% Finally, we define the hyphen ``types''. Their names will not +% change, so you may use them in |ldf|'s. After a space, the +% |\mbox| in |\bbl@hy@nobreak| is redundant. % % \begin{macrocode} -\begingroup -\bbl@ifunset{ifincsname}% TODO. Ugly. Correct? - {\gdef\active@prefix#1{% - \ifx\protect\@typeset@protect - \else - \ifx\protect\@unexpandable@protect - \noexpand#1% - \else - \protect#1% - \fi - \expandafter\@gobble - \fi}} - {\gdef\active@prefix#1{% - \ifincsname - \string#1% - \expandafter\@gobble - \else - \ifx\protect\@typeset@protect - \else - \ifx\protect\@unexpandable@protect - \noexpand#1% - \else - \protect#1% - \fi - \expandafter\expandafter\expandafter\@gobble - \fi - \fi}} -\endgroup +\def\bbl@hy@soft{\bbl@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}} +\def\bbl@hy@@soft{\bbl@@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}} +\def\bbl@hy@hard{\bbl@usehyphen\bbl@hyphenchar} +\def\bbl@hy@@hard{\bbl@@usehyphen\bbl@hyphenchar} +\def\bbl@hy@nobreak{\bbl@usehyphen{\mbox{\bbl@hyphenchar}}} +\def\bbl@hy@@nobreak{\mbox{\bbl@hyphenchar}} +\def\bbl@hy@repeat{% + \bbl@usehyphen{% + \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}} +\def\bbl@hy@@repeat{% + \bbl@@usehyphen{% + \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}} +\def\bbl@hy@empty{\hskip\z@skip} +\def\bbl@hy@@empty{\discretionary{}{}{}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\if@safe@actives} -% In some circumstances it is necessary to be able to change the -% expansion of an active character on the fly. For this purpose the -% switch |@safe@actives| is available. The setting of this switch -% should be checked in the first level expansion of -% |\active@char|\m{char}. +% \begin{macro}{\bbl@disc} +% For some languages the macro |\bbl@disc| is used to ease the +% insertion of discretionaries for letters that behave `abnormally' +% at a breakpoint. % % \begin{macrocode} -\newif\if@safe@actives -\@safe@activesfalse +\def\bbl@disc#1#2{\nobreak\discretionary{#2-}{}{#1}\bbl@allowhyphens} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@restore@actives} -% When the output routine kicks in while the -% active characters were made ``safe'' this must be undone in -% the headers to prevent unexpected typeset results. For this -% situation we define a command to make them ``unsafe'' again. -% -% \begin{macrocode} -\def\bbl@restore@actives{\if@safe@actives\@safe@activesfalse\fi} -% \end{macrocode} +% \subsection{Multiencoding strings} % -% \end{macro} +% The aim following commands is to provide a commom interface for +% strings in several encodings. They also contains several hooks which +% can be used by \luatex{} and \xetex. The code is organized here with +% pseudo-guards, so we start with the basic commands. % -% \begin{macro}{\bbl@activate} -% \begin{macro}{\bbl@deactivate} +% \paragraph{Tools} % -% Both macros take one argument, like |\initiate@active@char|. The -% macro is used to change the definition of an active character to -% expand to |\active@char|\m{char} in the case of |\bbl@activate|, -% or |\normal@char|\m{char} in the case of |\bbl@deactivate|. +% But first, a couple of tools. The first one makes global a local +% variable. This is not the best solution, but it works. % % \begin{macrocode} -\chardef\bbl@activated\z@ -\def\bbl@activate#1{% - \chardef\bbl@activated\@ne - \bbl@withactive{\expandafter\let\expandafter}#1% - \csname bbl@active@\string#1\endcsname} -\def\bbl@deactivate#1{% - \chardef\bbl@activated\tw@ - \bbl@withactive{\expandafter\let\expandafter}#1% - \csname bbl@normal@\string#1\endcsname} +\bbl@trace{Multiencoding strings} +\def\bbl@toglobal#1{\global\let#1#1} +\def\bbl@recatcode#1{% TODO. Used only once? + \@tempcnta="7F + \def\bbl@tempa{% + \ifnum\@tempcnta>"FF\else + \catcode\@tempcnta=#1\relax + \advance\@tempcnta\@ne + \expandafter\bbl@tempa + \fi}% + \bbl@tempa} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\bbl@firstcs} -% \begin{macro}{\bbl@scndcs} -% -% These macros are used only as a trick when declaring shorthands. +% The second one. We need to patch |\@uclclist|, but it is done once +% and only if |\SetCase| is used or if strings are encoded. The code +% is far from satisfactory for several reasons, including the fact +% |\@uclclist| is not a list any more. Therefore a package option is +% added to ignore it. Instead of gobbling the macro +% getting the next two elements (usually |\reserved@a|), we pass it as +% argument to |\bbl@uclc|. The parser is restarted inside +% |\|\m{lang}|@bbl@uclc| because we do not know how many expansions +% are necessary (depends on whether strings are encoded). The last +% part is tricky -- when uppercasing, we have: +%\begin{verbatim} +% \let\bbl@tolower\@empty\bbl@toupper\@empty +%\end{verbatim} +% and starts over (and similarly when lowercasing). % % \begin{macrocode} -\def\bbl@firstcs#1#2{\csname#1\endcsname} -\def\bbl@scndcs#1#2{\csname#2\endcsname} +\@ifpackagewith{babel}{nocase}% + {\let\bbl@patchuclc\relax}% + {\def\bbl@patchuclc{% + \global\let\bbl@patchuclc\relax + \g@addto@macro\@uclclist{\reserved@b{\reserved@b\bbl@uclc}}% + \gdef\bbl@uclc##1{% + \let\bbl@encoded\bbl@encoded@uclc + \bbl@ifunset{\languagename @bbl@uclc}% and resumes it + {##1}% + {\let\bbl@tempa##1\relax % Used by LANG@bbl@uclc + \csname\languagename @bbl@uclc\endcsname}% + {\bbl@tolower\@empty}{\bbl@toupper\@empty}}% + \gdef\bbl@tolower{\csname\languagename @bbl@lc\endcsname}% + \gdef\bbl@toupper{\csname\languagename @bbl@uc\endcsname}}} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\declare@shorthand} -% The command |\declare@shorthand| is used to declare a shorthand -% on a certain level. It takes three arguments: -% \begin{enumerate} -% \item a name for the collection of shorthands, i.e. `system', or -% `dutch'; -% \item the character (sequence) that makes up the shorthand, -% i.e. |~| or |"a|; -% \item the code to be executed when the shorthand is encountered. -% \end{enumerate} -% -% The auxiliary macro |\babel@texpdf| improves the interoperativity with -% \textsf{hyperref} and takes 4 arguments: (1) The \TeX{} code in text -% mode, (2) the string for \textsf{hyperref}, (3) the \TeX{} code in -% math mode, and (4), which is currently ignored, but it's meant for a -% string in math mode, like a minus sign instead of an hyphen -% (currently \textsf{hyperref} doesn't discriminate the mode). This -% macro may be used in |ldf| files. - % \begin{macrocode} -\def\babel@texpdf#1#2#3#4{% - \ifx\texorpdfstring\@undefined - \textormath{#1}{#3}% - \else - \texorpdfstring{\textormath{#1}{#3}}{#2}% - % \texorpdfstring{\textormath{#1}{#3}}{\textormath{#2}{#4}}% - \fi} -% -\def\declare@shorthand#1#2{\@decl@short{#1}#2\@nil} -\def\@decl@short#1#2#3\@nil#4{% - \def\bbl@tempa{#3}% - \ifx\bbl@tempa\@empty - \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@scndcs - \bbl@ifunset{#1@sh@\string#2@}{}% - {\def\bbl@tempa{#4}% - \expandafter\ifx\csname#1@sh@\string#2@\endcsname\bbl@tempa - \else - \bbl@info - {Redefining #1 shorthand \string#2\\% - in language \CurrentOption}% - \fi}% - \@namedef{#1@sh@\string#2@}{#4}% - \else - \expandafter\let\csname #1@sh@\string#2@sel\endcsname\bbl@firstcs - \bbl@ifunset{#1@sh@\string#2@\string#3@}{}% - {\def\bbl@tempa{#4}% - \expandafter\ifx\csname#1@sh@\string#2@\string#3@\endcsname\bbl@tempa - \else - \bbl@info - {Redefining #1 shorthand \string#2\string#3\\% - in language \CurrentOption}% - \fi}% - \@namedef{#1@sh@\string#2@\string#3@}{#4}% - \fi} +%<<*More package options>> +\DeclareOption{nocase}{} +%<> % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\textormath} -% Some of the shorthands that will be declared by the language -% definition files have to be usable in both text and mathmode. To -% achieve this the helper macro |\textormath| is provided. +% The following package options control the behavior of |\SetString|. % % \begin{macrocode} -\def\textormath{% - \ifmmode - \expandafter\@secondoftwo - \else - \expandafter\@firstoftwo - \fi} +%<<*More package options>> +\let\bbl@opt@strings\@nnil % accept strings=value +\DeclareOption{strings}{\def\bbl@opt@strings{\BabelStringsDefault}} +\DeclareOption{strings=encoded}{\let\bbl@opt@strings\relax} +\def\BabelStringsDefault{generic} +%<> % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\user@group} -% \begin{macro}{\language@group} -% \begin{macro}{\system@group} -% The current concept of `shorthands' supports three levels or -% groups of shorthands. For each level the name of the level or -% group is stored in a macro. The default is to have a user group; -% use language group `english' and have a system group called -% `system'. +% \paragraph{Main command} This is the main command. With the first +% use it is redefined to omit the basic setup in subsequent blocks. +% We make sure strings contain actual letters in the range 128-255, +% not active characters. % % \begin{macrocode} -\def\user@group{user} -\def\language@group{english} % TODO. I don't like defaults -\def\system@group{system} +\@onlypreamble\StartBabelCommands +\def\StartBabelCommands{% + \begingroup + \bbl@recatcode{11}% + <@Macros local to BabelCommands@> + \def\bbl@provstring##1##2{% + \providecommand##1{##2}% + \bbl@toglobal##1}% + \global\let\bbl@scafter\@empty + \let\StartBabelCommands\bbl@startcmds + \ifx\BabelLanguages\relax + \let\BabelLanguages\CurrentOption + \fi + \begingroup + \let\bbl@screset\@nnil % local flag - disable 1st stopcommands + \StartBabelCommands} +\def\bbl@startcmds{% + \ifx\bbl@screset\@nnil\else + \bbl@usehooks{stopcommands}{}% + \fi + \endgroup + \begingroup + \@ifstar + {\ifx\bbl@opt@strings\@nnil + \let\bbl@opt@strings\BabelStringsDefault + \fi + \bbl@startcmds@i}% + \bbl@startcmds@i} +\def\bbl@startcmds@i#1#2{% + \edef\bbl@L{\zap@space#1 \@empty}% + \edef\bbl@G{\zap@space#2 \@empty}% + \bbl@startcmds@ii} +\let\bbl@startcommands\StartBabelCommands % \end{macrocode} % -% \end{macro} -% \end{macro} -% \end{macro} +% Parse the encoding info to get the label, input, and font parts. % -% \begin{macro}{\useshorthands} +% Select the behavior of |\SetString|. Thre are two main cases, +% depending of if there is an optional argument: without it and +% |strings=encoded|, strings are defined +% always; otherwise, they are set only if they are still undefined +% (ie, fallback values). With labelled blocks and +% |strings=encoded|, define the strings, but with another value, +% define strings only if the current label or font encoding is the +% value of |strings|; otherwise (ie, no |strings| or a block whose +% label is not in |strings=|) do nothing. % -% This is the user level macro. It initializes and activates the -% character for use as a shorthand character (ie, it's active in the -% preamble). Languages can deactivate shorthands, so a starred -% version is also provided which activates them always after the -% language has been switched. +% We presume the current block is not loaded, and therefore set +% (above) a couple of default values to gobble the arguments. Then, +% these macros are redefined if necessary according to several +% parameters. % % \begin{macrocode} -\def\useshorthands{% - \@ifstar\bbl@usesh@s{\bbl@usesh@x{}}} -\def\bbl@usesh@s#1{% - \bbl@usesh@x - {\AddBabelHook{babel-sh-\string#1}{afterextras}{\bbl@activate{#1}}}% - {#1}} -\def\bbl@usesh@x#1#2{% - \bbl@ifshorthand{#2}% - {\def\user@group{user}% - \initiate@active@char{#2}% - #1% - \bbl@activate{#2}}% - {\bbl@error - {I can't declare a shorthand turned off (\string#2)} - {Sorry, but you can't use shorthands which have been\\% - turned off in the package options}}} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\defineshorthand} -% -% Currently we only support two groups of user level shorthands, -% named internally |user| and |user@| (language-dependent -% user shorthands). By default, only the first one is taken into -% account, but if the former is also used (in the optional argument -% of |\defineshorthand|) a new level is inserted for it -% (|user@generic|, done by |\bbl@set@user@generic|); we make also -% sure |{}| and |\protect| are taken into account in this new top -% level. +\newcommand\bbl@startcmds@ii[1][\@empty]{% + \let\SetString\@gobbletwo + \let\bbl@stringdef\@gobbletwo + \let\AfterBabelCommands\@gobble + \ifx\@empty#1% + \def\bbl@sc@label{generic}% + \def\bbl@encstring##1##2{% + \ProvideTextCommandDefault##1{##2}% + \bbl@toglobal##1% + \expandafter\bbl@toglobal\csname\string?\string##1\endcsname}% + \let\bbl@sctest\in@true + \else + \let\bbl@sc@charset\space % <- zapped below + \let\bbl@sc@fontenc\space % <- " " + \def\bbl@tempa##1=##2\@nil{% + \bbl@csarg\edef{sc@\zap@space##1 \@empty}{##2 }}% + \bbl@vforeach{label=#1}{\bbl@tempa##1\@nil}% + \def\bbl@tempa##1 ##2{% space -> comma + ##1% + \ifx\@empty##2\else\ifx,##1,\else,\fi\bbl@afterfi\bbl@tempa##2\fi}% + \edef\bbl@sc@fontenc{\expandafter\bbl@tempa\bbl@sc@fontenc\@empty}% + \edef\bbl@sc@label{\expandafter\zap@space\bbl@sc@label\@empty}% + \edef\bbl@sc@charset{\expandafter\zap@space\bbl@sc@charset\@empty}% + \def\bbl@encstring##1##2{% + \bbl@foreach\bbl@sc@fontenc{% + \bbl@ifunset{T@####1}% + {}% + {\ProvideTextCommand##1{####1}{##2}% + \bbl@toglobal##1% + \expandafter + \bbl@toglobal\csname####1\string##1\endcsname}}}% + \def\bbl@sctest{% + \bbl@xin@{,\bbl@opt@strings,}{,\bbl@sc@label,\bbl@sc@fontenc,}}% + \fi + \ifx\bbl@opt@strings\@nnil % ie, no strings key -> defaults + \else\ifx\bbl@opt@strings\relax % ie, strings=encoded + \let\AfterBabelCommands\bbl@aftercmds + \let\SetString\bbl@setstring + \let\bbl@stringdef\bbl@encstring + \else % ie, strings=value + \bbl@sctest + \ifin@ + \let\AfterBabelCommands\bbl@aftercmds + \let\SetString\bbl@setstring + \let\bbl@stringdef\bbl@provstring + \fi\fi\fi + \bbl@scswitch + \ifx\bbl@G\@empty + \def\SetString##1##2{% + \bbl@error{Missing group for string \string##1}% + {You must assign strings to some category, typically\\% + captions or extras, but you set none}}% + \fi + \ifx\@empty#1% + \bbl@usehooks{defaultcommands}{}% + \else + \@expandtwoargs + \bbl@usehooks{encodedcommands}{{\bbl@sc@charset}{\bbl@sc@fontenc}}% + \fi} +% \end{macrocode} % -% \begin{macrocode} -\def\user@language@group{user@\language@group} -\def\bbl@set@user@generic#1#2{% - \bbl@ifunset{user@generic@active#1}% - {\bbl@active@def#1\user@language@group{user@active}{user@generic@active}% - \bbl@active@def#1\user@group{user@generic@active}{language@active}% - \expandafter\edef\csname#2@sh@#1@@\endcsname{% - \expandafter\noexpand\csname normal@char#1\endcsname}% - \expandafter\edef\csname#2@sh@#1@\string\protect@\endcsname{% - \expandafter\noexpand\csname user@active#1\endcsname}}% - \@empty} -\newcommand\defineshorthand[3][user]{% - \edef\bbl@tempa{\zap@space#1 \@empty}% - \bbl@for\bbl@tempb\bbl@tempa{% - \if*\expandafter\@car\bbl@tempb\@nil - \edef\bbl@tempb{user@\expandafter\@gobble\bbl@tempb}% - \@expandtwoargs - \bbl@set@user@generic{\expandafter\string\@car#2\@nil}\bbl@tempb - \fi - \declare@shorthand{\bbl@tempb}{#2}{#3}}} +% There are two versions of |\bbl@scswitch|. The first version is used +% when |ldf|s are read, and it makes sure |\|\m{group}\m{language} is +% reset, but only once (|\bbl@screset| is used to keep track of this). +% The second version is used in the preamble and packages loaded after +% \babel{} and does nothing. +% +% The macro |\bbl@forlang| loops |\bbl@L| but its body is executed only +% if the value is in |\BabelLanguages| (inside \babel) or +% |\date|\m{language} is defined (after \babel{} has been loaded). +% There are also two version of |\bbl@forlang|. The first one skips the +% current iteration if the language is not in |\BabelLanguages| (used +% in |ldf|s), and the second one skips undefined languages (after +% \babel{} has been loaded) . +% +% \begin{macrocode} +\def\bbl@forlang#1#2{% + \bbl@for#1\bbl@L{% + \bbl@xin@{,#1,}{,\BabelLanguages,}% + \ifin@#2\relax\fi}} +\def\bbl@scswitch{% + \bbl@forlang\bbl@tempa{% + \ifx\bbl@G\@empty\else + \ifx\SetString\@gobbletwo\else + \edef\bbl@GL{\bbl@G\bbl@tempa}% + \bbl@xin@{,\bbl@GL,}{,\bbl@screset,}% + \ifin@\else + \global\expandafter\let\csname\bbl@GL\endcsname\@undefined + \xdef\bbl@screset{\bbl@screset,\bbl@GL}% + \fi + \fi + \fi}} +\AtEndOfPackage{% + \def\bbl@forlang#1#2{\bbl@for#1\bbl@L{\bbl@ifunset{date#1}{}{#2}}}% + \let\bbl@scswitch\relax} +\@onlypreamble\EndBabelCommands +\def\EndBabelCommands{% + \bbl@usehooks{stopcommands}{}% + \endgroup + \endgroup + \bbl@scafter} +\let\bbl@endcommands\EndBabelCommands % \end{macrocode} % -% \end{macro} +% Now we define commands to be used inside |\StartBabelCommands|. % -% \begin{macro}{\languageshorthands} +% \paragraph{Strings} The following macro is the actual definition +% of |\SetString| when it is ``active'' % -% A user level command to change the language from which shorthands -% are used. Unfortunately, \babel{} currently does not keep track -% of defined groups, and therefore there is no way to catch a -% possible change in casing to fix it in the same way languages names -% are fixed. [TODO]. +% First save the ``switcher''. Create it if undefined. Strings are +% defined only if undefined (ie, like |\providescommmand|). With +% the event |stringprocess| you can preprocess the string by +% manipulating the value of |\BabelString|. If there are several +% hooks assigned to this event, preprocessing is done in the same +% order as defined. Finally, the string is set. % % \begin{macrocode} -\def\languageshorthands#1{\def\language@group{#1}} +\def\bbl@setstring#1#2{% eg, \prefacename{} + \bbl@forlang\bbl@tempa{% + \edef\bbl@LC{\bbl@tempa\bbl@stripslash#1}% + \bbl@ifunset{\bbl@LC}% eg, \germanchaptername + {\bbl@exp{% + \global\\\bbl@add\<\bbl@G\bbl@tempa>{\\\bbl@scset\\#1\<\bbl@LC>}}}% + {}% + \def\BabelString{#2}% + \bbl@usehooks{stringprocess}{}% + \expandafter\bbl@stringdef + \csname\bbl@LC\expandafter\endcsname\expandafter{\BabelString}}} % \end{macrocode} % -% \end{macro} +% Now, some addtional stuff to be used when encoded strings are +% used. Captions then include |\bbl@encoded| for string to be +% expanded in case transformations. It is |\relax| by default, but +% in |\MakeUppercase| and |\MakeLowercase| its value is a modified +% expandable |\@changed@cmd|. % -% \begin{macro}{\aliasshorthand} -% First the new shorthand needs to be initialized. Then, we define -% the new shorthand in terms of the original one, but note with -% |\aliasshorthands{"}{/}| is |\active@prefix /\active@char/|, so we -% still need to let the lattest to |\active@char"|. +% \begin{macrocode} +\ifx\bbl@opt@strings\relax + \def\bbl@scset#1#2{\def#1{\bbl@encoded#2}} + \bbl@patchuclc + \let\bbl@encoded\relax + \def\bbl@encoded@uclc#1{% + \@inmathwarn#1% + \expandafter\ifx\csname\cf@encoding\string#1\endcsname\relax + \expandafter\ifx\csname ?\string#1\endcsname\relax + \TextSymbolUnavailable#1% + \else + \csname ?\string#1\endcsname + \fi + \else + \csname\cf@encoding\string#1\endcsname + \fi} +\else + \def\bbl@scset#1#2{\def#1{#2}} +\fi +% \end{macrocode} % +% Define |\SetStringLoop|, which is actually set inside +% |\StartBabelCommands|. The current definition is somewhat complicated +% because we need a count, but |\count@| is not under our control +% (remember |\SetString| may call hooks). Instead of defining a +% dedicated count, we just ``pre-expand'' its value. % % \begin{macrocode} -\def\aliasshorthand#1#2{% - \bbl@ifshorthand{#2}% - {\expandafter\ifx\csname active@char\string#2\endcsname\relax - \ifx\document\@notprerr - \@notshorthand{#2}% - \else - \initiate@active@char{#2}% - \expandafter\let\csname active@char\string#2\expandafter\endcsname - \csname active@char\string#1\endcsname - \expandafter\let\csname normal@char\string#2\expandafter\endcsname - \csname normal@char\string#1\endcsname - \bbl@activate{#2}% - \fi - \fi}% - {\bbl@error - {Cannot declare a shorthand turned off (\string#2)} - {Sorry, but you cannot use shorthands which have been\\% - turned off in the package options}}} +%<<*Macros local to BabelCommands>> +\def\SetStringLoop##1##2{% + \def\bbl@templ####1{\expandafter\noexpand\csname##1\endcsname}% + \count@\z@ + \bbl@loop\bbl@tempa{##2}{% empty items and spaces are ok + \advance\count@\@ne + \toks@\expandafter{\bbl@tempa}% + \bbl@exp{% + \\\SetString\bbl@templ{\romannumeral\count@}{\the\toks@}% + \count@=\the\count@\relax}}}% +%<> % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\@notshorthand} +% \paragraph{Delaying code} Now the definition of |\AfterBabelCommands| +% when it is activated. % % \begin{macrocode} -\def\@notshorthand#1{% - \bbl@error{% - The character '\string #1' should be made a shorthand character;\\% - add the command \string\useshorthands\string{#1\string} to - the preamble.\\% - I will ignore your instruction}% - {You may proceed, but expect unexpected results}} +\def\bbl@aftercmds#1{% + \toks@\expandafter{\bbl@scafter#1}% + \xdef\bbl@scafter{\the\toks@}} % \end{macrocode} % -% \end{macro} +% \paragraph{Case mapping} % -% \begin{macro}{\shorthandon} -% \begin{macro}{\shorthandoff} -% The first level definition of these macros just passes the -% argument on to |\bbl@switch@sh|, adding |\@nil| at the end to -% denote the end of the list of characters. +% The command |\SetCase| provides a way to change the behavior of +% |\MakeUppercase| and |\MakeLowercase|. |\bbl@tempa| is set by the +% patched |\@uclclist| to the parsing command. % % \begin{macrocode} -\newcommand*\shorthandon[1]{\bbl@switch@sh\@ne#1\@nnil} -\DeclareRobustCommand*\shorthandoff{% - \@ifstar{\bbl@shorthandoff\tw@}{\bbl@shorthandoff\z@}} -\def\bbl@shorthandoff#1#2{\bbl@switch@sh#1#2\@nnil} +%<<*Macros local to BabelCommands>> + \newcommand\SetCase[3][]{% + \bbl@patchuclc + \bbl@forlang\bbl@tempa{% + \expandafter\bbl@encstring + \csname\bbl@tempa @bbl@uclc\endcsname{\bbl@tempa##1}% + \expandafter\bbl@encstring + \csname\bbl@tempa @bbl@uc\endcsname{##2}% + \expandafter\bbl@encstring + \csname\bbl@tempa @bbl@lc\endcsname{##3}}}% +%<> % \end{macrocode} % -% \begin{macro}{\bbl@switch@sh} -% -% The macro |\bbl@switch@sh| takes the list of characters apart one -% by one and subsequently switches the category code of the -% shorthand character according to the first argument of -% |\bbl@switch@sh|. +% Macros to deal with case mapping for hyphenation. To decide if the +% document is monolingual or multilingual, we make a rough guess -- +% just see if there is a comma in the languages list, built in the +% first pass of the package options. % -% But before any of this switching takes place we make sure that the -% character we are dealing with is known as a shorthand character. -% If it is, a macro such as |\active@char"| should exist. +% \begin{macrocode} +%<<*Macros local to BabelCommands>> + \newcommand\SetHyphenMap[1]{% + \bbl@forlang\bbl@tempa{% + \expandafter\bbl@stringdef + \csname\bbl@tempa @bbl@hyphenmap\endcsname{##1}}}% +%<> +% \end{macrocode} % -% Switching off and on is easy -- we just set the category code to -% `other' (12) and |\active|. With the starred version, the original -% catcode and the original definition, saved in -% |@initiate@active@char|, are restored. +% There are 3 helper macros which do most of the work for you. % -% \begin{macrocode} -\def\bbl@switch@sh#1#2{% - \ifx#2\@nnil\else - \bbl@ifunset{bbl@active@\string#2}% - {\bbl@error - {I can't switch '\string#2' on or off--not a shorthand}% - {This character is not a shorthand. Maybe you made\\% - a typing mistake? I will ignore your instruction.}}% - {\ifcase#1% off, on, off* - \catcode`#212\relax - \or - \catcode`#2\active - \bbl@ifunset{bbl@shdef@\string#2}% - {}% - {\bbl@withactive{\expandafter\let\expandafter}#2% - \csname bbl@shdef@\string#2\endcsname - \bbl@csarg\let{shdef@\string#2}\relax}% - \ifcase\bbl@activated\or - \bbl@activate{#2}% - \else - \bbl@deactivate{#2}% - \fi - \or - \bbl@ifunset{bbl@shdef@\string#2}% - {\bbl@withactive{\bbl@csarg\let{shdef@\string#2}}#2}% - {}% - \csname bbl@oricat@\string#2\endcsname - \csname bbl@oridef@\string#2\endcsname - \fi}% - \bbl@afterfi\bbl@switch@sh#1% +% \begin{macrocode} +\newcommand\BabelLower[2]{% one to one. + \ifnum\lccode#1=#2\else + \babel@savevariable{\lccode#1}% + \lccode#1=#2\relax \fi} +\newcommand\BabelLowerMM[4]{% many-to-many + \@tempcnta=#1\relax + \@tempcntb=#4\relax + \def\bbl@tempa{% + \ifnum\@tempcnta>#2\else + \@expandtwoargs\BabelLower{\the\@tempcnta}{\the\@tempcntb}% + \advance\@tempcnta#3\relax + \advance\@tempcntb#3\relax + \expandafter\bbl@tempa + \fi}% + \bbl@tempa} +\newcommand\BabelLowerMO[4]{% many-to-one + \@tempcnta=#1\relax + \def\bbl@tempa{% + \ifnum\@tempcnta>#2\else + \@expandtwoargs\BabelLower{\the\@tempcnta}{#4}% + \advance\@tempcnta#3 + \expandafter\bbl@tempa + \fi}% + \bbl@tempa} % \end{macrocode} % -% \end{macro} -% \end{macro} -% \end{macro} -% -% Note the value is that at the expansion time; eg, in the preample -% shorhands are usually deactivated. +% The following package options control the behavior of +% hyphenation mapping. % % \begin{macrocode} -\def\babelshorthand{\active@prefix\babelshorthand\bbl@putsh} -\def\bbl@putsh#1{% - \bbl@ifunset{bbl@active@\string#1}% - {\bbl@putsh@i#1\@empty\@nnil}% - {\csname bbl@active@\string#1\endcsname}} -\def\bbl@putsh@i#1#2\@nnil{% - \csname\language@group @sh@\string#1@% - \ifx\@empty#2\else\string#2@\fi\endcsname} -\ifx\bbl@opt@shorthands\@nnil\else - \let\bbl@s@initiate@active@char\initiate@active@char - \def\initiate@active@char#1{% - \bbl@ifshorthand{#1}{\bbl@s@initiate@active@char{#1}}{}} - \let\bbl@s@switch@sh\bbl@switch@sh - \def\bbl@switch@sh#1#2{% - \ifx#2\@nnil\else - \bbl@afterfi - \bbl@ifshorthand{#2}{\bbl@s@switch@sh#1{#2}}{\bbl@switch@sh#1}% - \fi} - \let\bbl@s@activate\bbl@activate - \def\bbl@activate#1{% - \bbl@ifshorthand{#1}{\bbl@s@activate{#1}}{}} - \let\bbl@s@deactivate\bbl@deactivate - \def\bbl@deactivate#1{% - \bbl@ifshorthand{#1}{\bbl@s@deactivate{#1}}{}} -\fi +%<<*More package options>> +\DeclareOption{hyphenmap=off}{\chardef\bbl@opt@hyphenmap\z@} +\DeclareOption{hyphenmap=first}{\chardef\bbl@opt@hyphenmap\@ne} +\DeclareOption{hyphenmap=select}{\chardef\bbl@opt@hyphenmap\tw@} +\DeclareOption{hyphenmap=other}{\chardef\bbl@opt@hyphenmap\thr@@} +\DeclareOption{hyphenmap=other*}{\chardef\bbl@opt@hyphenmap4\relax} +%<> % \end{macrocode} % -% You may want to test if a character is a shorthand. Note it does not -% test whether the shorthand is on or off. +% Initial setup to provide a default behavior if |hypenmap| +% is not set. % % \begin{macrocode} -\newcommand\ifbabelshorthand[3]{\bbl@ifunset{bbl@active@\string#1}{#3}{#2}} +\AtEndOfPackage{% + \ifx\bbl@opt@hyphenmap\@undefined + \bbl@xin@{,}{\bbl@language@opts}% + \chardef\bbl@opt@hyphenmap\ifin@4\else\@ne\fi + \fi} % \end{macrocode} % -% \begin{macro}{\bbl@prim@s} -% \begin{macro}{\bbl@pr@m@s} -% -% One of the internal macros that are involved in substituting |\prime| -% for each right quote in mathmode is |\prim@s|. This checks if the -% next character is a right quote. When the right quote is active, the -% definition of this macro needs to be adapted to look also for an -% active right quote; the hat could be active, too. +% This sections ends with a general tool for resetting the caption +% names with a unique interface. With the old way, which mixes the +% switcher and the string, we convert it to the new one, which +% separates these two steps. % % \begin{macrocode} -\def\bbl@prim@s{% - \prime\futurelet\@let@token\bbl@pr@m@s} -\def\bbl@if@primes#1#2{% - \ifx#1\@let@token - \expandafter\@firstoftwo - \else\ifx#2\@let@token - \bbl@afterelse\expandafter\@firstoftwo +\newcommand\setlocalecaption{% TODO. Catch typos. What about ensure? + \@ifstar\bbl@setcaption@s\bbl@setcaption@x} +\def\bbl@setcaption@x#1#2#3{% language caption-name string + \bbl@trim@def\bbl@tempa{#2}% + \bbl@xin@{.template}{\bbl@tempa}% + \ifin@ + \bbl@ini@captions@template{#3}{#1}% \else - \bbl@afterfi\expandafter\@secondoftwo - \fi\fi} -\begingroup - \catcode`\^=7 \catcode`\*=\active \lccode`\*=`\^ - \catcode`\'=12 \catcode`\"=\active \lccode`\"=`\' - \lowercase{% - \gdef\bbl@pr@m@s{% - \bbl@if@primes"'% - \pr@@@s - {\bbl@if@primes*^\pr@@@t\egroup}}} -\endgroup + \edef\bbl@tempd{% + \expandafter\expandafter\expandafter + \strip@prefix\expandafter\meaning\csname captions#1\endcsname}% + \bbl@xin@ + {\expandafter\string\csname #2name\endcsname}% + {\bbl@tempd}% + \ifin@ % Renew caption + \bbl@xin@{\string\bbl@scset}{\bbl@tempd}% + \ifin@ + \bbl@exp{% + \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% + {\\\bbl@scset\<#2name>\<#1#2name>}% + {}}% + \else % Old way converts to new way + \bbl@ifunset{#1#2name}% + {\bbl@exp{% + \\\bbl@add\{\def\<#2name>{\<#1#2name>}}% + \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% + {\def\<#2name>{\<#1#2name>}}% + {}}}% + {}% + \fi + \else + \bbl@xin@{\string\bbl@scset}{\bbl@tempd}% New + \ifin@ % New way + \bbl@exp{% + \\\bbl@add\{\\\bbl@scset\<#2name>\<#1#2name>}% + \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% + {\\\bbl@scset\<#2name>\<#1#2name>}% + {}}% + \else % Old way, but defined in the new way + \bbl@exp{% + \\\bbl@add\{\def\<#2name>{\<#1#2name>}}% + \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% + {\def\<#2name>{\<#1#2name>}}% + {}}% + \fi% + \fi + \@namedef{#1#2name}{#3}% + \toks@\expandafter{\bbl@captionslist}% + \bbl@exp{\\\in@{\<#2name>}{\the\toks@}}% + \ifin@\else + \bbl@exp{\\\bbl@add\\\bbl@captionslist{\<#2name>}}% + \bbl@toglobal\bbl@captionslist + \fi + \fi} +% \def\bbl@setcaption@s#1#2#3{} % TODO. Not yet implemented % \end{macrocode} % -% \end{macro} -% \end{macro} +% \subsection{Macros common to a number of languages} % -% Usually the |~| is active and expands to \verb*=\penalty\@M\ =. -% When it is written to the \file{.aux} file it is written -% expanded. To prevent that and to be able to use the character |~| -% as a start character for a shorthand, it is redefined here as a -% one character shorthand on system level. The system declaration -% is in most cases redundant (when |~| is still a non-break space), -% and in some cases is inconvenient (if |~| has been redefined); -% however, for backward compatibility it is maintained (some -% existing documents may rely on the \babel{} value). +% \begin{macro}{\set@low@box} +% +% The following macro is used to lower quotes to the same level as +% the comma. It prepares its argument in box register~0. % % \begin{macrocode} -\initiate@active@char{~} -\declare@shorthand{system}{~}{\leavevmode\nobreak\ } -\bbl@activate{~} +\bbl@trace{Macros related to glyphs} +\def\set@low@box#1{\setbox\tw@\hbox{,}\setbox\z@\hbox{#1}% + \dimen\z@\ht\z@ \advance\dimen\z@ -\ht\tw@% + \setbox\z@\hbox{\lower\dimen\z@ \box\z@}\ht\z@\ht\tw@ \dp\z@\dp\tw@} % \end{macrocode} % -% \begin{macro}{\OT1dqpos} -% \begin{macro}{\T1dqpos} -% The position of the double quote character is different for the -% OT1 and T1 encodings. It will later be selected using the -% |\f@encoding| macro. Therefore we define two macros here to store -% the position of the character in these encodings. +% \end{macro} +% +% \begin{macro}{\save@sf@q} +% The macro |\save@sf@q| is used to save and reset the current +% space factor. % % \begin{macrocode} -\expandafter\def\csname OT1dqpos\endcsname{127} -\expandafter\def\csname T1dqpos\endcsname{4} +\def\save@sf@q#1{\leavevmode + \begingroup + \edef\@SF{\spacefactor\the\spacefactor}#1\@SF + \endgroup} % \end{macrocode} % -% When the macro |\f@encoding| is undefined (as it is in plain -% \TeX) we define it here to expand to \texttt{OT1} -% -% \begin{macrocode} -\ifx\f@encoding\@undefined - \def\f@encoding{OT1} -\fi -% \end{macrocode} -% -% \end{macro} % \end{macro} % -% \subsection{Language attributes} -% -% Language attributes provide a means to give the user control over -% which features of the language definition files he wants to -% enable. -% \begin{macro}{\languageattribute} +% \subsection{Making glyphs available} % -% The macro |\languageattribute| checks whether its arguments are -% valid and then activates the selected language attribute. -% First check whether the language is known, and then process each -% attribute in the list. +% This section makes a number of glyphs available that either do not +% exist in the \texttt{OT1} encoding and have to be `faked', or +% that are not accessible through \file{T1enc.def}. % -% \begin{macrocode} -\bbl@trace{Language attributes} -\newcommand\languageattribute[2]{% - \def\bbl@tempc{#1}% - \bbl@fixname\bbl@tempc - \bbl@iflanguage\bbl@tempc{% - \bbl@vforeach{#2}{% -% \end{macrocode} +% \subsubsection{Quotation marks} % -% We want to make sure that each attribute is selected only once; -% therefore we store the already selected attributes in -% |\bbl@known@attribs|. When that control sequence is not yet -% defined this attribute is certainly not selected before. +% \begin{macro}{\quotedblbase} +% In the \texttt{T1} encoding the opening double quote at the +% baseline is available as a separate character, accessible via +% |\quotedblbase|. In the \texttt{OT1} encoding it is not +% available, therefore we make it available by lowering the normal +% open quote character to the baseline. % % \begin{macrocode} - \ifx\bbl@known@attribs\@undefined - \in@false - \else - \bbl@xin@{,\bbl@tempc-##1,}{,\bbl@known@attribs,}% - \fi - \ifin@ - \bbl@warning{% - You have more than once selected the attribute '##1'\\% - for language #1. Reported}% - \else +\ProvideTextCommand{\quotedblbase}{OT1}{% + \save@sf@q{\set@low@box{\textquotedblright\/}% + \box\z@\kern-.04em\bbl@allowhyphens}} % \end{macrocode} % -% When we end up here the attribute is not selected before. So, we -% add it to the list of selected attributes and execute the -% associated \TeX-code. +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used this glyph can still be typeset. % % \begin{macrocode} - \bbl@exp{% - \\\bbl@add@list\\\bbl@known@attribs{\bbl@tempc-##1}}% - \edef\bbl@tempa{\bbl@tempc-##1}% - \expandafter\bbl@ifknown@ttrib\expandafter{\bbl@tempa}\bbl@attributes% - {\csname\bbl@tempc @attr@##1\endcsname}% - {\@attrerr{\bbl@tempc}{##1}}% - \fi}}} -\@onlypreamble\languageattribute +\ProvideTextCommandDefault{\quotedblbase}{% + \UseTextSymbol{OT1}{\quotedblbase}} % \end{macrocode} % -% The error text to be issued when an unknown attribute is -% selected. +% \end{macro} +% +% \begin{macro}{\quotesinglbase} +% We also need the single quote character at the baseline. % % \begin{macrocode} -\newcommand*{\@attrerr}[2]{% - \bbl@error - {The attribute #2 is unknown for language #1.}% - {Your command will be ignored, type to proceed}} +\ProvideTextCommand{\quotesinglbase}{OT1}{% + \save@sf@q{\set@low@box{\textquoteright\/}% + \box\z@\kern-.04em\bbl@allowhyphens}} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\bbl@declare@ttribute} -% This command adds the new language/attribute combination to the -% list of known attributes. -% -% Then it defines a control sequence to be executed when the -% attribute is used in a document. The result of this should be -% that the macro |\extras...| for the current language is extended, -% otherwise the attribute will not work as its code is removed from -% memory at |\begin{document}|. +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used this glyph can still be typeset. % % \begin{macrocode} -\def\bbl@declare@ttribute#1#2#3{% - \bbl@xin@{,#2,}{,\BabelModifiers,}% - \ifin@ - \AfterBabelLanguage{#1}{\languageattribute{#1}{#2}}% - \fi - \bbl@add@list\bbl@attributes{#1-#2}% - \expandafter\def\csname#1@attr@#2\endcsname{#3}} +\ProvideTextCommandDefault{\quotesinglbase}{% + \UseTextSymbol{OT1}{\quotesinglbase}} % \end{macrocode} % % \end{macro} % -% \begin{macro}{\bbl@ifattributeset} -% This internal macro has 4 arguments. It can be used to interpret -% \TeX\ code based on whether a certain attribute was set. This -% command should appear inside the argument to |\AtBeginDocument| -% because the attributes are set in the document preamble, -% \emph{after} \babel\ is loaded. -% -% The first argument is the language, the second argument the -% attribute being checked, and the third and fourth arguments are -% the true and false clauses. +% \begin{macro}{\guillemetleft} +% \begin{macro}{\guillemetright} +% The guillemet characters are not available in \texttt{OT1} +% encoding. They are faked. (Wrong names with o preserved for +% compatibility.) % % \begin{macrocode} -\def\bbl@ifattributeset#1#2#3#4{% - \ifx\bbl@known@attribs\@undefined - \in@false +\ProvideTextCommand{\guillemetleft}{OT1}{% + \ifmmode + \ll \else - \bbl@xin@{,#1-#2,}{,\bbl@known@attribs,}% - \fi - \ifin@ - \bbl@afterelse#3% + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle\ll$}\bbl@allowhyphens}% + \fi} +\ProvideTextCommand{\guillemetright}{OT1}{% + \ifmmode + \gg \else - \bbl@afterfi#4% + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle\gg$}\bbl@allowhyphens}% + \fi} +\ProvideTextCommand{\guillemotleft}{OT1}{% + \ifmmode + \ll + \else + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle\ll$}\bbl@allowhyphens}% + \fi} +\ProvideTextCommand{\guillemotright}{OT1}{% + \ifmmode + \gg + \else + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle\gg$}\bbl@allowhyphens}% \fi} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\bbl@ifknown@ttrib} -% An internal macro to check whether a given language/attribute is -% known. The macro takes 4 arguments, the language/attribute, the -% attribute list, the \TeX-code to be executed when the attribute -% is known and the \TeX-code to be executed otherwise. -% -% We first assume the attribute is unknown. Then we loop over the -% list of known attributes, trying to find a match. +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used these glyphs can still be typeset. % % \begin{macrocode} -\def\bbl@ifknown@ttrib#1#2{% - \let\bbl@tempa\@secondoftwo - \bbl@loopx\bbl@tempb{#2}{% - \expandafter\in@\expandafter{\expandafter,\bbl@tempb,}{,#1,}% - \ifin@ - \let\bbl@tempa\@firstoftwo - \else - \fi}% - \bbl@tempa} +\ProvideTextCommandDefault{\guillemetleft}{% + \UseTextSymbol{OT1}{\guillemetleft}} +\ProvideTextCommandDefault{\guillemetright}{% + \UseTextSymbol{OT1}{\guillemetright}} +\ProvideTextCommandDefault{\guillemotleft}{% + \UseTextSymbol{OT1}{\guillemotleft}} +\ProvideTextCommandDefault{\guillemotright}{% + \UseTextSymbol{OT1}{\guillemotright}} % \end{macrocode} % % \end{macro} +% \end{macro} % -% \begin{macro}{\bbl@clear@ttribs} -% This macro removes all the attribute code from \LaTeX's memory at -% |\begin{document}| time (if any is present). +% \begin{macro}{\guilsinglleft} +% \begin{macro}{\guilsinglright} +% The single guillemets are not available in \texttt{OT1} +% encoding. They are faked. % % \begin{macrocode} -\def\bbl@clear@ttribs{% - \ifx\bbl@attributes\@undefined\else - \bbl@loopx\bbl@tempa{\bbl@attributes}{% - \expandafter\bbl@clear@ttrib\bbl@tempa. - }% - \let\bbl@attributes\@undefined +\ProvideTextCommand{\guilsinglleft}{OT1}{% + \ifmmode + <% + \else + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle<$}\bbl@allowhyphens}% + \fi} +\ProvideTextCommand{\guilsinglright}{OT1}{% + \ifmmode + >% + \else + \save@sf@q{\nobreak + \raise.2ex\hbox{$\scriptscriptstyle>$}\bbl@allowhyphens}% \fi} -\def\bbl@clear@ttrib#1-#2.{% - \expandafter\let\csname#1@attr@#2\endcsname\@undefined} -\AtBeginDocument{\bbl@clear@ttribs} % \end{macrocode} % -% \end{macro} +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used these glyphs can still be typeset. % -% \subsection{Support for saving macro definitions} +% \begin{macrocode} +\ProvideTextCommandDefault{\guilsinglleft}{% + \UseTextSymbol{OT1}{\guilsinglleft}} +\ProvideTextCommandDefault{\guilsinglright}{% + \UseTextSymbol{OT1}{\guilsinglright}} +% \end{macrocode} % -% To save the meaning of control sequences using |\babel@save|, we -% use temporary control sequences. To save hash table entries for -% these control sequences, we don't use the name of the control -% sequence to be saved to construct the temporary name. Instead we -% simply use the value of a counter, which is reset to zero each time -% we begin to save new values. This works well because we release -% the saved meanings before we begin to save a new set of control -% sequence meanings (see |\selectlanguage| and |\originalTeX|). Note -% undefined macros are not undefined any more when saved -- they are -% |\relax|'ed. +% \end{macro} +% \end{macro} % -% \begin{macro}{\babel@savecnt} -% \begin{macro}{\babel@beginsave} -% The initialization of a new save cycle: reset the counter to -% zero. +% \subsubsection{Letters} +% +% \begin{macro}{\ij} +% \begin{macro}{\IJ} +% The dutch language uses the letter `ij'. It is available in +% \texttt{T1} encoded fonts, but not in the \texttt{OT1} encoded +% fonts. Therefore we fake it for the \texttt{OT1} encoding. % % \begin{macrocode} -\bbl@trace{Macros for saving definitions} -\def\babel@beginsave{\babel@savecnt\z@} +\DeclareTextCommand{\ij}{OT1}{% + i\kern-0.02em\bbl@allowhyphens j} +\DeclareTextCommand{\IJ}{OT1}{% + I\kern-0.02em\bbl@allowhyphens J} +\DeclareTextCommand{\ij}{T1}{\char188} +\DeclareTextCommand{\IJ}{T1}{\char156} % \end{macrocode} % -% Before it's forgotten, allocate the counter and initialize all. +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used these glyphs can still be typeset. % % \begin{macrocode} -\newcount\babel@savecnt -\babel@beginsave +\ProvideTextCommandDefault{\ij}{% + \UseTextSymbol{OT1}{\ij}} +\ProvideTextCommandDefault{\IJ}{% + \UseTextSymbol{OT1}{\IJ}} % \end{macrocode} % % \end{macro} % \end{macro} % -% \begin{macro}{\babel@save} -% \begin{macro}{\babel@savevariable} +% \begin{macro}{\dj} +% \begin{macro}{\DJ} +% The croatian language needs the letters |\dj| and |\DJ|; they are +% available in the \texttt{T1} encoding, but not in the +% \texttt{OT1} encoding by default. % -% The macro |\babel@save|\meta{csname} saves the current meaning of the -% control sequence \meta{csname} to -% |\originalTeX|\footnote{\cs{originalTeX} has to be expandable, -% i.\,e.\ you shouldn't let it to \cs{relax}.}. To do this, we let the -% current meaning to a temporary control sequence, the restore commands -% are appended to |\originalTeX| and the counter is incremented. The -% macro |\babel@savevariable|\meta{variable} saves the value of the -% variable. \meta{variable} can be anything allowed after the |\the| -% primitive. +% Some code to construct these glyphs for the \texttt{OT1} encoding +% was made available to me by Stipčević Mario, +% (\texttt{stipcevic@olimp.irb.hr}). % % \begin{macrocode} -\def\babel@save#1{% - \expandafter\let\csname babel@\number\babel@savecnt\endcsname#1\relax - \toks@\expandafter{\originalTeX\let#1=}% - \bbl@exp{% - \def\\\originalTeX{\the\toks@\\relax}}% - \advance\babel@savecnt\@ne} -\def\babel@savevariable#1{% - \toks@\expandafter{\originalTeX #1=}% - \bbl@exp{\def\\\originalTeX{\the\toks@\the#1\relax}}} -% \end{macrocode} +\def\crrtic@{\hrule height0.1ex width0.3em} +\def\crttic@{\hrule height0.1ex width0.33em} +\def\ddj@{% + \setbox0\hbox{d}\dimen@=\ht0 + \advance\dimen@1ex + \dimen@.45\dimen@ + \dimen@ii\expandafter\rem@pt\the\fontdimen\@ne\font\dimen@ + \advance\dimen@ii.5ex + \leavevmode\rlap{\raise\dimen@\hbox{\kern\dimen@ii\vbox{\crrtic@}}}} +\def\DDJ@{% + \setbox0\hbox{D}\dimen@=.55\ht0 + \dimen@ii\expandafter\rem@pt\the\fontdimen\@ne\font\dimen@ + \advance\dimen@ii.15ex % correction for the dash position + \advance\dimen@ii-.15\fontdimen7\font % correction for cmtt font + \dimen\thr@@\expandafter\rem@pt\the\fontdimen7\font\dimen@ + \leavevmode\rlap{\raise\dimen@\hbox{\kern\dimen@ii\vbox{\crttic@}}}} % -% \end{macro} -% \end{macro} +\DeclareTextCommand{\dj}{OT1}{\ddj@ d} +\DeclareTextCommand{\DJ}{OT1}{\DDJ@ D} +% \end{macrocode} % -% \begin{macro}{\bbl@frenchspacing} -% \begin{macro}{\bbl@nonfrenchspacing} -% Some languages need to have |\frenchspacing| in effect. Others -% don't want that. The command |\bbl@frenchspacing| switches it on -% when it isn't already in effect and |\bbl@nonfrenchspacing| -% switches it off if necessary. A more refined way to switch the -% catcodes is done with |ini| files. Here an auxiliary macro is -% defined, but the main part is in |\babelprovide|. This new method -% should be ideally the default one. +% Make sure that when an encoding other than \texttt{OT1} or +% \texttt{T1} is used these glyphs can still be typeset. % % \begin{macrocode} -\def\bbl@frenchspacing{% - \ifnum\the\sfcode`\.=\@m - \let\bbl@nonfrenchspacing\relax - \else - \frenchspacing - \let\bbl@nonfrenchspacing\nonfrenchspacing - \fi} -\let\bbl@nonfrenchspacing\nonfrenchspacing -\let\bbl@elt\relax -\edef\bbl@fs@chars{% - \bbl@elt{\string.}\@m{3000}\bbl@elt{\string?}\@m{3000}% - \bbl@elt{\string!}\@m{3000}\bbl@elt{\string:}\@m{2000}% - \bbl@elt{\string;}\@m{1500}\bbl@elt{\string,}\@m{1250}} -\def\bbl@pre@fs{% - \def\bbl@elt##1##2##3{\sfcode`##1=\the\sfcode`##1\relax}% - \edef\bbl@save@sfcodes{\bbl@fs@chars}}% -\def\bbl@post@fs{% - \bbl@save@sfcodes - \edef\bbl@tempa{\bbl@cl{frspc}}% - \edef\bbl@tempa{\expandafter\@car\bbl@tempa\@nil}% - \if u\bbl@tempa % do nothing - \else\if n\bbl@tempa % non french - \def\bbl@elt##1##2##3{% - \ifnum\sfcode`##1=##2\relax - \babel@savevariable{\sfcode`##1}% - \sfcode`##1=##3\relax - \fi}% - \bbl@fs@chars - \else\if y\bbl@tempa % french - \def\bbl@elt##1##2##3{% - \ifnum\sfcode`##1=##3\relax - \babel@savevariable{\sfcode`##1}% - \sfcode`##1=##2\relax - \fi}% - \bbl@fs@chars - \fi\fi\fi} +\ProvideTextCommandDefault{\dj}{% + \UseTextSymbol{OT1}{\dj}} +\ProvideTextCommandDefault{\DJ}{% + \UseTextSymbol{OT1}{\DJ}} % \end{macrocode} % % \end{macro} % \end{macro} % -% \subsection{Short tags} -% -% \begin{macro}{\babeltags} -% This macro is straightforward. After zapping spaces, we -% loop over the list and define the macros |\text|\m{tag} and -% |\|\m{tag}. Definitions are first expanded so that they don't -% contain |\csname| but the actual macro. +% \begin{macro}{\SS} +% For the \texttt{T1} encoding |\SS| is defined and selects a +% specific glyph from the font, but for other encodings it is not +% available. Therefore we make it available here. % -% \begin{macrocode} -\bbl@trace{Short tags} -\def\babeltags#1{% - \edef\bbl@tempa{\zap@space#1 \@empty}% - \def\bbl@tempb##1=##2\@@{% - \edef\bbl@tempc{% - \noexpand\newcommand - \expandafter\noexpand\csname ##1\endcsname{% - \noexpand\protect - \expandafter\noexpand\csname otherlanguage*\endcsname{##2}} - \noexpand\newcommand - \expandafter\noexpand\csname text##1\endcsname{% - \noexpand\foreignlanguage{##2}}} - \bbl@tempc}% - \bbl@for\bbl@tempa\bbl@tempa{% - \expandafter\bbl@tempb\bbl@tempa\@@}} +% \begin{macrocode} +\DeclareTextCommand{\SS}{OT1}{SS} +\ProvideTextCommandDefault{\SS}{\UseTextSymbol{OT1}{\SS}} % \end{macrocode} % -% \end{macro} +% \end{macro} % -% \subsection{Hyphens} +% \subsubsection{Shorthands for quotation marks} % -% \begin{macro}{\babelhyphenation} +% Shorthands are provided for a number of different quotation +% marks, which make them usable both outside and inside mathmode. +% They are defined with |\ProvideTextCommandDefault|, but this is +% very likely not required because their definitions are based on +% encoding-dependent macros. % -% This macro saves hyphenation exceptions. Two macros are used to -% store them: |\bbl@hyphenation@| for the global ones and -% |\bbl@hyphenation| for language ones. See |\bbl@patterns| -% above for further details. We make sure there is a space between -% words when multiple commands are used. +% \begin{macro}{\glq} +% \begin{macro}{\grq} +% +% The `german' single quotes. % % \begin{macrocode} -\bbl@trace{Hyphens} -\@onlypreamble\babelhyphenation -\AtEndOfPackage{% - \newcommand\babelhyphenation[2][\@empty]{% - \ifx\bbl@hyphenation@\relax - \let\bbl@hyphenation@\@empty - \fi - \ifx\bbl@hyphlist\@empty\else - \bbl@warning{% - You must not intermingle \string\selectlanguage\space and\\% - \string\babelhyphenation\space or some exceptions will not\\% - be taken into account. Reported}% - \fi - \ifx\@empty#1% - \protected@edef\bbl@hyphenation@{\bbl@hyphenation@\space#2}% - \else - \bbl@vforeach{#1}{% - \def\bbl@tempa{##1}% - \bbl@fixname\bbl@tempa - \bbl@iflanguage\bbl@tempa{% - \bbl@csarg\protected@edef{hyphenation@\bbl@tempa}{% - \bbl@ifunset{bbl@hyphenation@\bbl@tempa}% - {}% - {\csname bbl@hyphenation@\bbl@tempa\endcsname\space}% - #2}}}% - \fi}} +\ProvideTextCommandDefault{\glq}{% + \textormath{\quotesinglbase}{\mbox{\quotesinglbase}}} % \end{macrocode} % -% \end{macro} -% -% \begin{macro}{\bbl@allowhyphens} -% -% This macro makes hyphenation possible. Basically its definition -% is nothing more than |\nobreak| |\hskip| \texttt{0pt plus -% 0pt}\footnote{\TeX\ begins and ends a word for hyphenation at a -% glue node. The penalty prevents a linebreak at this glue node.}. +% The definition of |\grq| depends on the fontencoding. With +% \texttt{T1} encoding no extra kerning is needed. % % \begin{macrocode} -\def\bbl@allowhyphens{\ifvmode\else\nobreak\hskip\z@skip\fi} -\def\bbl@t@one{T1} -\def\allowhyphens{\ifx\cf@encoding\bbl@t@one\else\bbl@allowhyphens\fi} +\ProvideTextCommand{\grq}{T1}{% + \textormath{\kern\z@\textquoteleft}{\mbox{\textquoteleft}}} +\ProvideTextCommand{\grq}{TU}{% + \textormath{\textquoteleft}{\mbox{\textquoteleft}}} +\ProvideTextCommand{\grq}{OT1}{% + \save@sf@q{\kern-.0125em + \textormath{\textquoteleft}{\mbox{\textquoteleft}}% + \kern.07em\relax}} +\ProvideTextCommandDefault{\grq}{\UseTextSymbol{OT1}\grq} % \end{macrocode} % % \end{macro} +% \end{macro} % -% \begin{macro}{\babelhyphen} +% \begin{macro}{\glqq} +% \begin{macro}{\grqq} % -% Macros to insert common hyphens. Note the space before |@| in -% |\babelhyphen|. Instead of protecting it with -% |\DeclareRobustCommand|, which could insert a |\relax|, we use -% the same procedure as shorthands, with |\active@prefix|. +% The `german' double quotes. % % \begin{macrocode} -\newcommand\babelnullhyphen{\char\hyphenchar\font} -\def\babelhyphen{\active@prefix\babelhyphen\bbl@hyphen} -\def\bbl@hyphen{% - \@ifstar{\bbl@hyphen@i @}{\bbl@hyphen@i\@empty}} -\def\bbl@hyphen@i#1#2{% - \bbl@ifunset{bbl@hy@#1#2\@empty}% - {\csname bbl@#1usehyphen\endcsname{\discretionary{#2}{}{#2}}}% - {\csname bbl@hy@#1#2\@empty\endcsname}} +\ProvideTextCommandDefault{\glqq}{% + \textormath{\quotedblbase}{\mbox{\quotedblbase}}} % \end{macrocode} % -% The following two commands are used to wrap the ``hyphen'' and -% set the behavior of the rest of the word -- the version with a -% single |@| is used when further hyphenation is allowed, while -% that with |@@| if no more hyphens are allowed. In both cases, if -% the hyphen is preceded by a positive space, breaking after the -% hyphen is disallowed. -% -% There should not be a discretionary after a hyphen at the -% beginning of a word, so it is prevented if preceded by a -% skip. Unfortunately, this does handle cases like ``(-suffix)''. -% |\nobreak| is always preceded by |\leavevmode|, in case the -% shorthand starts a paragraph. +% The definition of |\grqq| depends on the fontencoding. With +% \texttt{T1} encoding no extra kerning is needed. % % \begin{macrocode} -\def\bbl@usehyphen#1{% - \leavevmode - \ifdim\lastskip>\z@\mbox{#1}\else\nobreak#1\fi - \nobreak\hskip\z@skip} -\def\bbl@@usehyphen#1{% - \leavevmode\ifdim\lastskip>\z@\mbox{#1}\else#1\fi} +\ProvideTextCommand{\grqq}{T1}{% + \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}} +\ProvideTextCommand{\grqq}{TU}{% + \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}} +\ProvideTextCommand{\grqq}{OT1}{% + \save@sf@q{\kern-.07em + \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}% + \kern.07em\relax}} +\ProvideTextCommandDefault{\grqq}{\UseTextSymbol{OT1}\grqq} % \end{macrocode} % -% The following macro inserts the hyphen char. +% \end{macro} +% \end{macro} % -% \begin{macrocode} -\def\bbl@hyphenchar{% - \ifnum\hyphenchar\font=\m@ne - \babelnullhyphen - \else - \char\hyphenchar\font - \fi} -% \end{macrocode} +% \begin{macro}{\flq} +% \begin{macro}{\frq} % -% Finally, we define the hyphen ``types''. Their names will not -% change, so you may use them in |ldf|'s. After a space, the -% |\mbox| in |\bbl@hy@nobreak| is redundant. +% The `french' single guillemets. % % \begin{macrocode} -\def\bbl@hy@soft{\bbl@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}} -\def\bbl@hy@@soft{\bbl@@usehyphen{\discretionary{\bbl@hyphenchar}{}{}}} -\def\bbl@hy@hard{\bbl@usehyphen\bbl@hyphenchar} -\def\bbl@hy@@hard{\bbl@@usehyphen\bbl@hyphenchar} -\def\bbl@hy@nobreak{\bbl@usehyphen{\mbox{\bbl@hyphenchar}}} -\def\bbl@hy@@nobreak{\mbox{\bbl@hyphenchar}} -\def\bbl@hy@repeat{% - \bbl@usehyphen{% - \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}} -\def\bbl@hy@@repeat{% - \bbl@@usehyphen{% - \discretionary{\bbl@hyphenchar}{\bbl@hyphenchar}{\bbl@hyphenchar}}} -\def\bbl@hy@empty{\hskip\z@skip} -\def\bbl@hy@@empty{\discretionary{}{}{}} +\ProvideTextCommandDefault{\flq}{% + \textormath{\guilsinglleft}{\mbox{\guilsinglleft}}} +\ProvideTextCommandDefault{\frq}{% + \textormath{\guilsinglright}{\mbox{\guilsinglright}}} % \end{macrocode} % % \end{macro} +% \end{macro} % -% \begin{macro}{\bbl@disc} -% For some languages the macro |\bbl@disc| is used to ease the -% insertion of discretionaries for letters that behave `abnormally' -% at a breakpoint. +% \begin{macro}{\flqq} +% \begin{macro}{\frqq} +% +% The `french' double guillemets. % % \begin{macrocode} -\def\bbl@disc#1#2{\nobreak\discretionary{#2-}{}{#1}\bbl@allowhyphens} +\ProvideTextCommandDefault{\flqq}{% + \textormath{\guillemetleft}{\mbox{\guillemetleft}}} +\ProvideTextCommandDefault{\frqq}{% + \textormath{\guillemetright}{\mbox{\guillemetright}}} % \end{macrocode} % % \end{macro} +% \end{macro} % -% \subsection{Multiencoding strings} +% \subsubsection{Umlauts and tremas} % -% The aim following commands is to provide a commom interface for -% strings in several encodings. They also contains several hooks which -% can be used by \luatex{} and \xetex. The code is organized here with -% pseudo-guards, so we start with the basic commands. +% The command |\"| needs to have a different effect for different +% languages. For German for instance, the `umlaut' should be +% positioned lower than the default position for placing it over +% the letters a, o, u, A, O and U. When placed over an e, i, E or I +% it can retain its normal position. For Dutch the same glyph is +% always placed in the lower position. % -% \paragraph{Tools} +% \begin{macro}{\umlauthigh} % -% But first, a couple of tools. The first one makes global a local -% variable. This is not the best solution, but it works. +% \begin{macro}{\umlautlow} +% To be able to provide both positions of |\"| we provide two +% commands to switch the positioning, the default will be +% |\umlauthigh| (the normal positioning). % % \begin{macrocode} -\bbl@trace{Multiencoding strings} -\def\bbl@toglobal#1{\global\let#1#1} -\def\bbl@recatcode#1{% TODO. Used only once? - \@tempcnta="7F - \def\bbl@tempa{% - \ifnum\@tempcnta>"FF\else - \catcode\@tempcnta=#1\relax - \advance\@tempcnta\@ne - \expandafter\bbl@tempa - \fi}% - \bbl@tempa} +\def\umlauthigh{% + \def\bbl@umlauta##1{\leavevmode\bgroup% + \expandafter\accent\csname\f@encoding dqpos\endcsname + ##1\bbl@allowhyphens\egroup}% + \let\bbl@umlaute\bbl@umlauta} +\def\umlautlow{% + \def\bbl@umlauta{\protect\lower@umlaut}} +\def\umlautelow{% + \def\bbl@umlaute{\protect\lower@umlaut}} +\umlauthigh % \end{macrocode} % -% The second one. We need to patch |\@uclclist|, but it is done once -% and only if |\SetCase| is used or if strings are encoded. The code -% is far from satisfactory for several reasons, including the fact -% |\@uclclist| is not a list any more. Therefore a package option is -% added to ignore it. Instead of gobbling the macro -% getting the next two elements (usually |\reserved@a|), we pass it as -% argument to |\bbl@uclc|. The parser is restarted inside -% |\|\m{lang}|@bbl@uclc| because we do not know how many expansions -% are necessary (depends on whether strings are encoded). The last -% part is tricky -- when uppercasing, we have: -%\begin{verbatim} -% \let\bbl@tolower\@empty\bbl@toupper\@empty -%\end{verbatim} -% and starts over (and similarly when lowercasing). +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lower@umlaut} +% The command |\lower@umlaut| is used to position the |\"| closer +% to the letter. +% +% We want the umlaut character lowered, nearer to the letter. To do +% this we need an extra \meta{dimen} register. % % \begin{macrocode} -\@ifpackagewith{babel}{nocase}% - {\let\bbl@patchuclc\relax}% - {\def\bbl@patchuclc{% - \global\let\bbl@patchuclc\relax - \g@addto@macro\@uclclist{\reserved@b{\reserved@b\bbl@uclc}}% - \gdef\bbl@uclc##1{% - \let\bbl@encoded\bbl@encoded@uclc - \bbl@ifunset{\languagename @bbl@uclc}% and resumes it - {##1}% - {\let\bbl@tempa##1\relax % Used by LANG@bbl@uclc - \csname\languagename @bbl@uclc\endcsname}% - {\bbl@tolower\@empty}{\bbl@toupper\@empty}}% - \gdef\bbl@tolower{\csname\languagename @bbl@lc\endcsname}% - \gdef\bbl@toupper{\csname\languagename @bbl@uc\endcsname}}} +\expandafter\ifx\csname U@D\endcsname\relax + \csname newdimen\endcsname\U@D +\fi % \end{macrocode} % +% The following code fools \TeX's \texttt{make\_accent} procedure +% about the current x-height of the font to force another placement +% of the umlaut character. +% First we have to save the current x-height of the font, because +% we'll change this font dimension and this is always done +% globally. +% +% Then we compute the new x-height in such a way that the umlaut +% character is lowered to the base character. The value of +% \texttt{.45ex} depends on the \MF\ parameters with which the +% fonts were built. (Just try out, which value will look best.) +% If the new x-height is too low, it is not changed. +% Finally we call the |\accent| primitive, reset the old x-height +% and insert the base character in the argument. +% % \begin{macrocode} -%<<*More package options>> -\DeclareOption{nocase}{} -%<> +\def\lower@umlaut#1{% + \leavevmode\bgroup + \U@D 1ex% + {\setbox\z@\hbox{% + \expandafter\char\csname\f@encoding dqpos\endcsname}% + \dimen@ -.45ex\advance\dimen@\ht\z@ + \ifdim 1ex<\dimen@ \fontdimen5\font\dimen@ \fi}% + \expandafter\accent\csname\f@encoding dqpos\endcsname + \fontdimen5\font\U@D #1% + \egroup} % \end{macrocode} % -% The following package options control the behavior of |\SetString|. +% \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). % % \begin{macrocode} -%<<*More package options>> -\let\bbl@opt@strings\@nnil % accept strings=value -\DeclareOption{strings}{\def\bbl@opt@strings{\BabelStringsDefault}} -\DeclareOption{strings=encoded}{\let\bbl@opt@strings\relax} -\def\BabelStringsDefault{generic} -%<> +\AtBeginDocument{% + \DeclareTextCompositeCommand{\"}{OT1}{a}{\bbl@umlauta{a}}% + \DeclareTextCompositeCommand{\"}{OT1}{e}{\bbl@umlaute{e}}% + \DeclareTextCompositeCommand{\"}{OT1}{i}{\bbl@umlaute{\i}}% + \DeclareTextCompositeCommand{\"}{OT1}{\i}{\bbl@umlaute{\i}}% + \DeclareTextCompositeCommand{\"}{OT1}{o}{\bbl@umlauta{o}}% + \DeclareTextCompositeCommand{\"}{OT1}{u}{\bbl@umlauta{u}}% + \DeclareTextCompositeCommand{\"}{OT1}{A}{\bbl@umlauta{A}}% + \DeclareTextCompositeCommand{\"}{OT1}{E}{\bbl@umlaute{E}}% + \DeclareTextCompositeCommand{\"}{OT1}{I}{\bbl@umlaute{I}}% + \DeclareTextCompositeCommand{\"}{OT1}{O}{\bbl@umlauta{O}}% + \DeclareTextCompositeCommand{\"}{OT1}{U}{\bbl@umlauta{U}}} % \end{macrocode} % -% \paragraph{Main command} This is the main command. With the first -% use it is redefined to omit the basic setup in subsequent blocks. -% We make sure strings contain actual letters in the range 128-255, -% not active characters. +% Finally, make sure the default hyphenrules are defined (even if +% empty). For internal use, another empty |\language| is defined. +% Currently used in Amharic. % % \begin{macrocode} -\@onlypreamble\StartBabelCommands -\def\StartBabelCommands{% - \begingroup - \bbl@recatcode{11}% - <@Macros local to BabelCommands@> - \def\bbl@provstring##1##2{% - \providecommand##1{##2}% - \bbl@toglobal##1}% - \global\let\bbl@scafter\@empty - \let\StartBabelCommands\bbl@startcmds - \ifx\BabelLanguages\relax - \let\BabelLanguages\CurrentOption - \fi - \begingroup - \let\bbl@screset\@nnil % local flag - disable 1st stopcommands - \StartBabelCommands} -\def\bbl@startcmds{% - \ifx\bbl@screset\@nnil\else - \bbl@usehooks{stopcommands}{}% - \fi - \endgroup - \begingroup - \@ifstar - {\ifx\bbl@opt@strings\@nnil - \let\bbl@opt@strings\BabelStringsDefault - \fi - \bbl@startcmds@i}% - \bbl@startcmds@i} -\def\bbl@startcmds@i#1#2{% - \edef\bbl@L{\zap@space#1 \@empty}% - \edef\bbl@G{\zap@space#2 \@empty}% - \bbl@startcmds@ii} -\let\bbl@startcommands\StartBabelCommands +\ifx\l@english\@undefined + \chardef\l@english\z@ +\fi +% The following is used to cancel rules in ini files (see Amharic). +\ifx\l@unhyphenated\@undefined + \newlanguage\l@unhyphenated +\fi % \end{macrocode} % -% Parse the encoding info to get the label, input, and font parts. -% -% Select the behavior of |\SetString|. Thre are two main cases, -% depending of if there is an optional argument: without it and -% |strings=encoded|, strings are defined -% always; otherwise, they are set only if they are still undefined -% (ie, fallback values). With labelled blocks and -% |strings=encoded|, define the strings, but with another value, -% define strings only if the current label or font encoding is the -% value of |strings|; otherwise (ie, no |strings| or a block whose -% label is not in |strings=|) do nothing. +% \subsection{Layout} % -% We presume the current block is not loaded, and therefore set -% (above) a couple of default values to gobble the arguments. Then, -% these macros are redefined if necessary according to several -% parameters. +% Layout is mainly intended to set bidi documents, but there is at +% least a tool useful in general. % % \begin{macrocode} -\newcommand\bbl@startcmds@ii[1][\@empty]{% - \let\SetString\@gobbletwo - \let\bbl@stringdef\@gobbletwo - \let\AfterBabelCommands\@gobble - \ifx\@empty#1% - \def\bbl@sc@label{generic}% - \def\bbl@encstring##1##2{% - \ProvideTextCommandDefault##1{##2}% - \bbl@toglobal##1% - \expandafter\bbl@toglobal\csname\string?\string##1\endcsname}% - \let\bbl@sctest\in@true - \else - \let\bbl@sc@charset\space % <- zapped below - \let\bbl@sc@fontenc\space % <- " " - \def\bbl@tempa##1=##2\@nil{% - \bbl@csarg\edef{sc@\zap@space##1 \@empty}{##2 }}% - \bbl@vforeach{label=#1}{\bbl@tempa##1\@nil}% - \def\bbl@tempa##1 ##2{% space -> comma - ##1% - \ifx\@empty##2\else\ifx,##1,\else,\fi\bbl@afterfi\bbl@tempa##2\fi}% - \edef\bbl@sc@fontenc{\expandafter\bbl@tempa\bbl@sc@fontenc\@empty}% - \edef\bbl@sc@label{\expandafter\zap@space\bbl@sc@label\@empty}% - \edef\bbl@sc@charset{\expandafter\zap@space\bbl@sc@charset\@empty}% - \def\bbl@encstring##1##2{% - \bbl@foreach\bbl@sc@fontenc{% - \bbl@ifunset{T@####1}% - {}% - {\ProvideTextCommand##1{####1}{##2}% - \bbl@toglobal##1% - \expandafter - \bbl@toglobal\csname####1\string##1\endcsname}}}% - \def\bbl@sctest{% - \bbl@xin@{,\bbl@opt@strings,}{,\bbl@sc@label,\bbl@sc@fontenc,}}% - \fi - \ifx\bbl@opt@strings\@nnil % ie, no strings key -> defaults - \else\ifx\bbl@opt@strings\relax % ie, strings=encoded - \let\AfterBabelCommands\bbl@aftercmds - \let\SetString\bbl@setstring - \let\bbl@stringdef\bbl@encstring - \else % ie, strings=value - \bbl@sctest - \ifin@ - \let\AfterBabelCommands\bbl@aftercmds - \let\SetString\bbl@setstring - \let\bbl@stringdef\bbl@provstring - \fi\fi\fi - \bbl@scswitch - \ifx\bbl@G\@empty - \def\SetString##1##2{% - \bbl@error{Missing group for string \string##1}% - {You must assign strings to some category, typically\\% - captions or extras, but you set none}}% - \fi - \ifx\@empty#1% - \bbl@usehooks{defaultcommands}{}% - \else - \@expandtwoargs - \bbl@usehooks{encodedcommands}{{\bbl@sc@charset}{\bbl@sc@fontenc}}% - \fi} -% \end{macrocode} -% -% There are two versions of |\bbl@scswitch|. The first version is used -% when |ldf|s are read, and it makes sure |\|\m{group}\m{language} is -% reset, but only once (|\bbl@screset| is used to keep track of this). -% The second version is used in the preamble and packages loaded after -% \babel{} and does nothing. -% -% The macro |\bbl@forlang| loops |\bbl@L| but its body is executed only -% if the value is in |\BabelLanguages| (inside \babel) or -% |\date|\m{language} is defined (after \babel{} has been loaded). -% There are also two version of |\bbl@forlang|. The first one skips the -% current iteration if the language is not in |\BabelLanguages| (used -% in |ldf|s), and the second one skips undefined languages (after -% \babel{} has been loaded) . -% -% \begin{macrocode} -\def\bbl@forlang#1#2{% - \bbl@for#1\bbl@L{% - \bbl@xin@{,#1,}{,\BabelLanguages,}% - \ifin@#2\relax\fi}} -\def\bbl@scswitch{% - \bbl@forlang\bbl@tempa{% - \ifx\bbl@G\@empty\else - \ifx\SetString\@gobbletwo\else - \edef\bbl@GL{\bbl@G\bbl@tempa}% - \bbl@xin@{,\bbl@GL,}{,\bbl@screset,}% - \ifin@\else - \global\expandafter\let\csname\bbl@GL\endcsname\@undefined - \xdef\bbl@screset{\bbl@screset,\bbl@GL}% - \fi - \fi - \fi}} -\AtEndOfPackage{% - \def\bbl@forlang#1#2{\bbl@for#1\bbl@L{\bbl@ifunset{date#1}{}{#2}}}% - \let\bbl@scswitch\relax} -\@onlypreamble\EndBabelCommands -\def\EndBabelCommands{% - \bbl@usehooks{stopcommands}{}% - \endgroup - \endgroup - \bbl@scafter} -\let\bbl@endcommands\EndBabelCommands -% \end{macrocode} -% -% Now we define commands to be used inside |\StartBabelCommands|. -% -% \paragraph{Strings} The following macro is the actual definition -% of |\SetString| when it is ``active'' -% -% First save the ``switcher''. Create it if undefined. Strings are -% defined only if undefined (ie, like |\providescommmand|). With -% the event |stringprocess| you can preprocess the string by -% manipulating the value of |\BabelString|. If there are several -% hooks assigned to this event, preprocessing is done in the same -% order as defined. Finally, the string is set. -% -% \begin{macrocode} -\def\bbl@setstring#1#2{% eg, \prefacename{} - \bbl@forlang\bbl@tempa{% - \edef\bbl@LC{\bbl@tempa\bbl@stripslash#1}% - \bbl@ifunset{\bbl@LC}% eg, \germanchaptername - {\bbl@exp{% - \global\\\bbl@add\<\bbl@G\bbl@tempa>{\\\bbl@scset\\#1\<\bbl@LC>}}}% - {}% - \def\BabelString{#2}% - \bbl@usehooks{stringprocess}{}% - \expandafter\bbl@stringdef - \csname\bbl@LC\expandafter\endcsname\expandafter{\BabelString}}} +\bbl@trace{Bidi layout} +\providecommand\IfBabelLayout[3]{#3}% +\newcommand\BabelPatchSection[1]{% + \@ifundefined{#1}{}{% + \bbl@exp{\let\\<#1>}% + \@namedef{#1}{% + \@ifstar{\bbl@presec@s{#1}}% + {\@dblarg{\bbl@presec@x{#1}}}}}} +\def\bbl@presec@x#1[#2]#3{% + \bbl@exp{% + \\\select@language@x{\bbl@main@language}% + \\\bbl@cs{sspre@#1}% + \\\bbl@cs{ss@#1}% + [\\\foreignlanguage{\languagename}{\unexpanded{#2}}]% + {\\\foreignlanguage{\languagename}{\unexpanded{#3}}}% + \\\select@language@x{\languagename}}} +\def\bbl@presec@s#1#2{% + \bbl@exp{% + \\\select@language@x{\bbl@main@language}% + \\\bbl@cs{sspre@#1}% + \\\bbl@cs{ss@#1}*% + {\\\foreignlanguage{\languagename}{\unexpanded{#2}}}% + \\\select@language@x{\languagename}}} +\IfBabelLayout{sectioning}% + {\BabelPatchSection{part}% + \BabelPatchSection{chapter}% + \BabelPatchSection{section}% + \BabelPatchSection{subsection}% + \BabelPatchSection{subsubsection}% + \BabelPatchSection{paragraph}% + \BabelPatchSection{subparagraph}% + \def\babel@toc#1{% + \select@language@x{\bbl@main@language}}}{} +\IfBabelLayout{captions}% + {\BabelPatchSection{caption}}{} % \end{macrocode} % -% Now, some addtional stuff to be used when encoded strings are -% used. Captions then include |\bbl@encoded| for string to be -% expanded in case transformations. It is |\relax| by default, but -% in |\MakeUppercase| and |\MakeLowercase| its value is a modified -% expandable |\@changed@cmd|. +% \subsection{Load engine specific macros} % % \begin{macrocode} -\ifx\bbl@opt@strings\relax - \def\bbl@scset#1#2{\def#1{\bbl@encoded#2}} - \bbl@patchuclc - \let\bbl@encoded\relax - \def\bbl@encoded@uclc#1{% - \@inmathwarn#1% - \expandafter\ifx\csname\cf@encoding\string#1\endcsname\relax - \expandafter\ifx\csname ?\string#1\endcsname\relax - \TextSymbolUnavailable#1% - \else - \csname ?\string#1\endcsname - \fi - \else - \csname\cf@encoding\string#1\endcsname - \fi} -\else - \def\bbl@scset#1#2{\def#1{#2}} +\bbl@trace{Input engine specific macros} +\ifcase\bbl@engine + \input txtbabel.def +\or + \input luababel.def +\or + \input xebabel.def \fi % \end{macrocode} % -% Define |\SetStringLoop|, which is actually set inside -% |\StartBabelCommands|. The current definition is somewhat complicated -% because we need a count, but |\count@| is not under our control -% (remember |\SetString| may call hooks). Instead of defining a -% dedicated count, we just ``pre-expand'' its value. -% -% \begin{macrocode} -%<<*Macros local to BabelCommands>> -\def\SetStringLoop##1##2{% - \def\bbl@templ####1{\expandafter\noexpand\csname##1\endcsname}% - \count@\z@ - \bbl@loop\bbl@tempa{##2}{% empty items and spaces are ok - \advance\count@\@ne - \toks@\expandafter{\bbl@tempa}% - \bbl@exp{% - \\\SetString\bbl@templ{\romannumeral\count@}{\the\toks@}% - \count@=\the\count@\relax}}}% -%<> -% \end{macrocode} -% -% \paragraph{Delaying code} Now the definition of |\AfterBabelCommands| -% when it is activated. -% -% \begin{macrocode} -\def\bbl@aftercmds#1{% - \toks@\expandafter{\bbl@scafter#1}% - \xdef\bbl@scafter{\the\toks@}} -% \end{macrocode} -% -% \paragraph{Case mapping} -% -% The command |\SetCase| provides a way to change the behavior of -% |\MakeUppercase| and |\MakeLowercase|. |\bbl@tempa| is set by the -% patched |\@uclclist| to the parsing command. -% -% \begin{macrocode} -%<<*Macros local to BabelCommands>> - \newcommand\SetCase[3][]{% - \bbl@patchuclc - \bbl@forlang\bbl@tempa{% - \expandafter\bbl@encstring - \csname\bbl@tempa @bbl@uclc\endcsname{\bbl@tempa##1}% - \expandafter\bbl@encstring - \csname\bbl@tempa @bbl@uc\endcsname{##2}% - \expandafter\bbl@encstring - \csname\bbl@tempa @bbl@lc\endcsname{##3}}}% -%<> -% \end{macrocode} +% \subsection{Creating and modifying languages} % -% Macros to deal with case mapping for hyphenation. To decide if the -% document is monolingual or multilingual, we make a rough guess -- -% just see if there is a comma in the languages list, built in the -% first pass of the package options. +% |\babelprovide| is a general purpose tool for creating and modifying +% languages. It creates the language infrastructure, and loads, if +% requested, an |ini| file. It may be used in conjunction to previouly +% loaded |ldf| files. % % \begin{macrocode} -%<<*Macros local to BabelCommands>> - \newcommand\SetHyphenMap[1]{% - \bbl@forlang\bbl@tempa{% - \expandafter\bbl@stringdef - \csname\bbl@tempa @bbl@hyphenmap\endcsname{##1}}}% -%<> -% \end{macrocode} -% -% There are 3 helper macros which do most of the work for you. -% -% \begin{macrocode} -\newcommand\BabelLower[2]{% one to one. - \ifnum\lccode#1=#2\else - \babel@savevariable{\lccode#1}% - \lccode#1=#2\relax - \fi} -\newcommand\BabelLowerMM[4]{% many-to-many - \@tempcnta=#1\relax - \@tempcntb=#4\relax - \def\bbl@tempa{% - \ifnum\@tempcnta>#2\else - \@expandtwoargs\BabelLower{\the\@tempcnta}{\the\@tempcntb}% - \advance\@tempcnta#3\relax - \advance\@tempcntb#3\relax - \expandafter\bbl@tempa - \fi}% - \bbl@tempa} -\newcommand\BabelLowerMO[4]{% many-to-one - \@tempcnta=#1\relax - \def\bbl@tempa{% - \ifnum\@tempcnta>#2\else - \@expandtwoargs\BabelLower{\the\@tempcnta}{#4}% - \advance\@tempcnta#3 - \expandafter\bbl@tempa +\bbl@trace{Creating languages and reading ini files} +\let\bbl@extend@ini\@gobble +\newcommand\babelprovide[2][]{% + \let\bbl@savelangname\languagename + \edef\bbl@savelocaleid{\the\localeid}% + % Set name and locale id + \edef\languagename{#2}% + \bbl@id@assign + % Initialize keys + \let\bbl@KVP@captions\@nil + \let\bbl@KVP@date\@nil + \let\bbl@KVP@import\@nil + \let\bbl@KVP@main\@nil + \let\bbl@KVP@script\@nil + \let\bbl@KVP@language\@nil + \let\bbl@KVP@hyphenrules\@nil + \let\bbl@KVP@linebreaking\@nil + \let\bbl@KVP@justification\@nil + \let\bbl@KVP@mapfont\@nil + \let\bbl@KVP@maparabic\@nil + \let\bbl@KVP@mapdigits\@nil + \let\bbl@KVP@intraspace\@nil + \let\bbl@KVP@intrapenalty\@nil + \let\bbl@KVP@onchar\@nil + \let\bbl@KVP@transforms\@nil + \global\let\bbl@release@transforms\@empty + \let\bbl@KVP@alph\@nil + \let\bbl@KVP@Alph\@nil + \let\bbl@KVP@labels\@nil + \bbl@csarg\let{KVP@labels*}\@nil + \global\let\bbl@inidata\@empty + \global\let\bbl@extend@ini\@gobble + \gdef\bbl@key@list{;}% + \bbl@forkv{#1}{% TODO - error handling + \in@{/}{##1}% + \ifin@ + \global\let\bbl@extend@ini\bbl@extend@ini@aux + \bbl@renewinikey##1\@@{##2}% + \else + \bbl@csarg\def{KVP@##1}{##2}% \fi}% - \bbl@tempa} -% \end{macrocode} -% -% The following package options control the behavior of -% hyphenation mapping. -% -% \begin{macrocode} -%<<*More package options>> -\DeclareOption{hyphenmap=off}{\chardef\bbl@opt@hyphenmap\z@} -\DeclareOption{hyphenmap=first}{\chardef\bbl@opt@hyphenmap\@ne} -\DeclareOption{hyphenmap=select}{\chardef\bbl@opt@hyphenmap\tw@} -\DeclareOption{hyphenmap=other}{\chardef\bbl@opt@hyphenmap\thr@@} -\DeclareOption{hyphenmap=other*}{\chardef\bbl@opt@hyphenmap4\relax} -%<> -% \end{macrocode} -% -% Initial setup to provide a default behavior if |hypenmap| -% is not set. -% -% \begin{macrocode} -\AtEndOfPackage{% - \ifx\bbl@opt@hyphenmap\@undefined - \bbl@xin@{,}{\bbl@language@opts}% - \chardef\bbl@opt@hyphenmap\ifin@4\else\@ne\fi - \fi} -% \end{macrocode} -% -% This sections ends with a general tool for resetting the caption -% names with a unique interface. With the old way, which mixes the -% switcher and the string, we convert it to the new one, which -% separates these two steps. -% -% \begin{macrocode} -\newcommand\setlocalecaption{% TODO. Catch typos. What about ensure? - \@ifstar\bbl@setcaption@s\bbl@setcaption@x} -\def\bbl@setcaption@x#1#2#3{% language caption-name string - \bbl@trim@def\bbl@tempa{#2}% - \bbl@xin@{.template}{\bbl@tempa}% - \ifin@ - \bbl@ini@captions@template{#3}{#1}% + \chardef\bbl@howloaded=% 0:none; 1:ldf without ini; 2:ini + \bbl@ifunset{date#2}\z@{\bbl@ifunset{bbl@llevel@#2}\@ne\tw@}% + % == init == + \ifx\bbl@screset\@undefined + \bbl@ldfinit + \fi + % == + \let\bbl@lbkflag\relax % \@empty = do setup linebreak + \ifcase\bbl@howloaded + \let\bbl@lbkflag\@empty % new \else - \edef\bbl@tempd{% - \expandafter\expandafter\expandafter - \strip@prefix\expandafter\meaning\csname captions#1\endcsname}% - \bbl@xin@ - {\expandafter\string\csname #2name\endcsname}% - {\bbl@tempd}% - \ifin@ % Renew caption - \bbl@xin@{\string\bbl@scset}{\bbl@tempd}% - \ifin@ - \bbl@exp{% - \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% - {\\\bbl@scset\<#2name>\<#1#2name>}% - {}}% - \else % Old way converts to new way - \bbl@ifunset{#1#2name}% - {\bbl@exp{% - \\\bbl@add\{\def\<#2name>{\<#1#2name>}}% - \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% - {\def\<#2name>{\<#1#2name>}}% - {}}}% - {}% - \fi - \else - \bbl@xin@{\string\bbl@scset}{\bbl@tempd}% New - \ifin@ % New way - \bbl@exp{% - \\\bbl@add\{\\\bbl@scset\<#2name>\<#1#2name>}% - \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% - {\\\bbl@scset\<#2name>\<#1#2name>}% - {}}% - \else % Old way, but defined in the new way - \bbl@exp{% - \\\bbl@add\{\def\<#2name>{\<#1#2name>}}% - \\\bbl@ifsamestring{\bbl@tempa}{\languagename}% - {\def\<#2name>{\<#1#2name>}}% - {}}% - \fi% + \ifx\bbl@KVP@hyphenrules\@nil\else + \let\bbl@lbkflag\@empty \fi - \@namedef{#1#2name}{#3}% - \toks@\expandafter{\bbl@captionslist}% - \bbl@exp{\\\in@{\<#2name>}{\the\toks@}}% - \ifin@\else - \bbl@exp{\\\bbl@add\\\bbl@captionslist{\<#2name>}}% - \bbl@toglobal\bbl@captionslist + \ifx\bbl@KVP@import\@nil\else + \let\bbl@lbkflag\@empty \fi - \fi} -% \def\bbl@setcaption@s#1#2#3{} % TODO. Not yet implemented -% \end{macrocode} -% -% \subsection{Macros common to a number of languages} -% -% \begin{macro}{\set@low@box} -% -% The following macro is used to lower quotes to the same level as -% the comma. It prepares its argument in box register~0. -% -% \begin{macrocode} -\bbl@trace{Macros related to glyphs} -\def\set@low@box#1{\setbox\tw@\hbox{,}\setbox\z@\hbox{#1}% - \dimen\z@\ht\z@ \advance\dimen\z@ -\ht\tw@% - \setbox\z@\hbox{\lower\dimen\z@ \box\z@}\ht\z@\ht\tw@ \dp\z@\dp\tw@} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\save@sf@q} -% The macro |\save@sf@q| is used to save and reset the current -% space factor. -% -% \begin{macrocode} -\def\save@sf@q#1{\leavevmode - \begingroup - \edef\@SF{\spacefactor\the\spacefactor}#1\@SF - \endgroup} -% \end{macrocode} -% -% \end{macro} -% -% \subsection{Making glyphs available} -% -% This section makes a number of glyphs available that either do not -% exist in the \texttt{OT1} encoding and have to be `faked', or -% that are not accessible through \file{T1enc.def}. -% -% \subsubsection{Quotation marks} -% -% \begin{macro}{\quotedblbase} -% In the \texttt{T1} encoding the opening double quote at the -% baseline is available as a separate character, accessible via -% |\quotedblbase|. In the \texttt{OT1} encoding it is not -% available, therefore we make it available by lowering the normal -% open quote character to the baseline. -% -% \begin{macrocode} -\ProvideTextCommand{\quotedblbase}{OT1}{% - \save@sf@q{\set@low@box{\textquotedblright\/}% - \box\z@\kern-.04em\bbl@allowhyphens}} -% \end{macrocode} -% -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used this glyph can still be typeset. -% -% \begin{macrocode} -\ProvideTextCommandDefault{\quotedblbase}{% - \UseTextSymbol{OT1}{\quotedblbase}} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\quotesinglbase} -% We also need the single quote character at the baseline. -% -% \begin{macrocode} -\ProvideTextCommand{\quotesinglbase}{OT1}{% - \save@sf@q{\set@low@box{\textquoteright\/}% - \box\z@\kern-.04em\bbl@allowhyphens}} -% \end{macrocode} -% -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used this glyph can still be typeset. -% -% \begin{macrocode} -\ProvideTextCommandDefault{\quotesinglbase}{% - \UseTextSymbol{OT1}{\quotesinglbase}} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\guillemetleft} -% \begin{macro}{\guillemetright} -% The guillemet characters are not available in \texttt{OT1} -% encoding. They are faked. (Wrong names with o preserved for -% compatibility.) -% -% \begin{macrocode} -\ProvideTextCommand{\guillemetleft}{OT1}{% - \ifmmode - \ll - \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle\ll$}\bbl@allowhyphens}% - \fi} -\ProvideTextCommand{\guillemetright}{OT1}{% - \ifmmode - \gg - \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle\gg$}\bbl@allowhyphens}% - \fi} -\ProvideTextCommand{\guillemotleft}{OT1}{% - \ifmmode - \ll - \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle\ll$}\bbl@allowhyphens}% - \fi} -\ProvideTextCommand{\guillemotright}{OT1}{% - \ifmmode - \gg - \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle\gg$}\bbl@allowhyphens}% - \fi} -% \end{macrocode} -% -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used these glyphs can still be typeset. -% -% \begin{macrocode} -\ProvideTextCommandDefault{\guillemetleft}{% - \UseTextSymbol{OT1}{\guillemetleft}} -\ProvideTextCommandDefault{\guillemetright}{% - \UseTextSymbol{OT1}{\guillemetright}} -\ProvideTextCommandDefault{\guillemotleft}{% - \UseTextSymbol{OT1}{\guillemotleft}} -\ProvideTextCommandDefault{\guillemotright}{% - \UseTextSymbol{OT1}{\guillemotright}} -% \end{macrocode} -% -% \end{macro} -% \end{macro} -% -% \begin{macro}{\guilsinglleft} -% \begin{macro}{\guilsinglright} -% The single guillemets are not available in \texttt{OT1} -% encoding. They are faked. -% -% \begin{macrocode} -\ProvideTextCommand{\guilsinglleft}{OT1}{% - \ifmmode - <% - \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle<$}\bbl@allowhyphens}% - \fi} -\ProvideTextCommand{\guilsinglright}{OT1}{% - \ifmmode - >% + \fi + % == import, captions == + \ifx\bbl@KVP@import\@nil\else + \bbl@exp{\\\bbl@ifblank{\bbl@KVP@import}}% + {\ifx\bbl@initoload\relax + \begingroup + \def\BabelBeforeIni##1##2{\gdef\bbl@KVP@import{##1}\endinput}% + \bbl@input@texini{#2}% + \endgroup + \else + \xdef\bbl@KVP@import{\bbl@initoload}% + \fi}% + {}% + \fi + \ifx\bbl@KVP@captions\@nil + \let\bbl@KVP@captions\bbl@KVP@import + \fi + % == + \ifx\bbl@KVP@transforms\@nil\else + \bbl@replace\bbl@KVP@transforms{ }{,}% + \fi + % == Load ini == + \ifcase\bbl@howloaded + \bbl@provide@new{#2}% \else - \save@sf@q{\nobreak - \raise.2ex\hbox{$\scriptscriptstyle>$}\bbl@allowhyphens}% + \bbl@ifblank{#1}% + {}% With \bbl@load@basic below + {\bbl@provide@renew{#2}}% + \fi + % Post tasks + % ---------- + % == subsequent calls after the first provide for a locale == + \ifx\bbl@inidata\@empty\else + \bbl@extend@ini{#2}% + \fi + % == ensure captions == + \ifx\bbl@KVP@captions\@nil\else + \bbl@ifunset{bbl@extracaps@#2}% + {\bbl@exp{\\\babelensure[exclude=\\\today]{#2}}}% + {\bbl@exp{\\\babelensure[exclude=\\\today, + include=\[bbl@extracaps@#2]}]{#2}}% + \bbl@ifunset{bbl@ensure@\languagename}% + {\bbl@exp{% + \\\DeclareRobustCommand\[1]{% + \\\foreignlanguage{\languagename}% + {####1}}}}% + {}% + \bbl@exp{% + \\\bbl@toglobal\% + \\\bbl@toglobal\}% + \fi + % == + % At this point all parameters are defined if 'import'. Now we + % execute some code depending on them. But what about if nothing was + % imported? We just set the basic parameters, but still loading the + % whole ini file. + \bbl@load@basic{#2}% + % == script, language == + % Override the values from ini or defines them + \ifx\bbl@KVP@script\@nil\else + \bbl@csarg\edef{sname@#2}{\bbl@KVP@script}% + \fi + \ifx\bbl@KVP@language\@nil\else + \bbl@csarg\edef{lname@#2}{\bbl@KVP@language}% + \fi + % == onchar == + \ifx\bbl@KVP@onchar\@nil\else + \bbl@luahyphenate + \directlua{ + if Babel.locale_mapped == nil then + Babel.locale_mapped = true + Babel.linebreaking.add_before(Babel.locale_map) + Babel.loc_to_scr = {} + Babel.chr_to_loc = Babel.chr_to_loc or {} + end}% + \bbl@xin@{ ids }{ \bbl@KVP@onchar\space}% + \ifin@ + \ifx\bbl@starthyphens\@undefined % Needed if no explicit selection + \AddBabelHook{babel-onchar}{beforestart}{{\bbl@starthyphens}}% + \fi + \bbl@exp{\\\bbl@add\\\bbl@starthyphens + {\\\bbl@patterns@lua{\languagename}}}% + % TODO - error/warning if no script + \directlua{ + if Babel.script_blocks['\bbl@cl{sbcp}'] then + Babel.loc_to_scr[\the\localeid] = + Babel.script_blocks['\bbl@cl{sbcp}'] + Babel.locale_props[\the\localeid].lc = \the\localeid\space + Babel.locale_props[\the\localeid].lg = \the\@nameuse{l@\languagename}\space + end + }% + \fi + \bbl@xin@{ fonts }{ \bbl@KVP@onchar\space}% + \ifin@ + \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% + \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% + \directlua{ + if Babel.script_blocks['\bbl@cl{sbcp}'] then + Babel.loc_to_scr[\the\localeid] = + Babel.script_blocks['\bbl@cl{sbcp}'] + end}% + \ifx\bbl@mapselect\@undefined % TODO. almost the same as mapfont + \AtBeginDocument{% + \bbl@patchfont{{\bbl@mapselect}}% + {\selectfont}}% + \def\bbl@mapselect{% + \let\bbl@mapselect\relax + \edef\bbl@prefontid{\fontid\font}}% + \def\bbl@mapdir##1{% + {\def\languagename{##1}% + \let\bbl@ifrestoring\@firstoftwo % To avoid font warning + \bbl@switchfont + \directlua{ + Babel.locale_props[\the\csname bbl@id@@##1\endcsname]% + ['/\bbl@prefontid'] = \fontid\font\space}}}% + \fi + \bbl@exp{\\\bbl@add\\\bbl@mapselect{\\\bbl@mapdir{\languagename}}}% + \fi + % TODO - catch non-valid values + \fi + % == mapfont == + % For bidi texts, to switch the font based on direction + \ifx\bbl@KVP@mapfont\@nil\else + \bbl@ifsamestring{\bbl@KVP@mapfont}{direction}{}% + {\bbl@error{Option '\bbl@KVP@mapfont' unknown for\\% + mapfont. Use 'direction'.% + {See the manual for details.}}}% + \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% + \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% + \ifx\bbl@mapselect\@undefined % TODO. See onchar. + \AtBeginDocument{% + \bbl@patchfont{{\bbl@mapselect}}% + {\selectfont}}% + \def\bbl@mapselect{% + \let\bbl@mapselect\relax + \edef\bbl@prefontid{\fontid\font}}% + \def\bbl@mapdir##1{% + {\def\languagename{##1}% + \let\bbl@ifrestoring\@firstoftwo % avoid font warning + \bbl@switchfont + \directlua{Babel.fontmap + [\the\csname bbl@wdir@##1\endcsname]% + [\bbl@prefontid]=\fontid\font}}}% + \fi + \bbl@exp{\\\bbl@add\\\bbl@mapselect{\\\bbl@mapdir{\languagename}}}% + \fi + % == Line breaking: intraspace, intrapenalty == + % For CJK, East Asian, Southeast Asian, if interspace in ini + \ifx\bbl@KVP@intraspace\@nil\else % We can override the ini or set + \bbl@csarg\edef{intsp@#2}{\bbl@KVP@intraspace}% + \fi + \bbl@provide@intraspace + % == Line breaking: CJK quotes == + \ifcase\bbl@engine\or + \bbl@xin@{/c}{/\bbl@cl{lnbrk}}% + \ifin@ + \bbl@ifunset{bbl@quote@\languagename}{}% + {\directlua{ + Babel.locale_props[\the\localeid].cjk_quotes = {} + local cs = 'op' + for c in string.utfvalues(% + [[\csname bbl@quote@\languagename\endcsname]]) do + if Babel.cjk_characters[c].c == 'qu' then + Babel.locale_props[\the\localeid].cjk_quotes[c] = cs + end + cs = ( cs == 'op') and 'cl' or 'op' + end + }}% + \fi + \fi + % == Line breaking: justification == + \ifx\bbl@KVP@justification\@nil\else + \let\bbl@KVP@linebreaking\bbl@KVP@justification + \fi + \ifx\bbl@KVP@linebreaking\@nil\else + \bbl@xin@{,\bbl@KVP@linebreaking,}{,elongated,kashida,cjk,unhyphenated,}% + \ifin@ + \bbl@csarg\xdef + {lnbrk@\languagename}{\expandafter\@car\bbl@KVP@linebreaking\@nil}% + \fi + \fi + \bbl@xin@{/e}{/\bbl@cl{lnbrk}}% + \ifin@\else\bbl@xin@{/k}{/\bbl@cl{lnbrk}}\fi + \ifin@\bbl@arabicjust\fi + % == Line breaking: hyphenate.other.(locale|script) == + \ifx\bbl@lbkflag\@empty + \bbl@ifunset{bbl@hyotl@\languagename}{}% + {\bbl@csarg\bbl@replace{hyotl@\languagename}{ }{,}% + \bbl@startcommands*{\languagename}{}% + \bbl@csarg\bbl@foreach{hyotl@\languagename}{% + \ifcase\bbl@engine + \ifnum##1<257 + \SetHyphenMap{\BabelLower{##1}{##1}}% + \fi + \else + \SetHyphenMap{\BabelLower{##1}{##1}}% + \fi}% + \bbl@endcommands}% + \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}}% + \fi + % == Counters: maparabic == + % Native digits, if provided in ini (TeX level, xe and lua) + \ifcase\bbl@engine\else + \bbl@ifunset{bbl@dgnat@\languagename}{}% + {\expandafter\ifx\csname bbl@dgnat@\languagename\endcsname\@empty\else + \expandafter\expandafter\expandafter + \bbl@setdigits\csname bbl@dgnat@\languagename\endcsname + \ifx\bbl@KVP@maparabic\@nil\else + \ifx\bbl@latinarabic\@undefined + \expandafter\let\expandafter\@arabic + \csname bbl@counter@\languagename\endcsname + \else % ie, if layout=counters, which redefines \@arabic + \expandafter\let\expandafter\bbl@latinarabic + \csname bbl@counter@\languagename\endcsname + \fi + \fi + \fi}% + \fi + % == Counters: mapdigits == + % Native digits (lua level). + \ifodd\bbl@engine + \ifx\bbl@KVP@mapdigits\@nil\else + \bbl@ifunset{bbl@dgnat@\languagename}{}% + {\RequirePackage{luatexbase}% + \bbl@activate@preotf + \directlua{ + Babel = Babel or {} %%% -> presets in luababel + Babel.digits_mapped = true + Babel.digits = Babel.digits or {} + Babel.digits[\the\localeid] = + table.pack(string.utfvalue('\bbl@cl{dgnat}')) + if not Babel.numbers then + function Babel.numbers(head) + local LOCALE = Babel.attr_locale + local GLYPH = node.id'glyph' + local inmath = false + for item in node.traverse(head) do + if not inmath and item.id == GLYPH then + local temp = node.get_attribute(item, LOCALE) + if Babel.digits[temp] then + local chr = item.char + if chr > 47 and chr < 58 then + item.char = Babel.digits[temp][chr-47] + end + end + elseif item.id == node.id'math' then + inmath = (item.subtype == 0) + end + end + return head + end + end + }}% + \fi + \fi + % == Counters: alph, Alph == + % What if extras contains a \babel@save\@alph? It won't be + % restored correctly when exiting the language, so we ignore + % this change with the \bbl@alph@saved trick. + \ifx\bbl@KVP@alph\@nil\else + \bbl@extras@wrap{\\\bbl@alph@saved}% + {\let\bbl@alph@saved\@alph}% + {\let\@alph\bbl@alph@saved + \babel@save\@alph}% + \bbl@exp{% + \\\bbl@add\{% + \let\\\@alph\}}% + \fi + \ifx\bbl@KVP@Alph\@nil\else + \bbl@extras@wrap{\\\bbl@Alph@saved}% + {\let\bbl@Alph@saved\@Alph}% + {\let\@Alph\bbl@Alph@saved + \babel@save\@Alph}% + \bbl@exp{% + \\\bbl@add\{% + \let\\\@Alph\}}% + \fi + % == require.babel in ini == + % To load or reaload the babel-*.tex, if require.babel in ini + \ifx\bbl@beforestart\relax\else % But not in doc aux or body + \bbl@ifunset{bbl@rqtex@\languagename}{}% + {\expandafter\ifx\csname bbl@rqtex@\languagename\endcsname\@empty\else + \let\BabelBeforeIni\@gobbletwo + \chardef\atcatcode=\catcode`\@ + \catcode`\@=11\relax + \bbl@input@texini{\bbl@cs{rqtex@\languagename}}% + \catcode`\@=\atcatcode + \let\atcatcode\relax + \global\bbl@csarg\let{rqtex@\languagename}\relax + \fi}% + \fi + % == frenchspacing == + \ifcase\bbl@howloaded\in@true\else\in@false\fi + \ifin@\else\bbl@xin@{typography/frenchspacing}{\bbl@key@list}\fi + \ifin@ + \bbl@extras@wrap{\\\bbl@pre@fs}% + {\bbl@pre@fs}% + {\bbl@post@fs}% + \fi + % == Release saved transforms == + \bbl@release@transforms\relax % \relax closes the last item. + % == main == + \ifx\bbl@KVP@main\@nil % Restore only if not 'main' + \let\languagename\bbl@savelangname + \chardef\localeid\bbl@savelocaleid\relax \fi} % \end{macrocode} % -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used these glyphs can still be typeset. +% Depending on whether or not the language exists (based on +% |\date|), we define two macros. Remember +% |\bbl@startcommands| opens a group. % % \begin{macrocode} -\ProvideTextCommandDefault{\guilsinglleft}{% - \UseTextSymbol{OT1}{\guilsinglleft}} -\ProvideTextCommandDefault{\guilsinglright}{% - \UseTextSymbol{OT1}{\guilsinglright}} -% \end{macrocode} -% -% \end{macro} -% \end{macro} -% -% \subsubsection{Letters} -% -% \begin{macro}{\ij} -% \begin{macro}{\IJ} -% The dutch language uses the letter `ij'. It is available in -% \texttt{T1} encoded fonts, but not in the \texttt{OT1} encoded -% fonts. Therefore we fake it for the \texttt{OT1} encoding. +\def\bbl@provide@new#1{% + \@namedef{date#1}{}% marks lang exists - required by \StartBabelCommands + \@namedef{extras#1}{}% + \@namedef{noextras#1}{}% + \bbl@startcommands*{#1}{captions}% + \ifx\bbl@KVP@captions\@nil % and also if import, implicit + \def\bbl@tempb##1{% elt for \bbl@captionslist + \ifx##1\@empty\else + \bbl@exp{% + \\\SetString\\##1{% + \\\bbl@nocaption{\bbl@stripslash##1}{#1\bbl@stripslash##1}}}% + \expandafter\bbl@tempb + \fi}% + \expandafter\bbl@tempb\bbl@captionslist\@empty + \else + \ifx\bbl@initoload\relax + \bbl@read@ini{\bbl@KVP@captions}2% % Here letters cat = 11 + \else + \bbl@read@ini{\bbl@initoload}2% % Same + \fi + \fi + \StartBabelCommands*{#1}{date}% + \ifx\bbl@KVP@import\@nil + \bbl@exp{% + \\\SetString\\\today{\\\bbl@nocaption{today}{#1today}}}% + \else + \bbl@savetoday + \bbl@savedate + \fi + \bbl@endcommands + \bbl@load@basic{#1}% + % == hyphenmins == (only if new) + \bbl@exp{% + \gdef\<#1hyphenmins>{% + {\bbl@ifunset{bbl@lfthm@#1}{2}{\bbl@cs{lfthm@#1}}}% + {\bbl@ifunset{bbl@rgthm@#1}{3}{\bbl@cs{rgthm@#1}}}}}% + % == hyphenrules (also in renew) == + \bbl@provide@hyphens{#1}% + \ifx\bbl@KVP@main\@nil\else + \expandafter\main@language\expandafter{#1}% + \fi} % -% \begin{macrocode} -\DeclareTextCommand{\ij}{OT1}{% - i\kern-0.02em\bbl@allowhyphens j} -\DeclareTextCommand{\IJ}{OT1}{% - I\kern-0.02em\bbl@allowhyphens J} -\DeclareTextCommand{\ij}{T1}{\char188} -\DeclareTextCommand{\IJ}{T1}{\char156} +\def\bbl@provide@renew#1{% + \ifx\bbl@KVP@captions\@nil\else + \StartBabelCommands*{#1}{captions}% + \bbl@read@ini{\bbl@KVP@captions}2% % Here all letters cat = 11 + \EndBabelCommands + \fi + \ifx\bbl@KVP@import\@nil\else + \StartBabelCommands*{#1}{date}% + \bbl@savetoday + \bbl@savedate + \EndBabelCommands + \fi + % == hyphenrules (also in new) == + \ifx\bbl@lbkflag\@empty + \bbl@provide@hyphens{#1}% + \fi} % \end{macrocode} % -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used these glyphs can still be typeset. +% Load the basic parameters (ids, typography, counters, and a few +% more), while captions and dates are left out. But it may happen some +% data has been loaded before automatically, so we first discard the +% saved values. (TODO. But preserving previous values would be useful.) % % \begin{macrocode} -\ProvideTextCommandDefault{\ij}{% - \UseTextSymbol{OT1}{\ij}} -\ProvideTextCommandDefault{\IJ}{% - \UseTextSymbol{OT1}{\IJ}} +\def\bbl@load@basic#1{% + \ifcase\bbl@howloaded\or\or + \ifcase\csname bbl@llevel@\languagename\endcsname + \bbl@csarg\let{lname@\languagename}\relax + \fi + \fi + \bbl@ifunset{bbl@lname@#1}% + {\def\BabelBeforeIni##1##2{% + \begingroup + \let\bbl@ini@captions@aux\@gobbletwo + \def\bbl@inidate ####1.####2.####3.####4\relax ####5####6{}% + \bbl@read@ini{##1}1% + \ifx\bbl@initoload\relax\endinput\fi + \endgroup}% + \begingroup % boxed, to avoid extra spaces: + \ifx\bbl@initoload\relax + \bbl@input@texini{#1}% + \else + \setbox\z@\hbox{\BabelBeforeIni{\bbl@initoload}{}}% + \fi + \endgroup}% + {}} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\dj} -% \begin{macro}{\DJ} -% The croatian language needs the letters |\dj| and |\DJ|; they are -% available in the \texttt{T1} encoding, but not in the -% \texttt{OT1} encoding by default. -% -% Some code to construct these glyphs for the \texttt{OT1} encoding -% was made available to me by Stipčević Mario, -% (\texttt{stipcevic@olimp.irb.hr}). +% The |hyphenrules| option is handled with an auxiliary macro. % % \begin{macrocode} -\def\crrtic@{\hrule height0.1ex width0.3em} -\def\crttic@{\hrule height0.1ex width0.33em} -\def\ddj@{% - \setbox0\hbox{d}\dimen@=\ht0 - \advance\dimen@1ex - \dimen@.45\dimen@ - \dimen@ii\expandafter\rem@pt\the\fontdimen\@ne\font\dimen@ - \advance\dimen@ii.5ex - \leavevmode\rlap{\raise\dimen@\hbox{\kern\dimen@ii\vbox{\crrtic@}}}} -\def\DDJ@{% - \setbox0\hbox{D}\dimen@=.55\ht0 - \dimen@ii\expandafter\rem@pt\the\fontdimen\@ne\font\dimen@ - \advance\dimen@ii.15ex % correction for the dash position - \advance\dimen@ii-.15\fontdimen7\font % correction for cmtt font - \dimen\thr@@\expandafter\rem@pt\the\fontdimen7\font\dimen@ - \leavevmode\rlap{\raise\dimen@\hbox{\kern\dimen@ii\vbox{\crttic@}}}} -% -\DeclareTextCommand{\dj}{OT1}{\ddj@ d} -\DeclareTextCommand{\DJ}{OT1}{\DDJ@ D} +\def\bbl@provide@hyphens#1{% + \let\bbl@tempa\relax + \ifx\bbl@KVP@hyphenrules\@nil\else + \bbl@replace\bbl@KVP@hyphenrules{ }{,}% + \bbl@foreach\bbl@KVP@hyphenrules{% + \ifx\bbl@tempa\relax % if not yet found + \bbl@ifsamestring{##1}{+}% + {{\bbl@exp{\\\addlanguage\}}}% + {}% + \bbl@ifunset{l@##1}% + {}% + {\bbl@exp{\let\bbl@tempa\}}% + \fi}% + \fi + \ifx\bbl@tempa\relax % if no opt or no language in opt found + \ifx\bbl@KVP@import\@nil + \ifx\bbl@initoload\relax\else + \bbl@exp{% and hyphenrules is not empty + \\\bbl@ifblank{\bbl@cs{hyphr@#1}}% + {}% + {\let\\\bbl@tempa\}}% + \fi + \else % if importing + \bbl@exp{% and hyphenrules is not empty + \\\bbl@ifblank{\bbl@cs{hyphr@#1}}% + {}% + {\let\\\bbl@tempa\}}% + \fi + \fi + \bbl@ifunset{bbl@tempa}% ie, relax or undefined + {\bbl@ifunset{l@#1}% no hyphenrules found - fallback + {\bbl@exp{\\\adddialect\\language}}% + {}}% so, l@ is ok - nothing to do + {\bbl@exp{\\\adddialect\\bbl@tempa}}}% found in opt list or ini % \end{macrocode} % -% Make sure that when an encoding other than \texttt{OT1} or -% \texttt{T1} is used these glyphs can still be typeset. +% The reader of |babel-...tex| files. We reset temporarily some +% catcodes. % % \begin{macrocode} -\ProvideTextCommandDefault{\dj}{% - \UseTextSymbol{OT1}{\dj}} -\ProvideTextCommandDefault{\DJ}{% - \UseTextSymbol{OT1}{\DJ}} +\def\bbl@input@texini#1{% + \bbl@bsphack + \bbl@exp{% + \catcode`\\\%=14 \catcode`\\\\=0 + \catcode`\\\{=1 \catcode`\\\}=2 + \lowercase{\\\InputIfFileExists{babel-#1.tex}{}{}}% + \catcode`\\\%=\the\catcode`\%\relax + \catcode`\\\\=\the\catcode`\\\relax + \catcode`\\\{=\the\catcode`\{\relax + \catcode`\\\}=\the\catcode`\}\relax}% + \bbl@esphack} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\SS} -% For the \texttt{T1} encoding |\SS| is defined and selects a -% specific glyph from the font, but for other encodings it is not -% available. Therefore we make it available here. +% The following macros read and store |ini| files (but don't process +% them). For each line, there are 3 possible actions: ignore if starts +% with |;|, switch section if starts with |[|, and store otherwise. +% There are used in the first step of |\bbl@read@ini|. % % \begin{macrocode} -\DeclareTextCommand{\SS}{OT1}{SS} -\ProvideTextCommandDefault{\SS}{\UseTextSymbol{OT1}{\SS}} +\def\bbl@iniline#1\bbl@iniline{% + \@ifnextchar[\bbl@inisect{\@ifnextchar;\bbl@iniskip\bbl@inistore}#1\@@}% ] +\def\bbl@inisect[#1]#2\@@{\def\bbl@section{#1}} +\def\bbl@iniskip#1\@@{}% if starts with ; +\def\bbl@inistore#1=#2\@@{% full (default) + \bbl@trim@def\bbl@tempa{#1}% + \bbl@trim\toks@{#2}% + \bbl@xin@{;\bbl@section/\bbl@tempa;}{\bbl@key@list}% + \ifin@\else + \bbl@exp{% + \\\g@addto@macro\\\bbl@inidata{% + \\\bbl@elt{\bbl@section}{\bbl@tempa}{\the\toks@}}}% + \fi} +\def\bbl@inistore@min#1=#2\@@{% minimal (maybe set in \bbl@read@ini) + \bbl@trim@def\bbl@tempa{#1}% + \bbl@trim\toks@{#2}% + \bbl@xin@{.identification.}{.\bbl@section.}% + \ifin@ + \bbl@exp{\\\g@addto@macro\\\bbl@inidata{% + \\\bbl@elt{identification}{\bbl@tempa}{\the\toks@}}}% + \fi} % \end{macrocode} % -% \end{macro} -% -% \subsubsection{Shorthands for quotation marks} -% -% Shorthands are provided for a number of different quotation -% marks, which make them usable both outside and inside mathmode. -% They are defined with |\ProvideTextCommandDefault|, but this is -% very likely not required because their definitions are based on -% encoding-dependent macros. +% Now, the ‘main loop’, which \textbf{**must be executed inside a +% group**}. At this point, |\bbl@inidata| may contain data declared in +% |\babelprovide|, with ‘slashed’ keys. There are 3 steps: first read +% the ini file and store it; then traverse the stored values, and +% process some groups if required (date, captions, labels, counters); +% finally, ‘export’ some values by defining global macros +% (identification, typography, characters, numbers). The second +% argument is 0 when called to read the minimal data for fonts; with +% |\babelprovide| it's either 1 or 2. % -% \begin{macro}{\glq} -% \begin{macro}{\grq} +% \begin{macrocode} +\ifx\bbl@readstream\@undefined + \csname newread\endcsname\bbl@readstream +\fi +\def\bbl@read@ini#1#2{% + \global\let\bbl@extend@ini\@gobble + \openin\bbl@readstream=babel-#1.ini + \ifeof\bbl@readstream + \bbl@error + {There is no ini file for the requested language\\% + (#1). Perhaps you misspelled it or your installation\\% + is not complete.}% + {Fix the name or reinstall babel.}% + \else + % == Store ini data in \bbl@inidata == + \catcode`\[=12 \catcode`\]=12 \catcode`\==12 \catcode`\&=12 + \catcode`\;=12 \catcode`\|=12 \catcode`\%=14 \catcode`\-=12 + \bbl@info{Importing + \ifcase#2font and identification \or basic \fi + data for \languagename\\% + from babel-#1.ini. Reported}% + \ifnum#2=\z@ + \global\let\bbl@inidata\@empty + \let\bbl@inistore\bbl@inistore@min % Remember it's local + \fi + \def\bbl@section{identification}% + \bbl@exp{\\\bbl@inistore tag.ini=#1\\\@@}% + \bbl@inistore load.level=#2\@@ + \loop + \if T\ifeof\bbl@readstream F\fi T\relax % Trick, because inside \loop + \endlinechar\m@ne + \read\bbl@readstream to \bbl@line + \endlinechar`\^^M + \ifx\bbl@line\@empty\else + \expandafter\bbl@iniline\bbl@line\bbl@iniline + \fi + \repeat + % == Process stored data == + \bbl@csarg\xdef{lini@\languagename}{#1}% + \bbl@read@ini@aux + % == 'Export' data == + \bbl@ini@exports{#2}% + \global\bbl@csarg\let{inidata@\languagename}\bbl@inidata + \global\let\bbl@inidata\@empty + \bbl@exp{\\\bbl@add@list\\\bbl@ini@loaded{\languagename}}% + \bbl@toglobal\bbl@ini@loaded + \fi} +\def\bbl@read@ini@aux{% + \let\bbl@savestrings\@empty + \let\bbl@savetoday\@empty + \let\bbl@savedate\@empty + \def\bbl@elt##1##2##3{% + \def\bbl@section{##1}% + \in@{=date.}{=##1}% Find a better place + \ifin@ + \bbl@ini@calendar{##1}% + \fi + \bbl@ifunset{bbl@inikv@##1}{}% + {\csname bbl@inikv@##1\endcsname{##2}{##3}}}% + \bbl@inidata} +% \end{macrocode} % -% The `german' single quotes. +% A variant to be used when the ini file has been already loaded, +% because it's not the first |\babelprovide| for this language. % % \begin{macrocode} -\ProvideTextCommandDefault{\glq}{% - \textormath{\quotesinglbase}{\mbox{\quotesinglbase}}} +\def\bbl@extend@ini@aux#1{% + \bbl@startcommands*{#1}{captions}% + % Activate captions/... and modify exports + \bbl@csarg\def{inikv@captions.licr}##1##2{% + \setlocalecaption{#1}{##1}{##2}}% + \def\bbl@inikv@captions##1##2{% + \bbl@ini@captions@aux{##1}{##2}}% + \def\bbl@stringdef##1##2{\gdef##1{##2}}% + \def\bbl@exportkey##1##2##3{% + \bbl@ifunset{bbl@@kv@##2}{}% + {\expandafter\ifx\csname bbl@@kv@##2\endcsname\@empty\else + \bbl@exp{\global\let\\}% + \fi}}% + % As with \bbl@read@ini, but with some changes + \bbl@read@ini@aux + \bbl@ini@exports\tw@ + % Update inidata@lang by pretending the ini is read. + \def\bbl@elt##1##2##3{% + \def\bbl@section{##1}% + \bbl@iniline##2=##3\bbl@iniline}% + \csname bbl@inidata@#1\endcsname + \global\bbl@csarg\let{inidata@#1}\bbl@inidata + \StartBabelCommands*{#1}{date}% And from the import stuff + \def\bbl@stringdef##1##2{\gdef##1{##2}}% + \bbl@savetoday + \bbl@savedate + \bbl@endcommands} % \end{macrocode} % -% The definition of |\grq| depends on the fontencoding. With -% \texttt{T1} encoding no extra kerning is needed. +% A somewhat hackish tool to handle calendar sections. To be improved. % % \begin{macrocode} -\ProvideTextCommand{\grq}{T1}{% - \textormath{\kern\z@\textquoteleft}{\mbox{\textquoteleft}}} -\ProvideTextCommand{\grq}{TU}{% - \textormath{\textquoteleft}{\mbox{\textquoteleft}}} -\ProvideTextCommand{\grq}{OT1}{% - \save@sf@q{\kern-.0125em - \textormath{\textquoteleft}{\mbox{\textquoteleft}}% - \kern.07em\relax}} -\ProvideTextCommandDefault{\grq}{\UseTextSymbol{OT1}\grq} +\def\bbl@ini@calendar#1{% + \lowercase{\def\bbl@tempa{=#1=}}% + \bbl@replace\bbl@tempa{=date.gregorian}{}% + \bbl@replace\bbl@tempa{=date.}{}% + \in@{.licr=}{#1=}% + \ifin@ + \ifcase\bbl@engine + \bbl@replace\bbl@tempa{.licr=}{}% + \else + \let\bbl@tempa\relax + \fi + \fi + \ifx\bbl@tempa\relax\else + \bbl@replace\bbl@tempa{=}{}% + \bbl@exp{% + \def\####1####2{% + \\\bbl@inidate####1...\relax{####2}{\bbl@tempa}}}% + \fi} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\glqq} -% \begin{macro}{\grqq} -% -% The `german' double quotes. +% A key with a slash in |\babelprovide| replaces the value in the |ini| +% file (which is ignored altogether). The mechanism is simple (but +% suboptimal): add the data to the |ini| one (at this point the |ini| +% file has not yet been read), and define a dummy macro. When the |ini| +% file is read, just skip the corresponding key and reset the macro (in +% |\bbl@inistore| above). +% % % \begin{macrocode} -\ProvideTextCommandDefault{\glqq}{% - \textormath{\quotedblbase}{\mbox{\quotedblbase}}} +\def\bbl@renewinikey#1/#2\@@#3{% + \edef\bbl@tempa{\zap@space #1 \@empty}% section + \edef\bbl@tempb{\zap@space #2 \@empty}% key + \bbl@trim\toks@{#3}% value + \bbl@exp{% + \edef\\\bbl@key@list{\bbl@key@list \bbl@tempa/\bbl@tempb;}% + \\\g@addto@macro\\\bbl@inidata{% + \\\bbl@elt{\bbl@tempa}{\bbl@tempb}{\the\toks@}}}}% % \end{macrocode} % -% The definition of |\grqq| depends on the fontencoding. With -% \texttt{T1} encoding no extra kerning is needed. +% The previous assignments are local, so we need to export them. If +% the value is empty, we can provide a default value. % % \begin{macrocode} -\ProvideTextCommand{\grqq}{T1}{% - \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}} -\ProvideTextCommand{\grqq}{TU}{% - \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}} -\ProvideTextCommand{\grqq}{OT1}{% - \save@sf@q{\kern-.07em - \textormath{\textquotedblleft}{\mbox{\textquotedblleft}}% - \kern.07em\relax}} -\ProvideTextCommandDefault{\grqq}{\UseTextSymbol{OT1}\grqq} +\def\bbl@exportkey#1#2#3{% + \bbl@ifunset{bbl@@kv@#2}% + {\bbl@csarg\gdef{#1@\languagename}{#3}}% + {\expandafter\ifx\csname bbl@@kv@#2\endcsname\@empty + \bbl@csarg\gdef{#1@\languagename}{#3}% + \else + \bbl@exp{\global\let\\}% + \fi}} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\flq} -% \begin{macro}{\frq} -% -% The `french' single guillemets. +% Key-value pairs are treated differently depending on the section in +% the |ini| file. The following macros are the readers for +% |identification| and |typography|. Note |\bbl@ini@exports| +% is called always (via |\bbl@inisec|), while |\bbl@after@ini| must be +% called explicitly after |\bbl@read@ini| if necessary. % % \begin{macrocode} -\ProvideTextCommandDefault{\flq}{% - \textormath{\guilsinglleft}{\mbox{\guilsinglleft}}} -\ProvideTextCommandDefault{\frq}{% - \textormath{\guilsinglright}{\mbox{\guilsinglright}}} -% \end{macrocode} +\def\bbl@iniwarning#1{% + \bbl@ifunset{bbl@@kv@identification.warning#1}{}% + {\bbl@warning{% + From babel-\bbl@cs{lini@\languagename}.ini:\\% + \bbl@cs{@kv@identification.warning#1}\\% + Reported }}} % -% \end{macro} -% \end{macro} +\let\bbl@release@transforms\@empty % -% \begin{macro}{\flqq} -% \begin{macro}{\frqq} +\def\bbl@ini@exports#1{% + % Identification always exported + \bbl@iniwarning{}% + \ifcase\bbl@engine + \bbl@iniwarning{.pdflatex}% + \or + \bbl@iniwarning{.lualatex}% + \or + \bbl@iniwarning{.xelatex}% + \fi% + \bbl@exportkey{llevel}{identification.load.level}{}% + \bbl@exportkey{elname}{identification.name.english}{}% + \bbl@exp{\\\bbl@exportkey{lname}{identification.name.opentype}% + {\csname bbl@elname@\languagename\endcsname}}% + \bbl@exportkey{tbcp}{identification.tag.bcp47}{}% + \bbl@exportkey{lbcp}{identification.language.tag.bcp47}{}% + \bbl@exportkey{lotf}{identification.tag.opentype}{dflt}% + \bbl@exportkey{esname}{identification.script.name}{}% + \bbl@exp{\\\bbl@exportkey{sname}{identification.script.name.opentype}% + {\csname bbl@esname@\languagename\endcsname}}% + \bbl@exportkey{sbcp}{identification.script.tag.bcp47}{}% + \bbl@exportkey{sotf}{identification.script.tag.opentype}{DFLT}% + % Also maps bcp47 -> languagename + \ifbbl@bcptoname + \bbl@csarg\xdef{bcp@map@\bbl@cl{tbcp}}{\languagename}% + \fi + % Conditional + \ifnum#1>\z@ % 0 = only info, 1, 2 = basic, (re)new + \bbl@exportkey{lnbrk}{typography.linebreaking}{h}% + \bbl@exportkey{hyphr}{typography.hyphenrules}{}% + \bbl@exportkey{lfthm}{typography.lefthyphenmin}{2}% + \bbl@exportkey{rgthm}{typography.righthyphenmin}{3}% + \bbl@exportkey{prehc}{typography.prehyphenchar}{}% + \bbl@exportkey{hyotl}{typography.hyphenate.other.locale}{}% + \bbl@exportkey{hyots}{typography.hyphenate.other.script}{}% + \bbl@exportkey{intsp}{typography.intraspace}{}% + \bbl@exportkey{frspc}{typography.frenchspacing}{u}% + \bbl@exportkey{chrng}{characters.ranges}{}% + \bbl@exportkey{quote}{characters.delimiters.quotes}{}% + \bbl@exportkey{dgnat}{numbers.digits.native}{}% + \ifnum#1=\tw@ % only (re)new + \bbl@exportkey{rqtex}{identification.require.babel}{}% + \bbl@toglobal\bbl@savetoday + \bbl@toglobal\bbl@savedate + \bbl@savestrings + \fi + \fi} +% \end{macrocode} % -% The `french' double guillemets. +% A shared handler for key=val lines to be stored in +% |\bbl@@kv@
.|. % % \begin{macrocode} -\ProvideTextCommandDefault{\flqq}{% - \textormath{\guillemetleft}{\mbox{\guillemetleft}}} -\ProvideTextCommandDefault{\frqq}{% - \textormath{\guillemetright}{\mbox{\guillemetright}}} +\def\bbl@inikv#1#2{% key=value + \toks@{#2}% This hides #'s from ini values + \bbl@csarg\edef{@kv@\bbl@section.#1}{\the\toks@}} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \subsubsection{Umlauts and tremas} -% -% The command |\"| needs to have a different effect for different -% languages. For German for instance, the `umlaut' should be -% positioned lower than the default position for placing it over -% the letters a, o, u, A, O and U. When placed over an e, i, E or I -% it can retain its normal position. For Dutch the same glyph is -% always placed in the lower position. +% By default, the following sections are just read. Actions are taken +% later. % -% \begin{macro}{\umlauthigh} +% \begin{macrocode} +\let\bbl@inikv@identification\bbl@inikv +\let\bbl@inikv@typography\bbl@inikv +\let\bbl@inikv@characters\bbl@inikv +\let\bbl@inikv@numbers\bbl@inikv +% \end{macrocode} % -% \begin{macro}{\umlautlow} -% To be able to provide both positions of |\"| we provide two -% commands to switch the positioning, the default will be -% |\umlauthigh| (the normal positioning). +% Additive numerals require an additional definition. When |.1| is +% found, two macros are defined -- the basic one, without |.1| called +% by |\localenumeral|, and another one preserving the trailing |.1| for +% the ‘units’. % % \begin{macrocode} -\def\umlauthigh{% - \def\bbl@umlauta##1{\leavevmode\bgroup% - \expandafter\accent\csname\f@encoding dqpos\endcsname - ##1\bbl@allowhyphens\egroup}% - \let\bbl@umlaute\bbl@umlauta} -\def\umlautlow{% - \def\bbl@umlauta{\protect\lower@umlaut}} -\def\umlautelow{% - \def\bbl@umlaute{\protect\lower@umlaut}} -\umlauthigh +\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$}% + \ifin@ + \bbl@replace\bbl@tempc{.1}{}% + \bbl@csarg\protected@xdef{cntr@\bbl@tempc @\languagename}{% + \noexpand\bbl@alphnumeral{\bbl@tempc}}% + \fi + \in@{.F.}{#1}% + \ifin@\else\in@{.S.}{#1}\fi + \ifin@ + \bbl@csarg\protected@xdef{cntr@#1@\languagename}{\bbl@tempb*}% + \else + \toks@{}% Required by \bbl@buildifcase, which returns \bbl@tempa + \expandafter\bbl@buildifcase\bbl@tempb* \\ % Space after \\ + \bbl@csarg{\global\expandafter\let}{cntr@#1@\languagename}\bbl@tempa + \fi} % \end{macrocode} % -% \end{macro} -% \end{macro} -% -% \begin{macro}{\lower@umlaut} -% The command |\lower@umlaut| is used to position the |\"| closer -% to the letter. -% -% We want the umlaut character lowered, nearer to the letter. To do -% this we need an extra \meta{dimen} register. +% Now |captions| and |captions.licr|, depending on the engine. And +% below also for dates. They rely on a few auxiliary macros. It is +% expected the ini file provides the complete set in Unicode and LICR, +% in that order. % % \begin{macrocode} -\expandafter\ifx\csname U@D\endcsname\relax - \csname newdimen\endcsname\U@D +\ifcase\bbl@engine + \bbl@csarg\def{inikv@captions.licr}#1#2{% + \bbl@ini@captions@aux{#1}{#2}} +\else + \def\bbl@inikv@captions#1#2{% + \bbl@ini@captions@aux{#1}{#2}} \fi % \end{macrocode} % -% The following code fools \TeX's \texttt{make\_accent} procedure -% about the current x-height of the font to force another placement -% of the umlaut character. -% First we have to save the current x-height of the font, because -% we'll change this font dimension and this is always done -% globally. -% -% Then we compute the new x-height in such a way that the umlaut -% character is lowered to the base character. The value of -% \texttt{.45ex} depends on the \MF\ parameters with which the -% fonts were built. (Just try out, which value will look best.) -% If the new x-height is too low, it is not changed. -% Finally we call the |\accent| primitive, reset the old x-height -% and insert the base character in the argument. +% The auxiliary macro for captions define |\name|. % % \begin{macrocode} -\def\lower@umlaut#1{% - \leavevmode\bgroup - \U@D 1ex% - {\setbox\z@\hbox{% - \expandafter\char\csname\f@encoding dqpos\endcsname}% - \dimen@ -.45ex\advance\dimen@\ht\z@ - \ifdim 1ex<\dimen@ \fontdimen5\font\dimen@ \fi}% - \expandafter\accent\csname\f@encoding dqpos\endcsname - \fontdimen5\font\U@D #1% - \egroup} +\def\bbl@ini@captions@template#1#2{% string language tempa=capt-name + \bbl@replace\bbl@tempa{.template}{}% + \def\bbl@toreplace{#1{}}% + \bbl@replace\bbl@toreplace{[ ]}{\nobreakspace{}}% + \bbl@replace\bbl@toreplace{[[}{\csname}% + \bbl@replace\bbl@toreplace{[}{\csname the}% + \bbl@replace\bbl@toreplace{]]}{name\endcsname{}}% + \bbl@replace\bbl@toreplace{]}{\endcsname{}}% + \bbl@xin@{,\bbl@tempa,}{,chapter,appendix,part,}% + \ifin@ + \@nameuse{bbl@patch\bbl@tempa}% + \global\bbl@csarg\let{\bbl@tempa fmt@#2}\bbl@toreplace + \fi + \bbl@xin@{,\bbl@tempa,}{,figure,table,}% + \ifin@ + \toks@\expandafter{\bbl@toreplace}% + \bbl@exp{\gdef\{\the\toks@}}% + \fi} +\def\bbl@ini@captions@aux#1#2{% + \bbl@trim@def\bbl@tempa{#1}% + \bbl@xin@{.template}{\bbl@tempa}% + \ifin@ + \bbl@ini@captions@template{#2}\languagename + \else + \bbl@ifblank{#2}% + {\bbl@exp{% + \toks@{\\\bbl@nocaption{\bbl@tempa}{\languagename\bbl@tempa name}}}}% + {\bbl@trim\toks@{#2}}% + \bbl@exp{% + \\\bbl@add\\\bbl@savestrings{% + \\\SetString\<\bbl@tempa name>{\the\toks@}}}% + \toks@\expandafter{\bbl@captionslist}% + \bbl@exp{\\\in@{\<\bbl@tempa name>}{\the\toks@}}% + \ifin@\else + \bbl@exp{% + \\\bbl@add\{\<\bbl@tempa name>}% + \\\bbl@toglobal\}% + \fi + \fi} % \end{macrocode} % -% \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). -% +% \textbf{Labels.} Captions must contain just strings, no +% format at all, so there is new group in ini files. +% % \begin{macrocode} -\AtBeginDocument{% - \DeclareTextCompositeCommand{\"}{OT1}{a}{\bbl@umlauta{a}}% - \DeclareTextCompositeCommand{\"}{OT1}{e}{\bbl@umlaute{e}}% - \DeclareTextCompositeCommand{\"}{OT1}{i}{\bbl@umlaute{\i}}% - \DeclareTextCompositeCommand{\"}{OT1}{\i}{\bbl@umlaute{\i}}% - \DeclareTextCompositeCommand{\"}{OT1}{o}{\bbl@umlauta{o}}% - \DeclareTextCompositeCommand{\"}{OT1}{u}{\bbl@umlauta{u}}% - \DeclareTextCompositeCommand{\"}{OT1}{A}{\bbl@umlauta{A}}% - \DeclareTextCompositeCommand{\"}{OT1}{E}{\bbl@umlaute{E}}% - \DeclareTextCompositeCommand{\"}{OT1}{I}{\bbl@umlaute{I}}% - \DeclareTextCompositeCommand{\"}{OT1}{O}{\bbl@umlauta{O}}% - \DeclareTextCompositeCommand{\"}{OT1}{U}{\bbl@umlauta{U}}} +\def\bbl@list@the{% + part,chapter,section,subsection,subsubsection,paragraph,% + subparagraph,enumi,enumii,enumiii,enumiv,equation,figure,% + table,page,footnote,mpfootnote,mpfn} +\def\bbl@map@cnt#1{% #1:roman,etc, // #2:enumi,etc + \bbl@ifunset{bbl@map@#1@\languagename}% + {\@nameuse{#1}}% + {\@nameuse{bbl@map@#1@\languagename}}} +\def\bbl@inikv@labels#1#2{% + \in@{.map}{#1}% + \ifin@ + \ifx\bbl@KVP@labels\@nil\else + \bbl@xin@{ map }{ \bbl@KVP@labels\space}% + \ifin@ + \def\bbl@tempc{#1}% + \bbl@replace\bbl@tempc{.map}{}% + \in@{,#2,}{,arabic,roman,Roman,alph,Alph,fnsymbol,}% + \bbl@exp{% + \gdef\% + {\ifin@\<#2>\else\\\localecounter{#2}\fi}}% + \bbl@foreach\bbl@list@the{% + \bbl@ifunset{the##1}{}% + {\bbl@exp{\let\\\bbl@tempd\}% + \bbl@exp{% + \\\bbl@sreplace\% + {\<\bbl@tempc>{##1}}{\\\bbl@map@cnt{\bbl@tempc}{##1}}% + \\\bbl@sreplace\% + {\<\@empty @\bbl@tempc>\}{\\\bbl@map@cnt{\bbl@tempc}{##1}}}% + \expandafter\ifx\csname the##1\endcsname\bbl@tempd\else + \toks@\expandafter\expandafter\expandafter{% + \csname the##1\endcsname}% + \expandafter\xdef\csname the##1\endcsname{{\the\toks@}}% + \fi}}% + \fi + \fi + % + \else + % + % The following code is still under study. You can test it and make + % suggestions. Eg, enumerate.2 = ([enumi]).([enumii]). It's + % language dependent. + \in@{enumerate.}{#1}% + \ifin@ + \def\bbl@tempa{#1}% + \bbl@replace\bbl@tempa{enumerate.}{}% + \def\bbl@toreplace{#2}% + \bbl@replace\bbl@toreplace{[ ]}{\nobreakspace{}}% + \bbl@replace\bbl@toreplace{[}{\csname the}% + \bbl@replace\bbl@toreplace{]}{\endcsname{}}% + \toks@\expandafter{\bbl@toreplace}% + % TODO. Execute only once: + \bbl@exp{% + \\\bbl@add\{% + \\\babel@save\% + \def\{\the\toks@}}% + \\\bbl@toglobal\}% + \fi + \fi} % \end{macrocode} % -% Finally, make sure the default hyphenrules are defined (even if -% empty). For internal use, another empty |\language| is defined. -% Currently used in Amharic. +% To show correctly some captions in a few languages, we need to patch +% some internal macros, because the order is hardcoded. For example, in +% Japanese the chapter number is surrounded by two string, while in +% Hungarian is placed after. These replacement works in many classes, +% but not all. Actually, the following lines are somewhat tentative. % % \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@unhyphenated\@undefined - \newlanguage\l@unhyphenated +\def\bbl@chaptype{chapter} +\ifx\@makechapterhead\@undefined + \let\bbl@patchchapter\relax +\else\ifx\thechapter\@undefined + \let\bbl@patchchapter\relax +\else\ifx\ps@headings\@undefined + \let\bbl@patchchapter\relax +\else + \def\bbl@patchchapter{% + \global\let\bbl@patchchapter\relax + \gdef\bbl@chfmt{% + \bbl@ifunset{bbl@\bbl@chaptype fmt@\languagename}% + {\@chapapp\space\thechapter} + {\@nameuse{bbl@\bbl@chaptype fmt@\languagename}}} + \bbl@add\appendix{\def\bbl@chaptype{appendix}}% Not harmful, I hope + \bbl@sreplace\ps@headings{\@chapapp\ \thechapter}{\bbl@chfmt}% + \bbl@sreplace\chaptermark{\@chapapp\ \thechapter}{\bbl@chfmt}% + \bbl@sreplace\@makechapterhead{\@chapapp\space\thechapter}{\bbl@chfmt}% + \bbl@toglobal\appendix + \bbl@toglobal\ps@headings + \bbl@toglobal\chaptermark + \bbl@toglobal\@makechapterhead} + \let\bbl@patchappendix\bbl@patchchapter +\fi\fi\fi +\ifx\@part\@undefined + \let\bbl@patchpart\relax +\else + \def\bbl@patchpart{% + \global\let\bbl@patchpart\relax + \gdef\bbl@partformat{% + \bbl@ifunset{bbl@partfmt@\languagename}% + {\partname\nobreakspace\thepart} + {\@nameuse{bbl@partfmt@\languagename}}} + \bbl@sreplace\@part{\partname\nobreakspace\thepart}{\bbl@partformat}% + \bbl@toglobal\@part} \fi % \end{macrocode} % -% \subsection{Layout} -% -% Layout is mainly intended to set bidi documents, but there is at -% least a tool useful in general. -% -% \begin{macrocode} -\bbl@trace{Bidi layout} -\providecommand\IfBabelLayout[3]{#3}% -\newcommand\BabelPatchSection[1]{% - \@ifundefined{#1}{}{% - \bbl@exp{\let\\<#1>}% - \@namedef{#1}{% - \@ifstar{\bbl@presec@s{#1}}% - {\@dblarg{\bbl@presec@x{#1}}}}}} -\def\bbl@presec@x#1[#2]#3{% - \bbl@exp{% - \\\select@language@x{\bbl@main@language}% - \\\bbl@cs{sspre@#1}% - \\\bbl@cs{ss@#1}% - [\\\foreignlanguage{\languagename}{\unexpanded{#2}}]% - {\\\foreignlanguage{\languagename}{\unexpanded{#3}}}% - \\\select@language@x{\languagename}}} -\def\bbl@presec@s#1#2{% - \bbl@exp{% - \\\select@language@x{\bbl@main@language}% - \\\bbl@cs{sspre@#1}% - \\\bbl@cs{ss@#1}*% - {\\\foreignlanguage{\languagename}{\unexpanded{#2}}}% - \\\select@language@x{\languagename}}} -\IfBabelLayout{sectioning}% - {\BabelPatchSection{part}% - \BabelPatchSection{chapter}% - \BabelPatchSection{section}% - \BabelPatchSection{subsection}% - \BabelPatchSection{subsubsection}% - \BabelPatchSection{paragraph}% - \BabelPatchSection{subparagraph}% - \def\babel@toc#1{% - \select@language@x{\bbl@main@language}}}{} -\IfBabelLayout{captions}% - {\BabelPatchSection{caption}}{} -% \end{macrocode} -% -% \subsection{Load engine specific macros} +% \textbf{Date.} TODO. Document % % \begin{macrocode} -\bbl@trace{Input engine specific macros} -\ifcase\bbl@engine - \input txtbabel.def -\or - \input luababel.def -\or - \input xebabel.def -\fi +% Arguments are _not_ protected. +\let\bbl@calendar\@empty +\DeclareRobustCommand\localedate[1][]{\bbl@localedate{#1}} +\def\bbl@localedate#1#2#3#4{% + \begingroup + \ifx\@empty#1\@empty\else + \let\bbl@ld@calendar\@empty + \let\bbl@ld@variant\@empty + \edef\bbl@tempa{\zap@space#1 \@empty}% + \def\bbl@tempb##1=##2\@@{\@namedef{bbl@ld@##1}{##2}}% + \bbl@foreach\bbl@tempa{\bbl@tempb##1\@@}% + \edef\bbl@calendar{% + \bbl@ld@calendar + \ifx\bbl@ld@variant\@empty\else + .\bbl@ld@variant + \fi}% + \bbl@replace\bbl@calendar{gregorian}{}% + \fi + \bbl@cased + {\@nameuse{bbl@date@\languagename @\bbl@calendar}{#2}{#3}{#4}}% + \endgroup} +% eg: 1=months, 2=wide, 3=1, 4=dummy, 5=value, 6=calendar +\def\bbl@inidate#1.#2.#3.#4\relax#5#6{% TODO - ignore with 'captions' + \bbl@trim@def\bbl@tempa{#1.#2}% + \bbl@ifsamestring{\bbl@tempa}{months.wide}% to savedate + {\bbl@trim@def\bbl@tempa{#3}% + \bbl@trim\toks@{#5}% + \@temptokena\expandafter{\bbl@savedate}% + \bbl@exp{% Reverse order - in ini last wins + \def\\\bbl@savedate{% + \\\SetString\{\the\toks@}% + \the\@temptokena}}}% + {\bbl@ifsamestring{\bbl@tempa}{date.long}% defined now + {\lowercase{\def\bbl@tempb{#6}}% + \bbl@trim@def\bbl@toreplace{#5}% + \bbl@TG@@date + \bbl@ifunset{bbl@date@\languagename @}% + {\bbl@exp{% TODO. Move to a better place. + \gdef\<\languagename date>{\\\protect\<\languagename date >}% + \gdef\<\languagename date >####1####2####3{% + \\\bbl@usedategrouptrue + \{% + \\\localedate{####1}{####2}{####3}}}% + \\\bbl@add\\\bbl@savetoday{% + \\\SetString\\\today{% + \<\languagename date>% + {\\\the\year}{\\\the\month}{\\\the\day}}}}}% + {}% + \global\bbl@csarg\let{date@\languagename @}\bbl@toreplace + \ifx\bbl@tempb\@empty\else + \global\bbl@csarg\let{date@\languagename @\bbl@tempb}\bbl@toreplace + \fi}% + {}}} % \end{macrocode} % -% \subsection{Creating and modifying languages} -% -% |\babelprovide| is a general purpose tool for creating and modifying -% languages. It creates the language infrastructure, and loads, if -% requested, an |ini| file. It may be used in conjunction to previouly -% loaded |ldf| files. +% \textbf{Dates} will require some macros for the basic formatting. +% They may be redefined by language, so ``semi-public'' names (camel +% case) are used. Oddly enough, the CLDR places particles like “de” +% inconsistently in either in the date or in the month name. Note after +% |\bbl@replace| |\toks@| contains the resulting string, which is used +% by |\bbl@replace@finish@iii| (this implicit behavior doesn't seem a +% good idea, but it’s efficient). % % \begin{macrocode} -\bbl@trace{Creating languages and reading ini files} -\let\bbl@extend@ini\@gobble -\newcommand\babelprovide[2][]{% - \let\bbl@savelangname\languagename - \edef\bbl@savelocaleid{\the\localeid}% - % Set name and locale id - \edef\languagename{#2}% - \bbl@id@assign - % Initialize keys - \let\bbl@KVP@captions\@nil - \let\bbl@KVP@date\@nil - \let\bbl@KVP@import\@nil - \let\bbl@KVP@main\@nil - \let\bbl@KVP@script\@nil - \let\bbl@KVP@language\@nil - \let\bbl@KVP@hyphenrules\@nil - \let\bbl@KVP@linebreaking\@nil - \let\bbl@KVP@justification\@nil - \let\bbl@KVP@mapfont\@nil - \let\bbl@KVP@maparabic\@nil - \let\bbl@KVP@mapdigits\@nil - \let\bbl@KVP@intraspace\@nil - \let\bbl@KVP@intrapenalty\@nil - \let\bbl@KVP@onchar\@nil - \let\bbl@KVP@transforms\@nil - \global\let\bbl@release@transforms\@empty - \let\bbl@KVP@alph\@nil - \let\bbl@KVP@Alph\@nil - \let\bbl@KVP@labels\@nil - \bbl@csarg\let{KVP@labels*}\@nil - \global\let\bbl@inidata\@empty - \global\let\bbl@extend@ini\@gobble - \gdef\bbl@key@list{;}% - \bbl@forkv{#1}{% TODO - error handling - \in@{/}{##1}% - \ifin@ - \global\let\bbl@extend@ini\bbl@extend@ini@aux - \bbl@renewinikey##1\@@{##2}% - \else - \bbl@csarg\def{KVP@##1}{##2}% - \fi}% - \chardef\bbl@howloaded=% 0:none; 1:ldf without ini; 2:ini - \bbl@ifunset{date#2}\z@{\bbl@ifunset{bbl@llevel@#2}\@ne\tw@}% - % == init == - \ifx\bbl@screset\@undefined - \bbl@ldfinit - \fi - % == - \let\bbl@lbkflag\relax % \@empty = do setup linebreak - \ifcase\bbl@howloaded - \let\bbl@lbkflag\@empty % new - \else - \ifx\bbl@KVP@hyphenrules\@nil\else - \let\bbl@lbkflag\@empty - \fi - \ifx\bbl@KVP@import\@nil\else - \let\bbl@lbkflag\@empty - \fi - \fi - % == import, captions == - \ifx\bbl@KVP@import\@nil\else - \bbl@exp{\\\bbl@ifblank{\bbl@KVP@import}}% - {\ifx\bbl@initoload\relax - \begingroup - \def\BabelBeforeIni##1##2{\gdef\bbl@KVP@import{##1}\endinput}% - \bbl@input@texini{#2}% - \endgroup - \else - \xdef\bbl@KVP@import{\bbl@initoload}% - \fi}% - {}% - \fi - \ifx\bbl@KVP@captions\@nil - \let\bbl@KVP@captions\bbl@KVP@import - \fi - % == - \ifx\bbl@KVP@transforms\@nil\else - \bbl@replace\bbl@KVP@transforms{ }{,}% - \fi - % == Load ini == - \ifcase\bbl@howloaded - \bbl@provide@new{#2}% +\let\bbl@calendar\@empty +\newcommand\BabelDateSpace{\nobreakspace} +\newcommand\BabelDateDot{.\@} % TODO. \let instead of repeating +\newcommand\BabelDated[1]{{\number#1}} +\newcommand\BabelDatedd[1]{{\ifnum#1<10 0\fi\number#1}} +\newcommand\BabelDateM[1]{{\number#1}} +\newcommand\BabelDateMM[1]{{\ifnum#1<10 0\fi\number#1}} +\newcommand\BabelDateMMMM[1]{{% + \csname month\romannumeral#1\bbl@calendar name\endcsname}}% +\newcommand\BabelDatey[1]{{\number#1}}% +\newcommand\BabelDateyy[1]{{% + \ifnum#1<10 0\number#1 % + \else\ifnum#1<100 \number#1 % + \else\ifnum#1<1000 \expandafter\@gobble\number#1 % + \else\ifnum#1<10000 \expandafter\@gobbletwo\number#1 % \else - \bbl@ifblank{#1}% - {}% With \bbl@load@basic below - {\bbl@provide@renew{#2}}% - \fi - % Post tasks - % ---------- - % == subsequent calls after the first provide for a locale == - \ifx\bbl@inidata\@empty\else - \bbl@extend@ini{#2}% - \fi - % == ensure captions == - \ifx\bbl@KVP@captions\@nil\else - \bbl@ifunset{bbl@extracaps@#2}% - {\bbl@exp{\\\babelensure[exclude=\\\today]{#2}}}% - {\toks@\expandafter\expandafter\expandafter - {\csname bbl@extracaps@#2\endcsname}% - \bbl@exp{\\\babelensure[exclude=\\\today,include=\the\toks@}]{#2}}% - \bbl@ifunset{bbl@ensure@\languagename}% - {\bbl@exp{% - \\\DeclareRobustCommand\[1]{% - \\\foreignlanguage{\languagename}% - {####1}}}}% - {}% - \bbl@exp{% - \\\bbl@toglobal\% - \\\bbl@toglobal\}% - \fi - % == - % At this point all parameters are defined if 'import'. Now we - % execute some code depending on them. But what about if nothing was - % imported? We just set the basic parameters, but still loading the - % whole ini file. - \bbl@load@basic{#2}% - % == script, language == - % Override the values from ini or defines them - \ifx\bbl@KVP@script\@nil\else - \bbl@csarg\edef{sname@#2}{\bbl@KVP@script}% - \fi - \ifx\bbl@KVP@language\@nil\else - \bbl@csarg\edef{lname@#2}{\bbl@KVP@language}% - \fi - % == onchar == - \ifx\bbl@KVP@onchar\@nil\else - \bbl@luahyphenate - \directlua{ - if Babel.locale_mapped == nil then - Babel.locale_mapped = true - Babel.linebreaking.add_before(Babel.locale_map) - Babel.loc_to_scr = {} - Babel.chr_to_loc = Babel.chr_to_loc or {} - end}% - \bbl@xin@{ ids }{ \bbl@KVP@onchar\space}% - \ifin@ - \ifx\bbl@starthyphens\@undefined % Needed if no explicit selection - \AddBabelHook{babel-onchar}{beforestart}{{\bbl@starthyphens}}% - \fi - \bbl@exp{\\\bbl@add\\\bbl@starthyphens - {\\\bbl@patterns@lua{\languagename}}}% - % TODO - error/warning if no script - \directlua{ - if Babel.script_blocks['\bbl@cl{sbcp}'] then - Babel.loc_to_scr[\the\localeid] = - Babel.script_blocks['\bbl@cl{sbcp}'] - Babel.locale_props[\the\localeid].lc = \the\localeid\space - Babel.locale_props[\the\localeid].lg = \the\@nameuse{l@\languagename}\space - end - }% - \fi - \bbl@xin@{ fonts }{ \bbl@KVP@onchar\space}% - \ifin@ - \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% - \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% + \bbl@error + {Currently two-digit years are restricted to the\\ + range 0-9999.}% + {There is little you can do. Sorry.}% + \fi\fi\fi\fi}} +\newcommand\BabelDateyyyy[1]{{\number#1}} % TODO - add leading 0 +\def\bbl@replace@finish@iii#1{% + \bbl@exp{\def\\#1####1####2####3{\the\toks@}}} +\def\bbl@TG@@date{% + \bbl@replace\bbl@toreplace{[ ]}{\BabelDateSpace{}}% + \bbl@replace\bbl@toreplace{[.]}{\BabelDateDot{}}% + \bbl@replace\bbl@toreplace{[d]}{\BabelDated{####3}}% + \bbl@replace\bbl@toreplace{[dd]}{\BabelDatedd{####3}}% + \bbl@replace\bbl@toreplace{[M]}{\BabelDateM{####2}}% + \bbl@replace\bbl@toreplace{[MM]}{\BabelDateMM{####2}}% + \bbl@replace\bbl@toreplace{[MMMM]}{\BabelDateMMMM{####2}}% + \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|}% + \bbl@replace@finish@iii\bbl@toreplace} +\def\bbl@datecntr{\expandafter\bbl@xdatecntr\expandafter} +\def\bbl@xdatecntr[#1|#2]{\localenumeral{#2}{#1}} +% \end{macrocode} +% +% \textbf{Transforms.} +% +% \begin{macrocode} +\let\bbl@release@transforms\@empty +\@namedef{bbl@inikv@transforms.prehyphenation}{% + \bbl@transforms\babelprehyphenation} +\@namedef{bbl@inikv@transforms.posthyphenation}{% + \bbl@transforms\babelposthyphenation} +\def\bbl@transforms@aux#1#2#3,#4\relax{#1{#2}{#3}{#4}} +\begingroup % A hack. TODO. Don't require an specific order + \catcode`\%=12 + \catcode`\&=14 + \gdef\bbl@transforms#1#2#3{&% + \ifx\bbl@KVP@transforms\@nil\else \directlua{ - if Babel.script_blocks['\bbl@cl{sbcp}'] then - Babel.loc_to_scr[\the\localeid] = - Babel.script_blocks['\bbl@cl{sbcp}'] - end}% - \ifx\bbl@mapselect\@undefined % TODO. almost the same as mapfont - \AtBeginDocument{% - \bbl@patchfont{{\bbl@mapselect}}% - {\selectfont}}% - \def\bbl@mapselect{% - \let\bbl@mapselect\relax - \edef\bbl@prefontid{\fontid\font}}% - \def\bbl@mapdir##1{% - {\def\languagename{##1}% - \let\bbl@ifrestoring\@firstoftwo % To avoid font warning - \bbl@switchfont - \directlua{ - Babel.locale_props[\the\csname bbl@id@@##1\endcsname]% - ['/\bbl@prefontid'] = \fontid\font\space}}}% + str = [==[#2]==] + str = str:gsub('%.%d+%.%d+$', '') + tex.print([[\def\string\babeltempa{]] .. str .. [[}]]) + }&% + \bbl@xin@{,\babeltempa,}{,\bbl@KVP@transforms,}&% + \ifin@ + \in@{.0$}{#2$}&% + \ifin@ + \g@addto@macro\bbl@release@transforms{&% + \relax\bbl@transforms@aux#1{\languagename}{#3}}&% + \else + \g@addto@macro\bbl@release@transforms{, {#3}}&% + \fi \fi - \bbl@exp{\\\bbl@add\\\bbl@mapselect{\\\bbl@mapdir{\languagename}}}% - \fi - % TODO - catch non-valid values - \fi - % == mapfont == - % For bidi texts, to switch the font based on direction - \ifx\bbl@KVP@mapfont\@nil\else - \bbl@ifsamestring{\bbl@KVP@mapfont}{direction}{}% - {\bbl@error{Option '\bbl@KVP@mapfont' unknown for\\% - mapfont. Use 'direction'.% - {See the manual for details.}}}% - \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% - \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% - \ifx\bbl@mapselect\@undefined % TODO. See onchar. - \AtBeginDocument{% - \bbl@patchfont{{\bbl@mapselect}}% - {\selectfont}}% - \def\bbl@mapselect{% - \let\bbl@mapselect\relax - \edef\bbl@prefontid{\fontid\font}}% - \def\bbl@mapdir##1{% - {\def\languagename{##1}% - \let\bbl@ifrestoring\@firstoftwo % avoid font warning - \bbl@switchfont - \directlua{Babel.fontmap - [\the\csname bbl@wdir@##1\endcsname]% - [\bbl@prefontid]=\fontid\font}}}% - \fi - \bbl@exp{\\\bbl@add\\\bbl@mapselect{\\\bbl@mapdir{\languagename}}}% - \fi - % == Line breaking: intraspace, intrapenalty == - % For CJK, East Asian, Southeast Asian, if interspace in ini - \ifx\bbl@KVP@intraspace\@nil\else % We can override the ini or set - \bbl@csarg\edef{intsp@#2}{\bbl@KVP@intraspace}% - \fi - \bbl@provide@intraspace - % == Line breaking: CJK quotes == - \ifcase\bbl@engine\or - \bbl@xin@{/c}{/\bbl@cl{lnbrk}}% - \ifin@ - \bbl@ifunset{bbl@quote@\languagename}{}% - {\directlua{ - Babel.locale_props[\the\localeid].cjk_quotes = {} - local cs = 'op' - for c in string.utfvalues(% - [[\csname bbl@quote@\languagename\endcsname]]) do - if Babel.cjk_characters[c].c == 'qu' then - Babel.locale_props[\the\localeid].cjk_quotes[c] = cs - end - cs = ( cs == 'op') and 'cl' or 'op' - end - }}% - \fi - \fi - % == Line breaking: justification == - \ifx\bbl@KVP@justification\@nil\else - \let\bbl@KVP@linebreaking\bbl@KVP@justification - \fi - \ifx\bbl@KVP@linebreaking\@nil\else - \bbl@xin@{,\bbl@KVP@linebreaking,}{,elongated,kashida,cjk,unhyphenated,}% - \ifin@ - \bbl@csarg\xdef - {lnbrk@\languagename}{\expandafter\@car\bbl@KVP@linebreaking\@nil}% - \fi - \fi - \bbl@xin@{/e}{/\bbl@cl{lnbrk}}% - \ifin@\else\bbl@xin@{/k}{/\bbl@cl{lnbrk}}\fi - \ifin@\bbl@arabicjust\fi - % == Line breaking: hyphenate.other.(locale|script) == - \ifx\bbl@lbkflag\@empty - \bbl@ifunset{bbl@hyotl@\languagename}{}% - {\bbl@csarg\bbl@replace{hyotl@\languagename}{ }{,}% - \bbl@startcommands*{\languagename}{}% - \bbl@csarg\bbl@foreach{hyotl@\languagename}{% - \ifcase\bbl@engine - \ifnum##1<257 - \SetHyphenMap{\BabelLower{##1}{##1}}% - \fi - \else - \SetHyphenMap{\BabelLower{##1}{##1}}% - \fi}% - \bbl@endcommands}% - \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} +\endgroup +% \end{macrocode} +% +% Language and Script values to be used when defining a font or +% setting the direction are set with the following macros. +% +% \begin{macrocode} +\def\bbl@provide@lsys#1{% + \bbl@ifunset{bbl@lname@#1}% + {\bbl@load@info{#1}}% + {}% + \bbl@csarg\let{lsys@#1}\@empty + \bbl@ifunset{bbl@sname@#1}{\bbl@csarg\gdef{sname@#1}{Default}}{}% + \bbl@ifunset{bbl@sotf@#1}{\bbl@csarg\gdef{sotf@#1}{DFLT}}{}% + \bbl@csarg\bbl@add@list{lsys@#1}{Script=\bbl@cs{sname@#1}}% + \bbl@ifunset{bbl@lname@#1}{}% + {\bbl@csarg\bbl@add@list{lsys@#1}{Language=\bbl@cs{lname@#1}}}% + \ifcase\bbl@engine\or\or + \bbl@ifunset{bbl@prehc@#1}{}% + {\bbl@exp{\\\bbl@ifblank{\bbl@cs{prehc@#1}}}% + {}% + {\ifx\bbl@xenohyph\@undefined + \let\bbl@xenohyph\bbl@xenohyph@d + \ifx\AtBeginDocument\@notprerr + \expandafter\@secondoftwo % to execute right now \fi - \else - \global\lccode##1=##1\relax - \fi}}% - \fi - % == Counters: maparabic == - % Native digits, if provided in ini (TeX level, xe and lua) - \ifcase\bbl@engine\else - \bbl@ifunset{bbl@dgnat@\languagename}{}% - {\expandafter\ifx\csname bbl@dgnat@\languagename\endcsname\@empty\else - \expandafter\expandafter\expandafter - \bbl@setdigits\csname bbl@dgnat@\languagename\endcsname - \ifx\bbl@KVP@maparabic\@nil\else - \ifx\bbl@latinarabic\@undefined - \expandafter\let\expandafter\@arabic - \csname bbl@counter@\languagename\endcsname - \else % ie, if layout=counters, which redefines \@arabic - \expandafter\let\expandafter\bbl@latinarabic - \csname bbl@counter@\languagename\endcsname - \fi - \fi - \fi}% - \fi - % == Counters: mapdigits == - % Native digits (lua level). - \ifodd\bbl@engine - \ifx\bbl@KVP@mapdigits\@nil\else - \bbl@ifunset{bbl@dgnat@\languagename}{}% - {\RequirePackage{luatexbase}% - \bbl@activate@preotf - \directlua{ - Babel = Babel or {} %%% -> presets in luababel - Babel.digits_mapped = true - Babel.digits = Babel.digits or {} - Babel.digits[\the\localeid] = - table.pack(string.utfvalue('\bbl@cl{dgnat}')) - if not Babel.numbers then - function Babel.numbers(head) - local LOCALE = Babel.attr_locale - local GLYPH = node.id'glyph' - local inmath = false - for item in node.traverse(head) do - if not inmath and item.id == GLYPH then - local temp = node.get_attribute(item, LOCALE) - if Babel.digits[temp] then - local chr = item.char - if chr > 47 and chr < 58 then - item.char = Babel.digits[temp][chr-47] - end - end - elseif item.id == node.id'math' then - inmath = (item.subtype == 0) - end - end - return head - end - end - }}% - \fi - \fi - % == Counters: alph, Alph == - % What if extras contains a \babel@save\@alph? It won't be - % restored correctly when exiting the language, so we ignore - % this change with the \bbl@alph@saved trick. - \ifx\bbl@KVP@alph\@nil\else - \bbl@extras@wrap{\\\bbl@alph@saved}% - {\let\bbl@alph@saved\@alph}% - {\let\@alph\bbl@alph@saved - \babel@save\@alph}% - \bbl@exp{% - \\\bbl@add\{% - \let\\\@alph\}}% + \AtBeginDocument{% + \bbl@patchfont{\bbl@xenohyph}% + \expandafter\selectlanguage\expandafter{\languagename}}% + \fi}}% \fi - \ifx\bbl@KVP@Alph\@nil\else - \bbl@extras@wrap{\\\bbl@Alph@saved}% - {\let\bbl@Alph@saved\@Alph}% - {\let\@Alph\bbl@Alph@saved - \babel@save\@Alph}% + \bbl@csarg\bbl@toglobal{lsys@#1}} +\def\bbl@xenohyph@d{% + \bbl@ifset{bbl@prehc@\languagename}% + {\ifnum\hyphenchar\font=\defaulthyphenchar + \iffontchar\font\bbl@cl{prehc}\relax + \hyphenchar\font\bbl@cl{prehc}\relax + \else\iffontchar\font"200B + \hyphenchar\font"200B + \else + \bbl@warning + {Neither 0 nor ZERO WIDTH SPACE are available\\% + in the current font, and therefore the hyphen\\% + will be printed. Try changing the fontspec's\\% + 'HyphenChar' to another value, but be aware\\% + this setting is not safe (see the manual)}% + \hyphenchar\font\defaulthyphenchar + \fi\fi + \fi}% + {\hyphenchar\font\defaulthyphenchar}} + % \fi} +% \end{macrocode} +% +% The following |ini| reader ignores everything but the +% |identification| section. It is called when a font is defined (ie, +% when the language is first selected) to know which script/language +% must be enabled. This means we must make sure a few characters are +% not active. The |ini| is not read directly, but with a proxy |tex| +% file named as the language (which means any code in it must be +% skipped, too). +% +% \begin{macrocode} +\def\bbl@load@info#1{% + \def\BabelBeforeIni##1##2{% + \begingroup + \bbl@read@ini{##1}0% + \endinput % babel- .tex may contain onlypreamble's + \endgroup}% boxed, to avoid extra spaces: + {\bbl@input@texini{#1}}} +% \end{macrocode} +% +% 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. Non-digits characters are kept. The +% first macro is the generic “localized” command. +% +% \begin{macrocode} +\def\bbl@setdigits#1#2#3#4#5{% + \bbl@exp{% + \def\<\languagename digits>####1{% ie, \langdigits + \####1\\\@nil}% + \let\\<\languagename digits>% + \def\<\languagename counter>####1{% ie, \langcounter + \\\expandafter\% + \\\csname c@####1\endcsname}% + \def\####1{% ie, \bbl@counter@lang + \\\expandafter\% + \\\number####1\\\@nil}}% + \def\bbl@tempa##1##2##3##4##5{% + \bbl@exp{% Wow, quite a lot of hashes! :-( + \def\########1{% + \\\ifx########1\\\@nil % ie, \bbl@digits@lang + \\\else + \\\ifx0########1#1% + \\\else\\\ifx1########1#2% + \\\else\\\ifx2########1#3% + \\\else\\\ifx3########1#4% + \\\else\\\ifx4########1#5% + \\\else\\\ifx5########1##1% + \\\else\\\ifx6########1##2% + \\\else\\\ifx7########1##3% + \\\else\\\ifx8########1##4% + \\\else\\\ifx9########1##5% + \\\else########1% + \\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi + \\\expandafter\% + \\\fi}}}% + \bbl@tempa} +% \end{macrocode} +% +% Alphabetic counters must be converted from a space separated list to +% an |\ifcase| structure. +% +% \begin{macrocode} +\def\bbl@buildifcase#1 {% Returns \bbl@tempa, requires \toks@={} + \ifx\\#1% % \\ before, in case #1 is multiletter \bbl@exp{% - \\\bbl@add\{% - \let\\\@Alph\}}% + \def\\\bbl@tempa####1{% + \####1\space\the\toks@\\\\@ctrerr\}}% + \else + \toks@\expandafter{\the\toks@\or #1}% + \expandafter\bbl@buildifcase + \fi} +% \end{macrocode} +% +% The code for additive counters is somewhat tricky and it's based on +% the fact the arguments just before |\@@| collects digits which have +% been left ‘unused’ in previous arguments, the first of them being the +% 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). +% +% \begin{macrocode} +\newcommand\localenumeral[2]{\bbl@cs{cntr@#1@\languagename}{#2}} +\def\bbl@localecntr#1#2{\localenumeral{#2}{#1}} +\newcommand\localecounter[2]{% + \expandafter\bbl@localecntr + \expandafter{\number\csname c@#2\endcsname}{#1}} +\def\bbl@alphnumeral#1#2{% + \expandafter\bbl@alphnumeral@i\number#2 76543210\@@{#1}} +\def\bbl@alphnumeral@i#1#2#3#4#5#6#7#8\@@#9{% + \ifcase\@car#8\@nil\or % Currenty <10000, but prepared for bigger + \bbl@alphnumeral@ii{#9}000000#1\or + \bbl@alphnumeral@ii{#9}00000#1#2\or + \bbl@alphnumeral@ii{#9}0000#1#2#3\or + \bbl@alphnumeral@ii{#9}000#1#2#3#4\else + \bbl@alphnum@invalid{>9999}% + \fi} +\def\bbl@alphnumeral@ii#1#2#3#4#5#6#7#8{% + \bbl@ifunset{bbl@cntr@#1.F.\number#5#6#7#8@\languagename}% + {\bbl@cs{cntr@#1.4@\languagename}#5% + \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@ % TODO. An ad hoc rule for Greek. Ugly. + \bbl@ifunset{bbl@cntr@#1.S.321@\languagename}{}% + {\bbl@cs{cntr@#1.S.321@\languagename}}% + \fi}% + {\bbl@cs{cntr@#1.F.\number#5#6#7#8@\languagename}}} +\def\bbl@alphnum@invalid#1{% + \bbl@error{Alphabetic numeral too large (#1)}% + {Currently this is the limit.}} +% \end{macrocode} +% +% The information in the identification section can be useful, so the +% following macro just exposes it with a user command. +% +% \begin{macrocode} +\newcommand\localeinfo[1]{% + \bbl@ifunset{bbl@\csname bbl@info@#1\endcsname @\languagename}% + {\bbl@error{I've found no info for the current locale.\\% + The corresponding ini file has not been loaded\\% + Perhaps it doesn't exist}% + {See the manual for details.}}% + {\bbl@cs{\csname bbl@info@#1\endcsname @\languagename}}} +% \@namedef{bbl@info@name.locale}{lcname} +\@namedef{bbl@info@tag.ini}{lini} +\@namedef{bbl@info@name.english}{elname} +\@namedef{bbl@info@name.opentype}{lname} +\@namedef{bbl@info@tag.bcp47}{tbcp} +\@namedef{bbl@info@language.tag.bcp47}{lbcp} +\@namedef{bbl@info@tag.opentype}{lotf} +\@namedef{bbl@info@script.name}{esname} +\@namedef{bbl@info@script.name.opentype}{sname} +\@namedef{bbl@info@script.tag.bcp47}{sbcp} +\@namedef{bbl@info@script.tag.opentype}{sotf} +\let\bbl@ensureinfo\@gobble +\newcommand\BabelEnsureInfo{% + \ifx\InputIfFileExists\@undefined\else + \def\bbl@ensureinfo##1{% + \bbl@ifunset{bbl@lname@##1}{\bbl@load@info{##1}}{}}% \fi - % == require.babel in ini == - % To load or reaload the babel-*.tex, if require.babel in ini - \ifx\bbl@beforestart\relax\else % But not in doc aux or body - \bbl@ifunset{bbl@rqtex@\languagename}{}% - {\expandafter\ifx\csname bbl@rqtex@\languagename\endcsname\@empty\else - \let\BabelBeforeIni\@gobbletwo - \chardef\atcatcode=\catcode`\@ - \catcode`\@=11\relax - \bbl@input@texini{\bbl@cs{rqtex@\languagename}}% - \catcode`\@=\atcatcode - \let\atcatcode\relax - \global\bbl@csarg\let{rqtex@\languagename}\relax - \fi}% + \bbl@foreach\bbl@loaded{{% + \def\languagename{##1}% + \bbl@ensureinfo{##1}}}} +% \end{macrocode} +% +% More general, but non-expandable, is |\getlocaleproperty|. To inspect +% every possible loaded |ini|, we define |\LocaleForEach|, where +% |\bbl@ini@loaded| is a comma-separated list of locales, built by +% |\bbl@read@ini|. +% +% \begin{macrocode} +\newcommand\getlocaleproperty{% + \@ifstar\bbl@getproperty@s\bbl@getproperty@x} +\def\bbl@getproperty@s#1#2#3{% + \let#1\relax + \def\bbl@elt##1##2##3{% + \bbl@ifsamestring{##1/##2}{#3}% + {\providecommand#1{##3}% + \def\bbl@elt####1####2####3{}}% + {}}% + \bbl@cs{inidata@#2}}% +\def\bbl@getproperty@x#1#2#3{% + \bbl@getproperty@s{#1}{#2}{#3}% + \ifx#1\relax + \bbl@error + {Unknown key for locale '#2':\\% + #3\\% + \string#1 will be set to \relax}% + {Perhaps you misspelled it.}% + \fi} +\let\bbl@ini@loaded\@empty +\newcommand\LocaleForEach{\bbl@foreach\bbl@ini@loaded} +% \end{macrocode} +% +% \section{Adjusting the Babel bahavior} +% +% A generic high level inteface is provided to adjust some global +% and general settings. +% +% \begin{macrocode} +\newcommand\babeladjust[1]{% TODO. Error handling. + \bbl@forkv{#1}{% + \bbl@ifunset{bbl@ADJ@##1@##2}% + {\bbl@cs{ADJ@##1}{##2}}% + {\bbl@cs{ADJ@##1@##2}}}} +% +\def\bbl@adjust@lua#1#2{% + \ifvmode + \ifnum\currentgrouplevel=\z@ + \directlua{ Babel.#2 }% + \expandafter\expandafter\expandafter\@gobble + \fi + \fi + {\bbl@error % The error is gobbled if everything went ok. + {Currently, #1 related features can be adjusted only\\% + in the main vertical list.}% + {Maybe things change in the future, but this is what it is.}}} +\@namedef{bbl@ADJ@bidi.mirroring@on}{% + \bbl@adjust@lua{bidi}{mirroring_enabled=true}} +\@namedef{bbl@ADJ@bidi.mirroring@off}{% + \bbl@adjust@lua{bidi}{mirroring_enabled=false}} +\@namedef{bbl@ADJ@bidi.text@on}{% + \bbl@adjust@lua{bidi}{bidi_enabled=true}} +\@namedef{bbl@ADJ@bidi.text@off}{% + \bbl@adjust@lua{bidi}{bidi_enabled=false}} +\@namedef{bbl@ADJ@bidi.mapdigits@on}{% + \bbl@adjust@lua{bidi}{digits_mapped=true}} +\@namedef{bbl@ADJ@bidi.mapdigits@off}{% + \bbl@adjust@lua{bidi}{digits_mapped=false}} +% +\@namedef{bbl@ADJ@linebreak.sea@on}{% + \bbl@adjust@lua{linebreak}{sea_enabled=true}} +\@namedef{bbl@ADJ@linebreak.sea@off}{% + \bbl@adjust@lua{linebreak}{sea_enabled=false}} +\@namedef{bbl@ADJ@linebreak.cjk@on}{% + \bbl@adjust@lua{linebreak}{cjk_enabled=true}} +\@namedef{bbl@ADJ@linebreak.cjk@off}{% + \bbl@adjust@lua{linebreak}{cjk_enabled=false}} +\@namedef{bbl@ADJ@justify.arabic@on}{% + \bbl@adjust@lua{linebreak}{arabic.justify_enabled=true}} +\@namedef{bbl@ADJ@justify.arabic@off}{% + \bbl@adjust@lua{linebreak}{arabic.justify_enabled=false}} +% +\def\bbl@adjust@layout#1{% + \ifvmode + #1% + \expandafter\@gobble \fi - % == frenchspacing == - \ifcase\bbl@howloaded\in@true\else\in@false\fi - \ifin@\else\bbl@xin@{typography/frenchspacing}{\bbl@key@list}\fi - \ifin@ - \bbl@extras@wrap{\\\bbl@pre@fs}% - {\bbl@pre@fs}% - {\bbl@post@fs}% + {\bbl@error % The error is gobbled if everything went ok. + {Currently, layout related features can be adjusted only\\% + in vertical mode.}% + {Maybe things change in the future, but this is what it is.}}} +\@namedef{bbl@ADJ@layout.tabular@on}{% + \bbl@adjust@layout{\let\@tabular\bbl@NL@@tabular}} +\@namedef{bbl@ADJ@layout.tabular@off}{% + \bbl@adjust@layout{\let\@tabular\bbl@OL@@tabular}} +\@namedef{bbl@ADJ@layout.lists@on}{% + \bbl@adjust@layout{\let\list\bbl@NL@list}} +\@namedef{bbl@ADJ@layout.lists@off}{% + \bbl@adjust@layout{\let\list\bbl@OL@list}} +\@namedef{bbl@ADJ@hyphenation.extra@on}{% + \bbl@activateposthyphen} +% +\@namedef{bbl@ADJ@autoload.bcp47@on}{% + \bbl@bcpallowedtrue} +\@namedef{bbl@ADJ@autoload.bcp47@off}{% + \bbl@bcpallowedfalse} +\@namedef{bbl@ADJ@autoload.bcp47.prefix}#1{% + \def\bbl@bcp@prefix{#1}} +\def\bbl@bcp@prefix{bcp47-} +\@namedef{bbl@ADJ@autoload.options}#1{% + \def\bbl@autoload@options{#1}} +\let\bbl@autoload@bcpoptions\@empty +\@namedef{bbl@ADJ@autoload.bcp47.options}#1{% + \def\bbl@autoload@bcpoptions{#1}} +\newif\ifbbl@bcptoname +\@namedef{bbl@ADJ@bcp47.toname@on}{% + \bbl@bcptonametrue + \BabelEnsureInfo} +\@namedef{bbl@ADJ@bcp47.toname@off}{% + \bbl@bcptonamefalse} +\@namedef{bbl@ADJ@prehyphenation.disable@nohyphenation}{% + \directlua{ Babel.ignore_pre_char = function(node) + return (node.lang == \the\csname l@nohyphenation\endcsname) + end }} +\@namedef{bbl@ADJ@prehyphenation.disable@off}{% + \directlua{ Babel.ignore_pre_char = function(node) + return false + end }} +\@namedef{bbl@ADJ@select.write@shift}{% + \let\bbl@restorelastskip\relax + \def\bbl@savelastskip{% + \let\bbl@restorelastskip\relax + \ifvmode + \ifdim\lastskip=\z@ + \let\bbl@restorelastskip\nobreak + \else + \bbl@exp{% + \def\\\bbl@restorelastskip{% + \skip@=\the\lastskip + \\\nobreak \vskip-\skip@ \vskip\skip@}}% + \fi + \fi}} +\@namedef{bbl@ADJ@select.write@keep}{% + \let\bbl@restorelastskip\relax + \let\bbl@savelastskip\relax} +\@namedef{bbl@ADJ@select.write@omit}{% + \let\bbl@restorelastskip\relax + \def\bbl@savelastskip##1\bbl@restorelastskip{}} +% \end{macrocode} +% +% As the final task, load the code for lua. TODO: use babel name, override +% +% \begin{macrocode} +\ifx\directlua\@undefined\else + \ifx\bbl@luapatterns\@undefined + \input luababel.def \fi - % == Release saved transforms == - \bbl@release@transforms\relax % \relax closes the last item. - % == main == - \ifx\bbl@KVP@main\@nil % Restore only if not 'main' - \let\languagename\bbl@savelangname - \chardef\localeid\bbl@savelocaleid\relax - \fi} +\fi +% \end{macrocode} +% +% Continue with \LaTeX{}. +% +% \begin{macrocode} +% +%<*package> +% \end{macrocode} +% +% \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. +% +% 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. +% +% \begin{macrocode} +%<<*More package options>> +\DeclareOption{safe=none}{\let\bbl@opt@safe\@empty} +\DeclareOption{safe=bib}{\def\bbl@opt@safe{B}} +\DeclareOption{safe=ref}{\def\bbl@opt@safe{R}} +%<> +% \end{macrocode} +% +% \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. +% +% \begin{macrocode} +\bbl@trace{Cross referencing macros} +\ifx\bbl@opt@safe\@empty\else + \def\@newl@bel#1#2#3{% + {\@safe@activestrue + \bbl@ifunset{#1@#2}% + \relax + {\gdef\@multiplelabels{% + \@latex@warning@no@line{There were multiply-defined labels}}% + \@latex@warning@no@line{Label `#2' multiply defined}}% + \global\@namedef{#1@#2}{#3}}} +% \end{macrocode} +% +% \end{macro} +% +% \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. +% +% \begin{macrocode} + \CheckCommand*\@testdef[3]{% + \def\reserved@a{#3}% + \expandafter\ifx\csname#1@#2\endcsname\reserved@a + \else + \@tempswatrue + \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. +% +% \begin{macrocode} + \def\@testdef#1#2#3{% TODO. With @samestring? + \@safe@activestrue + \expandafter\let\expandafter\bbl@tempa\csname #1@#2\endcsname + \def\bbl@tempb{#3}% + \@safe@activesfalse + \ifx\bbl@tempa\relax + \else + \edef\bbl@tempa{\expandafter\strip@prefix\meaning\bbl@tempa}% + \fi + \edef\bbl@tempb{\expandafter\strip@prefix\meaning\bbl@tempb}% + \ifx\bbl@tempa\bbl@tempb + \else + \@tempswatrue + \fi} +\fi +% \end{macrocode} +% +% \end{macro} +% +% \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. +% +% \begin{macrocode} +\bbl@xin@{R}\bbl@opt@safe +\ifin@ + \bbl@redefinerobust\ref#1{% + \@safe@activestrue\org@ref{#1}\@safe@activesfalse} + \bbl@redefinerobust\pageref#1{% + \@safe@activestrue\org@pageref{#1}\@safe@activesfalse} +\else + \let\org@ref\ref + \let\org@pageref\pageref +\fi +% \end{macrocode} +% +% \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{macrocode} +\bbl@xin@{B}\bbl@opt@safe +\ifin@ + \bbl@redefine\@citex[#1]#2{% + \@safe@activestrue\edef\@tempa{#2}\@safe@activesfalse + \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. +% +% \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). +% +% (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{% + \@safe@activestrue\edef\@tempa{#3}\@safe@activesfalse + \org@@citex[#1][#2]{\@tempa}}% + }{}} +% \end{macrocode} +% +% The package \pkg{cite} has a definition of |\@citex| where the +% shorthands need to be turned off in both arguments. +% +% \begin{macrocode} + \AtBeginDocument{% + \@ifpackageloaded{cite}{% + \def\@citex[#1]#2{% + \@safe@activestrue\org@@citex[#1]{#2}\@safe@activesfalse}% + }{}} +% \end{macrocode} +% +% \end{macro} +% +% \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{% + \@safe@activestrue\org@nocite{#1}\@safe@activesfalse} % \end{macrocode} % -% Depending on whether or not the language exists (based on -% |\date|), we define two macros. Remember -% |\bbl@startcommands| opens a group. +% \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{macrocode} -\def\bbl@provide@new#1{% - \@namedef{date#1}{}% marks lang exists - required by \StartBabelCommands - \@namedef{extras#1}{}% - \@namedef{noextras#1}{}% - \bbl@startcommands*{#1}{captions}% - \ifx\bbl@KVP@captions\@nil % and also if import, implicit - \def\bbl@tempb##1{% elt for \bbl@captionslist - \ifx##1\@empty\else - \bbl@exp{% - \\\SetString\\##1{% - \\\bbl@nocaption{\bbl@stripslash##1}{#1\bbl@stripslash##1}}}% - \expandafter\bbl@tempb - \fi}% - \expandafter\bbl@tempb\bbl@captionslist\@empty - \else - \ifx\bbl@initoload\relax - \bbl@read@ini{\bbl@KVP@captions}2% % Here letters cat = 11 - \else - \bbl@read@ini{\bbl@initoload}2% % Same - \fi - \fi - \StartBabelCommands*{#1}{date}% - \ifx\bbl@KVP@import\@nil - \bbl@exp{% - \\\SetString\\\today{\\\bbl@nocaption{today}{#1today}}}% - \else - \bbl@savetoday - \bbl@savedate - \fi - \bbl@endcommands - \bbl@load@basic{#1}% - % == hyphenmins == (only if new) - \bbl@exp{% - \gdef\<#1hyphenmins>{% - {\bbl@ifunset{bbl@lfthm@#1}{2}{\bbl@cs{lfthm@#1}}}% - {\bbl@ifunset{bbl@rgthm@#1}{3}{\bbl@cs{rgthm@#1}}}}}% - % == hyphenrules (also in renew) == - \bbl@provide@hyphens{#1}% - \ifx\bbl@KVP@main\@nil\else - \expandafter\main@language\expandafter{#1}% - \fi} + \bbl@redefine\bibcite{% + \bbl@cite@choice + \bibcite} +% \end{macrocode} % -\def\bbl@provide@renew#1{% - \ifx\bbl@KVP@captions\@nil\else - \StartBabelCommands*{#1}{captions}% - \bbl@read@ini{\bbl@KVP@captions}2% % Here all letters cat = 11 - \EndBabelCommands - \fi - \ifx\bbl@KVP@import\@nil\else - \StartBabelCommands*{#1}{date}% - \bbl@savetoday - \bbl@savedate - \EndBabelCommands - \fi - % == hyphenrules (also in new) == - \ifx\bbl@lbkflag\@empty - \bbl@provide@hyphens{#1}% - \fi} +% \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{macrocode} + \def\bbl@bibcite#1#2{% + \org@bibcite{#1}{\@safe@activesfalse#2}} % \end{macrocode} % -% Load the basic parameters (ids, typography, counters, and a few -% more), while captions and dates are left out. But it may happen some -% data has been loaded before automatically, so we first discard the -% saved values. (TODO. But preserving previous values would be useful.) +% \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{macrocode} -\def\bbl@load@basic#1{% - \ifcase\bbl@howloaded\or\or - \ifcase\csname bbl@llevel@\languagename\endcsname - \bbl@csarg\let{lname@\languagename}\relax - \fi - \fi - \bbl@ifunset{bbl@lname@#1}% - {\def\BabelBeforeIni##1##2{% - \begingroup - \let\bbl@ini@captions@aux\@gobbletwo - \def\bbl@inidate ####1.####2.####3.####4\relax ####5####6{}% - \bbl@read@ini{##1}1% - \ifx\bbl@initoload\relax\endinput\fi - \endgroup}% - \begingroup % boxed, to avoid extra spaces: - \ifx\bbl@initoload\relax - \bbl@input@texini{#1}% - \else - \setbox\z@\hbox{\BabelBeforeIni{\bbl@initoload}{}}% - \fi - \endgroup}% - {}} + \def\bbl@cite@choice{% + \global\let\bibcite\bbl@bibcite + \@ifpackageloaded{natbib}{\global\let\bibcite\org@bibcite}{}% + \@ifpackageloaded{cite}{\global\let\bibcite\org@bibcite}{}% + \global\let\bbl@cite@choice\relax} % \end{macrocode} % -% The |hyphenrules| option is handled with an auxiliary macro. +% 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} -\def\bbl@provide@hyphens#1{% - \let\bbl@tempa\relax - \ifx\bbl@KVP@hyphenrules\@nil\else - \bbl@replace\bbl@KVP@hyphenrules{ }{,}% - \bbl@foreach\bbl@KVP@hyphenrules{% - \ifx\bbl@tempa\relax % if not yet found - \bbl@ifsamestring{##1}{+}% - {{\bbl@exp{\\\addlanguage\}}}% - {}% - \bbl@ifunset{l@##1}% - {}% - {\bbl@exp{\let\bbl@tempa\}}% - \fi}% - \fi - \ifx\bbl@tempa\relax % if no opt or no language in opt found - \ifx\bbl@KVP@import\@nil - \ifx\bbl@initoload\relax\else - \bbl@exp{% and hyphenrules is not empty - \\\bbl@ifblank{\bbl@cs{hyphr@#1}}% - {}% - {\let\\\bbl@tempa\}}% - \fi - \else % if importing - \bbl@exp{% and hyphenrules is not empty - \\\bbl@ifblank{\bbl@cs{hyphr@#1}}% - {}% - {\let\\\bbl@tempa\}}% - \fi - \fi - \bbl@ifunset{bbl@tempa}% ie, relax or undefined - {\bbl@ifunset{l@#1}% no hyphenrules found - fallback - {\bbl@exp{\\\adddialect\\language}}% - {}}% so, l@ is ok - nothing to do - {\bbl@exp{\\\adddialect\\bbl@tempa}}}% found in opt list or ini + \AtBeginDocument{\bbl@cite@choice} +% \end{macrocode} +% +% \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{macrocode} + \bbl@redefine\@bibitem#1{% + \@safe@activestrue\org@@bibitem{#1}\@safe@activesfalse} +\else + \let\org@nocite\nocite + \let\org@@citex\@citex + \let\org@bibcite\bibcite + \let\org@@bibitem\@bibitem +\fi +% \end{macrocode} +% +% \end{macro} +% +% \subsection{Marks} +% +% \begin{macro}{\markright} +% Because the output routine is asynchronous, we must pass the +% current language attribute to the head lines. To achieve this we +% need to adapt the definition of |\markright| and |\markboth| +% somewhat. However, headlines and footlines can contain text +% outside marks; for that we must take some actions in the output +% routine if the 'headfoot' options is used. +% +% We need to make some redefinitions to the output routine +% to avoid an endless loop and to correctly handle the page number +% in bidi documents. +% +% \begin{macrocode} +\bbl@trace{Marks} +\IfBabelLayout{sectioning} + {\ifx\bbl@opt@headfoot\@nnil + \g@addto@macro\@resetactivechars{% + \set@typeset@protect + \expandafter\select@language@x\expandafter{\bbl@main@language}% + \let\protect\noexpand + \ifcase\bbl@bidimode\else % Only with bidi. See also above + \edef\thepage{% + \noexpand\babelsublr{\unexpanded\expandafter{\thepage}}}% + \fi}% + \fi} + {\ifbbl@single\else + \bbl@ifunset{markright }\bbl@redefine\bbl@redefinerobust + \markright#1{% + \bbl@ifblank{#1}% + {\org@markright{}}% + {\toks@{#1}% + \bbl@exp{% + \\\org@markright{\\\protect\\\foreignlanguage{\languagename}% + {\\\protect\\\bbl@restore@actives\the\toks@}}}}}% +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\markboth} +% \begin{macro}{\@mkboth} +% The definition of |\markboth| is equivalent to that of +% |\markright|, except that we need two token registers. The +% documentclasses \cls{report} and \cls{book} define and set the +% headings for the page. While doing so they also store a copy of +% |\markboth| in |\@mkboth|. Therefore we need to check whether +% |\@mkboth| has already been set. If so we neeed to do that again +% with the new definition of |\markboth|. (As of Oct 2019, \LaTeX{} +% stores the definition in an intermediate macro, so it's not +% necessary anymore, but it's preserved for older versions.) +% +% \begin{macrocode} + \ifx\@mkboth\markboth + \def\bbl@tempc{\let\@mkboth\markboth} + \else + \def\bbl@tempc{} + \fi + \bbl@ifunset{markboth }\bbl@redefine\bbl@redefinerobust + \markboth#1#2{% + \protected@edef\bbl@tempb##1{% + \protect\foreignlanguage + {\languagename}{\protect\bbl@restore@actives##1}}% + \bbl@ifblank{#1}% + {\toks@{}}% + {\toks@\expandafter{\bbl@tempb{#1}}}% + \bbl@ifblank{#2}% + {\@temptokena{}}% + {\@temptokena\expandafter{\bbl@tempb{#2}}}% + \bbl@exp{\\\org@markboth{\the\toks@}{\the\@temptokena}}} + \bbl@tempc + \fi} % end ifbbl@single, end \IfBabelLayout % \end{macrocode} % -% The reader of |babel-...tex| files. We reset temporarily some -% catcodes. +% \end{macro} +% \end{macro} % -% \begin{macrocode} -\def\bbl@input@texini#1{% - \bbl@bsphack - \bbl@exp{% - \catcode`\\\%=14 \catcode`\\\\=0 - \catcode`\\\{=1 \catcode`\\\}=2 - \lowercase{\\\InputIfFileExists{babel-#1.tex}{}{}}% - \catcode`\\\%=\the\catcode`\%\relax - \catcode`\\\\=\the\catcode`\\\relax - \catcode`\\\{=\the\catcode`\{\relax - \catcode`\\\}=\the\catcode`\}\relax}% - \bbl@esphack} -% \end{macrocode} +% \subsection{Preventing clashes with other packages} % -% The following macros read and store |ini| files (but don't process -% them). For each line, there are 3 possible actions: ignore if starts -% with |;|, switch section if starts with |[|, and store otherwise. -% There are used in the first step of |\bbl@read@ini|. +% \subsubsection{\pkg{ifthen}} % -% \begin{macrocode} -\def\bbl@iniline#1\bbl@iniline{% - \@ifnextchar[\bbl@inisect{\@ifnextchar;\bbl@iniskip\bbl@inistore}#1\@@}% ] -\def\bbl@inisect[#1]#2\@@{\def\bbl@section{#1}} -\def\bbl@iniskip#1\@@{}% if starts with ; -\def\bbl@inistore#1=#2\@@{% full (default) - \bbl@trim@def\bbl@tempa{#1}% - \bbl@trim\toks@{#2}% - \bbl@xin@{;\bbl@section/\bbl@tempa;}{\bbl@key@list}% - \ifin@\else - \bbl@exp{% - \\\g@addto@macro\\\bbl@inidata{% - \\\bbl@elt{\bbl@section}{\bbl@tempa}{\the\toks@}}}% - \fi} -\def\bbl@inistore@min#1=#2\@@{% minimal (maybe set in \bbl@read@ini) - \bbl@trim@def\bbl@tempa{#1}% - \bbl@trim\toks@{#2}% - \bbl@xin@{.identification.}{.\bbl@section.}% - \ifin@ - \bbl@exp{\\\g@addto@macro\\\bbl@inidata{% - \\\bbl@elt{identification}{\bbl@tempa}{\the\toks@}}}% - \fi} -% \end{macrocode} +% \begin{macro}{\ifthenelse} % -% Now, the ‘main loop’, which \textbf{**must be executed inside a -% group**}. At this point, |\bbl@inidata| may contain data declared in -% |\babelprovide|, with ‘slashed’ keys. There are 3 steps: first read -% the ini file and store it; then traverse the stored values, and -% process some groups if required (date, captions, labels, counters); -% finally, ‘export’ some values by defining global macros -% (identification, typography, characters, numbers). The second -% argument is 0 when called to read the minimal data for fonts; with -% |\babelprovide| it's either 1 or 2. +% 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. +% +% 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. % % \begin{macrocode} -\ifx\bbl@readstream\@undefined - \csname newread\endcsname\bbl@readstream -\fi -\def\bbl@read@ini#1#2{% - \global\let\bbl@extend@ini\@gobble - \openin\bbl@readstream=babel-#1.ini - \ifeof\bbl@readstream - \bbl@error - {There is no ini file for the requested language\\% - (#1). Perhaps you misspelled it or your installation\\% - is not complete.}% - {Fix the name or reinstall babel.}% - \else - % == Store ini data in \bbl@inidata == - \catcode`\[=12 \catcode`\]=12 \catcode`\==12 \catcode`\&=12 - \catcode`\;=12 \catcode`\|=12 \catcode`\%=14 \catcode`\-=12 - \bbl@info{Importing - \ifcase#2font and identification \or basic \fi - data for \languagename\\% - from babel-#1.ini. Reported}% - \ifnum#2=\z@ - \global\let\bbl@inidata\@empty - \let\bbl@inistore\bbl@inistore@min % Remember it's local - \fi - \def\bbl@section{identification}% - \bbl@exp{\\\bbl@inistore tag.ini=#1\\\@@}% - \bbl@inistore load.level=#2\@@ - \loop - \if T\ifeof\bbl@readstream F\fi T\relax % Trick, because inside \loop - \endlinechar\m@ne - \read\bbl@readstream to \bbl@line - \endlinechar`\^^M - \ifx\bbl@line\@empty\else - \expandafter\bbl@iniline\bbl@line\bbl@iniline - \fi - \repeat - % == Process stored data == - \bbl@csarg\xdef{lini@\languagename}{#1}% - \bbl@read@ini@aux - % == 'Export' data == - \bbl@ini@exports{#2}% - \global\bbl@csarg\let{inidata@\languagename}\bbl@inidata - \global\let\bbl@inidata\@empty - \bbl@exp{\\\bbl@add@list\\\bbl@ini@loaded{\languagename}}% - \bbl@toglobal\bbl@ini@loaded - \fi} -\def\bbl@read@ini@aux{% - \let\bbl@savestrings\@empty - \let\bbl@savetoday\@empty - \let\bbl@savedate\@empty - \def\bbl@elt##1##2##3{% - \def\bbl@section{##1}% - \in@{=date.}{=##1}% Find a better place - \ifin@ - \bbl@ini@calendar{##1}% - \fi - \bbl@ifunset{bbl@inikv@##1}{}% - {\csname bbl@inikv@##1\endcsname{##2}{##3}}}% - \bbl@inidata} +\bbl@trace{Preventing clashes with other packages} +\bbl@xin@{R}\bbl@opt@safe +\ifin@ + \AtBeginDocument{% + \@ifpackageloaded{ifthen}{% + \bbl@redefine@long\ifthenelse#1#2#3{% + \let\bbl@temp@pref\pageref + \let\pageref\org@pageref + \let\bbl@temp@ref\ref + \let\ref\org@ref + \@safe@activestrue + \org@ifthenelse{#1}% + {\let\pageref\bbl@temp@pref + \let\ref\bbl@temp@ref + \@safe@activesfalse + #2}% + {\let\pageref\bbl@temp@pref + \let\ref\bbl@temp@ref + \@safe@activesfalse + #3}% + }% + }{}% + } % \end{macrocode} % -% A variant to be used when the ini file has been already loaded, -% because it's not the first |\babelprovide| for this language. +% \end{macro} +% +% \subsubsection{\pkg{varioref}} +% +% \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|. % % \begin{macrocode} -\def\bbl@extend@ini@aux#1{% - \bbl@startcommands*{#1}{captions}% - % Activate captions/... and modify exports - \bbl@csarg\def{inikv@captions.licr}##1##2{% - \setlocalecaption{#1}{##1}{##2}}% - \def\bbl@inikv@captions##1##2{% - \bbl@ini@captions@aux{##1}{##2}}% - \def\bbl@stringdef##1##2{\gdef##1{##2}}% - \def\bbl@exportkey##1##2##3{% - \bbl@ifunset{bbl@@kv@##2}{}% - {\expandafter\ifx\csname bbl@@kv@##2\endcsname\@empty\else - \bbl@exp{\global\let\\}% - \fi}}% - % As with \bbl@read@ini, but with some changes - \bbl@read@ini@aux - \bbl@ini@exports\tw@ - % Update inidata@lang by pretending the ini is read. - \def\bbl@elt##1##2##3{% - \def\bbl@section{##1}% - \bbl@iniline##2=##3\bbl@iniline}% - \csname bbl@inidata@#1\endcsname - \global\bbl@csarg\let{inidata@#1}\bbl@inidata - \StartBabelCommands*{#1}{date}% And from the import stuff - \def\bbl@stringdef##1##2{\gdef##1{##2}}% - \bbl@savetoday - \bbl@savedate - \bbl@endcommands} + \AtBeginDocument{% + \@ifpackageloaded{varioref}{% + \bbl@redefine\@@vpageref#1[#2]#3{% + \@safe@activestrue + \org@@@vpageref{#1}[#2]{#3}% + \@safe@activesfalse}% + \bbl@redefine\vrefpagenum#1#2{% + \@safe@activestrue + \org@vrefpagenum{#1}{#2}% + \@safe@activesfalse}% % \end{macrocode} % -% A somewhat hackish tool to handle calendar sections. To be improved. +% 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} -\def\bbl@ini@calendar#1{% - \lowercase{\def\bbl@tempa{=#1=}}% - \bbl@replace\bbl@tempa{=date.gregorian}{}% - \bbl@replace\bbl@tempa{=date.}{}% - \in@{.licr=}{#1=}% - \ifin@ - \ifcase\bbl@engine - \bbl@replace\bbl@tempa{.licr=}{}% - \else - \let\bbl@tempa\relax - \fi - \fi - \ifx\bbl@tempa\relax\else - \bbl@replace\bbl@tempa{=}{}% - \bbl@exp{% - \def\####1####2{% - \\\bbl@inidate####1...\relax{####2}{\bbl@tempa}}}% - \fi} + \expandafter\def\csname Ref \endcsname#1{% + \protected@edef\@tempa{\org@ref{#1}}\expandafter\MakeUppercase\@tempa} + }{}% + } +\fi % \end{macrocode} % -% A key with a slash in |\babelprovide| replaces the value in the |ini| -% file (which is ignored altogether). The mechanism is simple (but -% suboptimal): add the data to the |ini| one (at this point the |ini| -% file has not yet been read), and define a dummy macro. When the |ini| -% file is read, just skip the corresponding key and reset the macro (in -% |\bbl@inistore| above). -% +% \end{macro} +% \end{macro} +% \end{macro} +% +% \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{macrocode} -\def\bbl@renewinikey#1/#2\@@#3{% - \edef\bbl@tempa{\zap@space #1 \@empty}% section - \edef\bbl@tempb{\zap@space #2 \@empty}% key - \bbl@trim\toks@{#3}% value - \bbl@exp{% - \edef\\\bbl@key@list{\bbl@key@list \bbl@tempa/\bbl@tempb;}% - \\\g@addto@macro\\\bbl@inidata{% - \\\bbl@elt{\bbl@tempa}{\bbl@tempb}{\the\toks@}}}}% +\AtEndOfPackage{% + \AtBeginDocument{% + \@ifpackageloaded{hhline}% + {\expandafter\ifx\csname normal@char\string:\endcsname\relax + \else + \makeatletter + \def\@currname{hhline}\input{hhline.sty}\makeatother + \fi}% + {}}} % \end{macrocode} % -% The previous assignments are local, so we need to export them. If -% the value is empty, we can provide a default value. +% \end{macro} +% +% \begin{macro}{\substitutefontfamily} +% +% 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. % % \begin{macrocode} -\def\bbl@exportkey#1#2#3{% - \bbl@ifunset{bbl@@kv@#2}% - {\bbl@csarg\gdef{#1@\languagename}{#3}}% - {\expandafter\ifx\csname bbl@@kv@#2\endcsname\@empty - \bbl@csarg\gdef{#1@\languagename}{#3}% - \else - \bbl@exp{\global\let\\}% - \fi}} +\def\substitutefontfamily#1#2#3{% + \lowercase{\immediate\openout15=#1#2.fd\relax}% + \immediate\write15{% + \string\ProvidesFile{#1#2.fd}% + [\the\year/\two@digits{\the\month}/\two@digits{\the\day} + \space generated font description file]^^J + \string\DeclareFontFamily{#1}{#2}{}^^J + \string\DeclareFontShape{#1}{#2}{m}{n}{<->ssub * #3/m/n}{}^^J + \string\DeclareFontShape{#1}{#2}{m}{it}{<->ssub * #3/m/it}{}^^J + \string\DeclareFontShape{#1}{#2}{m}{sl}{<->ssub * #3/m/sl}{}^^J + \string\DeclareFontShape{#1}{#2}{m}{sc}{<->ssub * #3/m/sc}{}^^J + \string\DeclareFontShape{#1}{#2}{b}{n}{<->ssub * #3/bx/n}{}^^J + \string\DeclareFontShape{#1}{#2}{b}{it}{<->ssub * #3/bx/it}{}^^J + \string\DeclareFontShape{#1}{#2}{b}{sl}{<->ssub * #3/bx/sl}{}^^J + \string\DeclareFontShape{#1}{#2}{b}{sc}{<->ssub * #3/bx/sc}{}^^J + }% + \closeout15 + } +\@onlypreamble\substitutefontfamily % \end{macrocode} % -% Key-value pairs are treated differently depending on the section in -% the |ini| file. The following macros are the readers for -% |identification| and |typography|. Note |\bbl@ini@exports| -% is called always (via |\bbl@inisec|), while |\bbl@after@ini| must be -% called explicitly after |\bbl@read@ini| if necessary. +% \end{macro} % -% \begin{macrocode} -\def\bbl@iniwarning#1{% - \bbl@ifunset{bbl@@kv@identification.warning#1}{}% - {\bbl@warning{% - From babel-\bbl@cs{lini@\languagename}.ini:\\% - \bbl@cs{@kv@identification.warning#1}\\% - Reported }}} +% \subsection{Encoding and fonts} % -\let\bbl@release@transforms\@empty +% Because documents may use non-ASCII font encodings, we make sure +% that the logos of \TeX\ and \LaTeX\ always come out in the right +% encoding. There is a list of non-ASCII encodings. Requested +% encodings are currently stored in |\@fontenc@load@list|. If a +% non-ASCII has been loaded, we define versions of |\TeX| and |\LaTeX| +% for them using |\ensureascii|. The default ASCII encoding is set, +% too (in reverse order): the ``main'' encoding (when the document +% begins), the last loaded, or |OT1|. % -\def\bbl@ini@exports#1{% - % Identification always exported - \bbl@iniwarning{}% - \ifcase\bbl@engine - \bbl@iniwarning{.pdflatex}% - \or - \bbl@iniwarning{.lualatex}% - \or - \bbl@iniwarning{.xelatex}% - \fi% - \bbl@exportkey{llevel}{identification.load.level}{}% - \bbl@exportkey{elname}{identification.name.english}{}% - \bbl@exp{\\\bbl@exportkey{lname}{identification.name.opentype}% - {\csname bbl@elname@\languagename\endcsname}}% - \bbl@exportkey{tbcp}{identification.tag.bcp47}{}% - \bbl@exportkey{lbcp}{identification.language.tag.bcp47}{}% - \bbl@exportkey{lotf}{identification.tag.opentype}{dflt}% - \bbl@exportkey{esname}{identification.script.name}{}% - \bbl@exp{\\\bbl@exportkey{sname}{identification.script.name.opentype}% - {\csname bbl@esname@\languagename\endcsname}}% - \bbl@exportkey{sbcp}{identification.script.tag.bcp47}{}% - \bbl@exportkey{sotf}{identification.script.tag.opentype}{DFLT}% - % Also maps bcp47 -> languagename - \ifbbl@bcptoname - \bbl@csarg\xdef{bcp@map@\bbl@cl{tbcp}}{\languagename}% - \fi - % Conditional - \ifnum#1>\z@ % 0 = only info, 1, 2 = basic, (re)new - \bbl@exportkey{lnbrk}{typography.linebreaking}{h}% - \bbl@exportkey{hyphr}{typography.hyphenrules}{}% - \bbl@exportkey{lfthm}{typography.lefthyphenmin}{2}% - \bbl@exportkey{rgthm}{typography.righthyphenmin}{3}% - \bbl@exportkey{prehc}{typography.prehyphenchar}{}% - \bbl@exportkey{hyotl}{typography.hyphenate.other.locale}{}% - \bbl@exportkey{hyots}{typography.hyphenate.other.script}{}% - \bbl@exportkey{intsp}{typography.intraspace}{}% - \bbl@exportkey{frspc}{typography.frenchspacing}{u}% - \bbl@exportkey{chrng}{characters.ranges}{}% - \bbl@exportkey{quote}{characters.delimiters.quotes}{}% - \bbl@exportkey{dgnat}{numbers.digits.native}{}% - \ifnum#1=\tw@ % only (re)new - \bbl@exportkey{rqtex}{identification.require.babel}{}% - \bbl@toglobal\bbl@savetoday - \bbl@toglobal\bbl@savedate - \bbl@savestrings +% \begin{macro}{\ensureascii} +% +% \begin{macrocode} +\bbl@trace{Encoding and fonts} +\newcommand\BabelNonASCII{LGR,X2,OT2,OT3,OT6,LHE,LWN,LMA,LMC,LMS,LMU} +\newcommand\BabelNonText{TS1,T3,TS3} +\let\org@TeX\TeX +\let\org@LaTeX\LaTeX +\let\ensureascii\@firstofone +\AtBeginDocument{% + \def\@elt#1{,#1,}% + \edef\bbl@tempa{\expandafter\@gobbletwo\@fontenc@load@list}% + \let\@elt\relax + \let\bbl@tempb\@empty + \def\bbl@tempc{OT1}% + \bbl@foreach\BabelNonASCII{% LGR loaded in a non-standard way + \bbl@ifunset{T@#1}{}{\def\bbl@tempb{#1}}}% + \bbl@foreach\bbl@tempa{% + \bbl@xin@{#1}{\BabelNonASCII}% + \ifin@ + \def\bbl@tempb{#1}% Store last non-ascii + \else\bbl@xin@{#1}{\BabelNonText}% Pass + \ifin@\else + \def\bbl@tempc{#1}% Store last ascii + \fi + \fi}% + \ifx\bbl@tempb\@empty\else + \bbl@xin@{,\cf@encoding,}{,\BabelNonASCII,\BabelNonText,}% + \ifin@\else + \edef\bbl@tempc{\cf@encoding}% The default if ascii wins \fi + \edef\ensureascii#1{% + {\noexpand\fontencoding{\bbl@tempc}\noexpand\selectfont#1}}% + \DeclareTextCommandDefault{\TeX}{\ensureascii{\org@TeX}}% + \DeclareTextCommandDefault{\LaTeX}{\ensureascii{\org@LaTeX}}% \fi} % \end{macrocode} % -% A shared handler for key=val lines to be stored in -% |\bbl@@kv@
.|. +% \end{macro} +% +% Now comes the old deprecated stuff (with a little change in 3.9l, +% for \textsf{fontspec}). The first thing we need to do is to +% determine, at |\begin{document}|, which latin fontencoding to use. +% +% \begin{macro}{\latinencoding} +% When text is being typeset in an encoding other than `latin' +% (\texttt{OT1} or \texttt{T1}), it would be nice to still have +% Roman numerals come out in the Latin encoding. +% So we first assume that the current encoding at the end +% of processing the package is the Latin encoding. % % \begin{macrocode} -\def\bbl@inikv#1#2{% key=value - \toks@{#2}% This hides #'s from ini values - \bbl@csarg\edef{@kv@\bbl@section.#1}{\the\toks@}} +\AtEndOfPackage{\edef\latinencoding{\cf@encoding}} % \end{macrocode} % -% By default, the following sections are just read. Actions are taken -% later. +% But this might be overruled with a later loading of the package +% \pkg{fontenc}. Therefore we check at the execution of +% |\begin{document}| whether it was loaded with the \Lopt{T1} +% option. The normal way to do this (using |\@ifpackageloaded|) is +% disabled for this package. Now we have to revert to parsing the +% internal macro |\@filelist| which contains all the filenames +% loaded. % % \begin{macrocode} -\let\bbl@inikv@identification\bbl@inikv -\let\bbl@inikv@typography\bbl@inikv -\let\bbl@inikv@characters\bbl@inikv -\let\bbl@inikv@numbers\bbl@inikv +\AtBeginDocument{% + \@ifpackageloaded{fontspec}% + {\xdef\latinencoding{% + \ifx\UTFencname\@undefined + EU\ifcase\bbl@engine\or2\or1\fi + \else + \UTFencname + \fi}}% + {\gdef\latinencoding{OT1}% + \ifx\cf@encoding\bbl@t@one + \xdef\latinencoding{\bbl@t@one}% + \else + \def\@elt#1{,#1,}% + \edef\bbl@tempa{\expandafter\@gobbletwo\@fontenc@load@list}% + \let\@elt\relax + \bbl@xin@{,T1,}\bbl@tempa + \ifin@ + \xdef\latinencoding{\bbl@t@one}% + \fi + \fi}} % \end{macrocode} % -% Additive numerals require an additional definition. When |.1| is -% found, two macros are defined -- the basic one, without |.1| called -% by |\localenumeral|, and another one preserving the trailing |.1| for -% the ‘units’. +% \end{macro} % -% \begin{macrocode} -\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$}% - \ifin@ - \bbl@replace\bbl@tempc{.1}{}% - \bbl@csarg\protected@xdef{cntr@\bbl@tempc @\languagename}{% - \noexpand\bbl@alphnumeral{\bbl@tempc}}% - \fi - \in@{.F.}{#1}% - \ifin@\else\in@{.S.}{#1}\fi - \ifin@ - \bbl@csarg\protected@xdef{cntr@#1@\languagename}{\bbl@tempb*}% - \else - \toks@{}% Required by \bbl@buildifcase, which returns \bbl@tempa - \expandafter\bbl@buildifcase\bbl@tempb* \\ % Space after \\ - \bbl@csarg{\global\expandafter\let}{cntr@#1@\languagename}\bbl@tempa - \fi} +% \begin{macro}{\latintext} +% Then we can define the command |\latintext| which is a +% declarative switch to a latin font-encoding. Usage of this macro +% is deprecated. +% +% \begin{macrocode} +\DeclareRobustCommand{\latintext}{% + \fontencoding{\latinencoding}\selectfont + \def\encodingdefault{\latinencoding}} % \end{macrocode} % -% Now |captions| and |captions.licr|, depending on the engine. And -% below also for dates. They rely on a few auxiliary macros. It is -% expected the ini file provides the complete set in Unicode and LICR, -% in that order. +% \end{macro} +% +% \begin{macro}{\textlatin} +% This command takes an argument which is then typeset using the +% requested font encoding. In order to avoid many encoding switches +% it operates in a local scope. % % \begin{macrocode} -\ifcase\bbl@engine - \bbl@csarg\def{inikv@captions.licr}#1#2{% - \bbl@ini@captions@aux{#1}{#2}} +\ifx\@undefined\DeclareTextFontCommand + \DeclareRobustCommand{\textlatin}[1]{\leavevmode{\latintext #1}} \else - \def\bbl@inikv@captions#1#2{% - \bbl@ini@captions@aux{#1}{#2}} + \DeclareTextFontCommand{\textlatin}{\latintext} \fi % \end{macrocode} % -% The auxiliary macro for captions define |\name|. +% For several functions, we need to execute some code with +% |\selectfont|. With \LaTeX\ 2021-06-01, there is a hook for this +% purpose, but in older versions the \LaTeX{} command is patched (the +% latter solution will be eventually removed). % % \begin{macrocode} -\def\bbl@ini@captions@template#1#2{% string language tempa=capt-name - \bbl@replace\bbl@tempa{.template}{}% - \def\bbl@toreplace{#1{}}% - \bbl@replace\bbl@toreplace{[ ]}{\nobreakspace{}}% - \bbl@replace\bbl@toreplace{[[}{\csname}% - \bbl@replace\bbl@toreplace{[}{\csname the}% - \bbl@replace\bbl@toreplace{]]}{name\endcsname{}}% - \bbl@replace\bbl@toreplace{]}{\endcsname{}}% - \bbl@xin@{,\bbl@tempa,}{,chapter,appendix,part,}% - \ifin@ - \@nameuse{bbl@patch\bbl@tempa}% - \global\bbl@csarg\let{\bbl@tempa fmt@#2}\bbl@toreplace - \fi - \bbl@xin@{,\bbl@tempa,}{,figure,table,}% - \ifin@ - \toks@\expandafter{\bbl@toreplace}% - \bbl@exp{\gdef\{\the\toks@}}% - \fi} -\def\bbl@ini@captions@aux#1#2{% - \bbl@trim@def\bbl@tempa{#1}% - \bbl@xin@{.template}{\bbl@tempa}% - \ifin@ - \bbl@ini@captions@template{#2}\languagename - \else - \bbl@ifblank{#2}% - {\bbl@exp{% - \toks@{\\\bbl@nocaption{\bbl@tempa}{\languagename\bbl@tempa name}}}}% - {\bbl@trim\toks@{#2}}% - \bbl@exp{% - \\\bbl@add\\\bbl@savestrings{% - \\\SetString\<\bbl@tempa name>{\the\toks@}}}% - \toks@\expandafter{\bbl@captionslist}% - \bbl@exp{\\\in@{\<\bbl@tempa name>}{\the\toks@}}% - \ifin@\else - \bbl@exp{% - \\\bbl@add\{\<\bbl@tempa name>}% - \\\bbl@toglobal\}% - \fi - \fi} +\bbl@ifformatlater{2021-06-01}% + {\def\bbl@patchfont#1{\AddToHook{selectfont}{#1}}} + {\def\bbl@patchfont#1{% + \expandafter\bbl@add\csname selectfont \endcsname{#1}% + \expandafter\bbl@toglobal\csname selectfont \endcsname}} % \end{macrocode} % -% \textbf{Labels.} Captions must contain just strings, no -% format at all, so there is new group in ini files. -% -% \begin{macrocode} -\def\bbl@list@the{% - part,chapter,section,subsection,subsubsection,paragraph,% - subparagraph,enumi,enumii,enumiii,enumiv,equation,figure,% - table,page,footnote,mpfootnote,mpfn} -\def\bbl@map@cnt#1{% #1:roman,etc, // #2:enumi,etc - \bbl@ifunset{bbl@map@#1@\languagename}% - {\@nameuse{#1}}% - {\@nameuse{bbl@map@#1@\languagename}}} -\def\bbl@inikv@labels#1#2{% - \in@{.map}{#1}% - \ifin@ - \ifx\bbl@KVP@labels\@nil\else - \bbl@xin@{ map }{ \bbl@KVP@labels\space}% - \ifin@ - \def\bbl@tempc{#1}% - \bbl@replace\bbl@tempc{.map}{}% - \in@{,#2,}{,arabic,roman,Roman,alph,Alph,fnsymbol,}% - \bbl@exp{% - \gdef\% - {\ifin@\<#2>\else\\\localecounter{#2}\fi}}% - \bbl@foreach\bbl@list@the{% - \bbl@ifunset{the##1}{}% - {\bbl@exp{\let\\\bbl@tempd\}% - \bbl@exp{% - \\\bbl@sreplace\% - {\<\bbl@tempc>{##1}}{\\\bbl@map@cnt{\bbl@tempc}{##1}}% - \\\bbl@sreplace\% - {\<\@empty @\bbl@tempc>\}{\\\bbl@map@cnt{\bbl@tempc}{##1}}}% - \expandafter\ifx\csname the##1\endcsname\bbl@tempd\else - \toks@\expandafter\expandafter\expandafter{% - \csname the##1\endcsname}% - \expandafter\xdef\csname the##1\endcsname{{\the\toks@}}% - \fi}}% - \fi - \fi - % - \else - % - % The following code is still under study. You can test it and make - % suggestions. Eg, enumerate.2 = ([enumi]).([enumii]). It's - % language dependent. - \in@{enumerate.}{#1}% - \ifin@ - \def\bbl@tempa{#1}% - \bbl@replace\bbl@tempa{enumerate.}{}% - \def\bbl@toreplace{#2}% - \bbl@replace\bbl@toreplace{[ ]}{\nobreakspace{}}% - \bbl@replace\bbl@toreplace{[}{\csname the}% - \bbl@replace\bbl@toreplace{]}{\endcsname{}}% - \toks@\expandafter{\bbl@toreplace}% - % TODO. Execute only once: - \bbl@exp{% - \\\bbl@add\{% - \\\babel@save\% - \def\{\the\toks@}}% - \\\bbl@toglobal\}% - \fi - \fi} -% \end{macrocode} +% \end{macro} % -% To show correctly some captions in a few languages, we need to patch -% some internal macros, because the order is hardcoded. For example, in -% Japanese the chapter number is surrounded by two string, while in -% Hungarian is placed after. These replacement works in many classes, -% but not all. Actually, the following lines are somewhat tentative. +% \subsection{Basic bidi support} % -% \begin{macrocode} -\def\bbl@chaptype{chapter} -\ifx\@makechapterhead\@undefined - \let\bbl@patchchapter\relax -\else\ifx\thechapter\@undefined - \let\bbl@patchchapter\relax -\else\ifx\ps@headings\@undefined - \let\bbl@patchchapter\relax -\else - \def\bbl@patchchapter{% - \global\let\bbl@patchchapter\relax - \bbl@add\appendix{\def\bbl@chaptype{appendix}}% Not harmful, I hope - \bbl@toglobal\appendix - \bbl@sreplace\ps@headings - {\@chapapp\ \thechapter}% - {\bbl@chapterformat}% - \bbl@toglobal\ps@headings - \bbl@sreplace\chaptermark - {\@chapapp\ \thechapter}% - {\bbl@chapterformat}% - \bbl@toglobal\chaptermark - \bbl@sreplace\@makechapterhead - {\@chapapp\space\thechapter}% - {\bbl@chapterformat}% - \bbl@toglobal\@makechapterhead - \gdef\bbl@chapterformat{% - \bbl@ifunset{bbl@\bbl@chaptype fmt@\languagename}% - {\@chapapp\space\thechapter} - {\@nameuse{bbl@\bbl@chaptype fmt@\languagename}}}} - \let\bbl@patchappendix\bbl@patchchapter -\fi\fi\fi -\ifx\@part\@undefined - \let\bbl@patchpart\relax -\else - \def\bbl@patchpart{% - \global\let\bbl@patchpart\relax - \bbl@sreplace\@part - {\partname\nobreakspace\thepart}% - {\bbl@partformat}% - \bbl@toglobal\@part - \gdef\bbl@partformat{% - \bbl@ifunset{bbl@partfmt@\languagename}% - {\partname\nobreakspace\thepart} - {\@nameuse{bbl@partfmt@\languagename}}}} -\fi -% \end{macrocode} +% \textbf{Work in progress.} This code is currently placed here for +% practical reasons. It will be moved to the correct place soon, I +% hope. % -% \textbf{Date.} TODO. Document +% It is loosely based on |rlbabel.def|, but most of it has been +% developed from scratch. This \babel{} module (by Johannes Braams and +% Boris Lavva) has served the purpose of typesetting R documents for +% two decades, and despite its flaws I think it is still a good starting +% point (some parts have been copied here almost verbatim), partly +% thanks to its simplicity. I've also looked at \textsc{arabi} (by +% Youssef Jabri), which is compatible with \babel{}. % -% \begin{macrocode} -% Arguments are _not_ protected. -\let\bbl@calendar\@empty -\DeclareRobustCommand\localedate[1][]{\bbl@localedate{#1}} -\def\bbl@localedate#1#2#3#4{% - \begingroup - \ifx\@empty#1\@empty\else - \let\bbl@ld@calendar\@empty - \let\bbl@ld@variant\@empty - \edef\bbl@tempa{\zap@space#1 \@empty}% - \def\bbl@tempb##1=##2\@@{\@namedef{bbl@ld@##1}{##2}}% - \bbl@foreach\bbl@tempa{\bbl@tempb##1\@@}% - \edef\bbl@calendar{% - \bbl@ld@calendar - \ifx\bbl@ld@variant\@empty\else - .\bbl@ld@variant - \fi}% - \bbl@replace\bbl@calendar{gregorian}{}% - \fi - \bbl@cased - {\@nameuse{bbl@date@\languagename @\bbl@calendar}{#2}{#3}{#4}}% - \endgroup} -% eg: 1=months, 2=wide, 3=1, 4=dummy, 5=value, 6=calendar -\def\bbl@inidate#1.#2.#3.#4\relax#5#6{% TODO - ignore with 'captions' - \bbl@trim@def\bbl@tempa{#1.#2}% - \bbl@ifsamestring{\bbl@tempa}{months.wide}% to savedate - {\bbl@trim@def\bbl@tempa{#3}% - \bbl@trim\toks@{#5}% - \@temptokena\expandafter{\bbl@savedate}% - \bbl@exp{% Reverse order - in ini last wins - \def\\\bbl@savedate{% - \\\SetString\{\the\toks@}% - \the\@temptokena}}}% - {\bbl@ifsamestring{\bbl@tempa}{date.long}% defined now - {\lowercase{\def\bbl@tempb{#6}}% - \bbl@trim@def\bbl@toreplace{#5}% - \bbl@TG@@date - \bbl@ifunset{bbl@date@\languagename @}% - {\bbl@exp{% TODO. Move to a better place. - \gdef\<\languagename date>{\\\protect\<\languagename date >}% - \gdef\<\languagename date >####1####2####3{% - \\\bbl@usedategrouptrue - \{% - \\\localedate{####1}{####2}{####3}}}% - \\\bbl@add\\\bbl@savetoday{% - \\\SetString\\\today{% - \<\languagename date>% - {\\\the\year}{\\\the\month}{\\\the\day}}}}}% - {}% - \global\bbl@csarg\let{date@\languagename @}\bbl@toreplace - \ifx\bbl@tempb\@empty\else - \global\bbl@csarg\let{date@\languagename @\bbl@tempb}\bbl@toreplace - \fi}% - {}}} +% There are two ways of modifying macros to make them “bidi”, namely, +% by patching the internal low-level macros (which is what I have done +% with lists, columns, counters, tocs, much like |rlbabel| did), and +% 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{Loading basic (internal) bidi support} +\ifodd\bbl@engine +\else % TODO. Move to txtbabel + \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 + \bbl@loadfontspec % 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@loadxebidi{[rldocument]} + \or + \bbl@loadxebidi{} + \fi + \fi +\fi +% TODO? Separate: +\ifnum\bbl@bidimode=\@ne + \let\bbl@beforeforeign\leavevmode + \ifodd\bbl@engine + \newattribute\bbl@attr@dir + \directlua{ Babel.attr_dir = luatexbase.registernumber'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} % -% \textbf{Dates} will require some macros for the basic formatting. -% They may be redefined by language, so ``semi-public'' names (camel -% case) are used. Oddly enough, the CLDR places particles like “de” -% inconsistently in either in the date or in the month name. Note after -% |\bbl@replace| |\toks@| contains the resulting string, which is used -% by |\bbl@replace@finish@iii| (this implicit behavior doesn't seem a -% good idea, but it’s efficient). +% Now come the macros used to set the direction when a language is +% switched. First the (mostly) common macros. % % \begin{macrocode} -\let\bbl@calendar\@empty -\newcommand\BabelDateSpace{\nobreakspace} -\newcommand\BabelDateDot{.\@} % TODO. \let instead of repeating -\newcommand\BabelDated[1]{{\number#1}} -\newcommand\BabelDatedd[1]{{\ifnum#1<10 0\fi\number#1}} -\newcommand\BabelDateM[1]{{\number#1}} -\newcommand\BabelDateMM[1]{{\ifnum#1<10 0\fi\number#1}} -\newcommand\BabelDateMMMM[1]{{% - \csname month\romannumeral#1\bbl@calendar name\endcsname}}% -\newcommand\BabelDatey[1]{{\number#1}}% -\newcommand\BabelDateyy[1]{{% - \ifnum#1<10 0\number#1 % - \else\ifnum#1<100 \number#1 % - \else\ifnum#1<1000 \expandafter\@gobble\number#1 % - \else\ifnum#1<10000 \expandafter\@gobbletwo\number#1 % +\bbl@trace{Macros to switch the text direction} +\def\bbl@alscripts{,Arabic,Syriac,Thaana,} +\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,% + Nabataean,N'Ko,Orkhon,Palmyrene,Inscriptional Pahlavi,% + Psalter Pahlavi,Phoenician,Inscriptional Parthian,Samaritan,% + Old South Arabian,}% +\def\bbl@provide@dirs#1{% + \bbl@xin@{\csname bbl@sname@#1\endcsname}{\bbl@alscripts\bbl@rscripts}% + \ifin@ + \global\bbl@csarg\chardef{wdir@#1}\@ne + \bbl@xin@{\csname bbl@sname@#1\endcsname}{\bbl@alscripts}% + \ifin@ + \global\bbl@csarg\chardef{wdir@#1}\tw@ % useless in xetex + \fi \else - \bbl@error - {Currently two-digit years are restricted to the\\ - range 0-9999.}% - {There is little you can do. Sorry.}% - \fi\fi\fi\fi}} -\newcommand\BabelDateyyyy[1]{{\number#1}} % TODO - add leading 0 -\def\bbl@replace@finish@iii#1{% - \bbl@exp{\def\\#1####1####2####3{\the\toks@}}} -\def\bbl@TG@@date{% - \bbl@replace\bbl@toreplace{[ ]}{\BabelDateSpace{}}% - \bbl@replace\bbl@toreplace{[.]}{\BabelDateDot{}}% - \bbl@replace\bbl@toreplace{[d]}{\BabelDated{####3}}% - \bbl@replace\bbl@toreplace{[dd]}{\BabelDatedd{####3}}% - \bbl@replace\bbl@toreplace{[M]}{\BabelDateM{####2}}% - \bbl@replace\bbl@toreplace{[MM]}{\BabelDateMM{####2}}% - \bbl@replace\bbl@toreplace{[MMMM]}{\BabelDateMMMM{####2}}% - \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|}% - \bbl@replace@finish@iii\bbl@toreplace} -\def\bbl@datecntr{\expandafter\bbl@xdatecntr\expandafter} -\def\bbl@xdatecntr[#1|#2]{\localenumeral{#2}{#1}} + \global\bbl@csarg\chardef{wdir@#1}\z@ + \fi + \ifodd\bbl@engine + \bbl@csarg\ifcase{wdir@#1}% + \directlua{ Babel.locale_props[\the\localeid].textdir = 'l' }% + \or + \directlua{ Babel.locale_props[\the\localeid].textdir = 'r' }% + \or + \directlua{ Babel.locale_props[\the\localeid].textdir = 'al' }% + \fi + \fi} +\def\bbl@switchdir{% + \bbl@ifunset{bbl@lsys@\languagename}{\bbl@provide@lsys{\languagename}}{}% + \bbl@ifunset{bbl@wdir@\languagename}{\bbl@provide@dirs{\languagename}}{}% + \bbl@exp{\\\bbl@setdirs\bbl@cl{wdir}}} +\def\bbl@setdirs#1{% TODO - math + \ifcase\bbl@select@type % TODO - strictly, not the right test + \bbl@bodydir{#1}% + \bbl@pardir{#1}% + \fi + \bbl@textdir{#1}} +% TODO. Only if \bbl@bidimode > 0?: +\AddBabelHook{babel-bidi}{afterextras}{\bbl@switchdir} +\DisableBabelHook{babel-bidi} % \end{macrocode} % -% \textbf{Transforms.} +% Now the engine-dependent macros. TODO. Must be moved to the engine +% files. % -% \begin{macrocode} -\let\bbl@release@transforms\@empty -\@namedef{bbl@inikv@transforms.prehyphenation}{% - \bbl@transforms\babelprehyphenation} -\@namedef{bbl@inikv@transforms.posthyphenation}{% - \bbl@transforms\babelposthyphenation} -\def\bbl@transforms@aux#1#2#3,#4\relax{#1{#2}{#3}{#4}} -\begingroup - \catcode`\%=12 - \catcode`\&=14 - \gdef\bbl@transforms#1#2#3{&% - \ifx\bbl@KVP@transforms\@nil\else - \directlua{ - str = [==[#2]==] - str = str:gsub('%.%d+%.%d+$', '') - tex.print([[\def\string\babeltempa{]] .. str .. [[}]]) - }&% - \bbl@xin@{,\babeltempa,}{,\bbl@KVP@transforms,}&% - \ifin@ - \in@{.0$}{#2$}&% - \ifin@ - \g@addto@macro\bbl@release@transforms{&% - \relax\bbl@transforms@aux#1{\languagename}{#3}}&% +% \begin{macrocode} +\ifodd\bbl@engine % luatex=1 +\else % pdftex=0, xetex=2 + \newcount\bbl@dirlevel + \chardef\bbl@thetextdir\z@ + \chardef\bbl@thepardir\z@ + \def\bbl@textdir#1{% + \ifcase#1\relax + \chardef\bbl@thetextdir\z@ + \bbl@textdir@i\beginL\endL + \else + \chardef\bbl@thetextdir\@ne + \bbl@textdir@i\beginR\endR + \fi} + \def\bbl@textdir@i#1#2{% + \ifhmode + \ifnum\currentgrouplevel>\z@ + \ifnum\currentgrouplevel=\bbl@dirlevel + \bbl@error{Multiple bidi settings inside a group}% + {I'll insert a new group, but expect wrong results.}% + \bgroup\aftergroup#2\aftergroup\egroup \else - \g@addto@macro\bbl@release@transforms{, {#3}}&% + \ifcase\currentgrouptype\or % 0 bottom + \aftergroup#2% 1 simple {} + \or + \bgroup\aftergroup#2\aftergroup\egroup % 2 hbox + \or + \bgroup\aftergroup#2\aftergroup\egroup % 3 adj hbox + \or\or\or % vbox vtop align + \or + \bgroup\aftergroup#2\aftergroup\egroup % 7 noalign + \or\or\or\or\or\or % output math disc insert vcent mathchoice + \or + \aftergroup#2% 14 \begingroup + \else + \bgroup\aftergroup#2\aftergroup\egroup % 15 adj + \fi \fi + \bbl@dirlevel\currentgrouplevel \fi + #1% \fi} -\endgroup -% \end{macrocode} -% -% Language and Script values to be used when defining a font or -% setting the direction are set with the following macros. -% -% \begin{macrocode} -\def\bbl@provide@lsys#1{% - \bbl@ifunset{bbl@lname@#1}% - {\bbl@load@info{#1}}% - {}% - \bbl@csarg\let{lsys@#1}\@empty - \bbl@ifunset{bbl@sname@#1}{\bbl@csarg\gdef{sname@#1}{Default}}{}% - \bbl@ifunset{bbl@sotf@#1}{\bbl@csarg\gdef{sotf@#1}{DFLT}}{}% - \bbl@csarg\bbl@add@list{lsys@#1}{Script=\bbl@cs{sname@#1}}% - \bbl@ifunset{bbl@lname@#1}{}% - {\bbl@csarg\bbl@add@list{lsys@#1}{Language=\bbl@cs{lname@#1}}}% - \ifcase\bbl@engine\or\or - \bbl@ifunset{bbl@prehc@#1}{}% - {\bbl@exp{\\\bbl@ifblank{\bbl@cs{prehc@#1}}}% - {}% - {\ifx\bbl@xenohyph\@undefined - \let\bbl@xenohyph\bbl@xenohyph@d - \ifx\AtBeginDocument\@notprerr - \expandafter\@secondoftwo % to execute right now - \fi - \AtBeginDocument{% - \bbl@patchfont{\bbl@xenohyph}% - \expandafter\selectlanguage\expandafter{\languagename}}% - \fi}}% - \fi - \bbl@csarg\bbl@toglobal{lsys@#1}} -\def\bbl@xenohyph@d{% - \bbl@ifset{bbl@prehc@\languagename}% - {\ifnum\hyphenchar\font=\defaulthyphenchar - \iffontchar\font\bbl@cl{prehc}\relax - \hyphenchar\font\bbl@cl{prehc}\relax - \else\iffontchar\font"200B - \hyphenchar\font"200B - \else - \bbl@warning - {Neither 0 nor ZERO WIDTH SPACE are available\\% - in the current font, and therefore the hyphen\\% - will be printed. Try changing the fontspec's\\% - 'HyphenChar' to another value, but be aware\\% - this setting is not safe (see the manual)}% - \hyphenchar\font\defaulthyphenchar - \fi\fi - \fi}% - {\hyphenchar\font\defaulthyphenchar}} - % \fi} + \def\bbl@pardir#1{\chardef\bbl@thepardir#1\relax} + \let\bbl@bodydir\@gobble + \let\bbl@pagedir\@gobble + \def\bbl@dirparastext{\chardef\bbl@thepardir\bbl@thetextdir} % \end{macrocode} % -% The following |ini| reader ignores everything but the -% |identification| section. It is called when a font is defined (ie, -% when the language is first selected) to know which script/language -% must be enabled. This means we must make sure a few characters are -% not active. The |ini| is not read directly, but with a proxy |tex| -% file named as the language (which means any code in it must be -% skipped, too). +% The following command is executed only if there is a right-to-left +% script (once). It activates the |\everypar| hack for \xetex, to +% properly handle the par direction. Note text and par dirs are +% decoupled to some extent (although not completely). % % \begin{macrocode} -\def\bbl@load@info#1{% - \def\BabelBeforeIni##1##2{% - \begingroup - \bbl@read@ini{##1}0% - \endinput % babel- .tex may contain onlypreamble's - \endgroup}% boxed, to avoid extra spaces: - {\bbl@input@texini{#1}}} + \def\bbl@xebidipar{% + \let\bbl@xebidipar\relax + \TeXXeTstate\@ne + \def\bbl@xeeverypar{% + \ifcase\bbl@thepardir + \ifcase\bbl@thetextdir\else\beginR\fi + \else + {\setbox\z@\lastbox\beginR\box\z@}% + \fi}% + \let\bbl@severypar\everypar + \newtoks\everypar + \everypar=\bbl@severypar + \bbl@severypar{\bbl@xeeverypar\the\everypar}} + \ifnum\bbl@bidimode>200 + \let\bbl@textdir@i\@gobbletwo + \let\bbl@xebidipar\@empty + \AddBabelHook{bidi}{foreign}{% + \def\bbl@tempa{\def\BabelText####1}% + \ifcase\bbl@thetextdir + \expandafter\bbl@tempa\expandafter{\BabelText{\LR{##1}}}% + \else + \expandafter\bbl@tempa\expandafter{\BabelText{\RL{##1}}}% + \fi} + \def\bbl@pardir#1{\ifcase#1\relax\setLR\else\setRL\fi} + \fi +\fi % \end{macrocode} % -% 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. Non-digits characters are kept. The -% first macro is the generic “localized” command. +% A tool for weak L (mainly digits). We also disable warnings with +% \textsf{hyperref}. % % \begin{macrocode} -\def\bbl@setdigits#1#2#3#4#5{% - \bbl@exp{% - \def\<\languagename digits>####1{% ie, \langdigits - \####1\\\@nil}% - \let\\<\languagename digits>% - \def\<\languagename counter>####1{% ie, \langcounter - \\\expandafter\% - \\\csname c@####1\endcsname}% - \def\####1{% ie, \bbl@counter@lang - \\\expandafter\% - \\\number####1\\\@nil}}% - \def\bbl@tempa##1##2##3##4##5{% - \bbl@exp{% Wow, quite a lot of hashes! :-( - \def\########1{% - \\\ifx########1\\\@nil % ie, \bbl@digits@lang - \\\else - \\\ifx0########1#1% - \\\else\\\ifx1########1#2% - \\\else\\\ifx2########1#3% - \\\else\\\ifx3########1#4% - \\\else\\\ifx4########1#5% - \\\else\\\ifx5########1##1% - \\\else\\\ifx6########1##2% - \\\else\\\ifx7########1##3% - \\\else\\\ifx8########1##4% - \\\else\\\ifx9########1##5% - \\\else########1% - \\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi\\\fi - \\\expandafter\% - \\\fi}}}% - \bbl@tempa} +\DeclareRobustCommand\babelsublr[1]{\leavevmode{\bbl@textdir\z@#1}} +\AtBeginDocument{% + \ifx\pdfstringdefDisableCommands\@undefined\else + \ifx\pdfstringdefDisableCommands\relax\else + \pdfstringdefDisableCommands{\let\babelsublr\@firstofone}% + \fi + \fi} % \end{macrocode} % -% Alphabetic counters must be converted from a space separated list to -% an |\ifcase| structure. +% \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. +% +% For plain-based formats we don't want to override the definition +% of |\loadlocalcfg| from \file{plain.def}. % % \begin{macrocode} -\def\bbl@buildifcase#1 {% Returns \bbl@tempa, requires \toks@={} - \ifx\\#1% % \\ before, in case #1 is multiletter - \bbl@exp{% - \def\\\bbl@tempa####1{% - \####1\space\the\toks@\\\\@ctrerr\}}% - \else - \toks@\expandafter{\the\toks@\or #1}% - \expandafter\bbl@buildifcase - \fi} -% \end{macrocode} +\bbl@trace{Local Language Configuration} +\ifx\loadlocalcfg\@undefined + \@ifpackagewith{babel}{noconfigs}% + {\let\loadlocalcfg\@gobble}% + {\def\loadlocalcfg#1{% + \InputIfFileExists{#1.cfg}% + {\typeout{*************************************^^J% + * Local config file #1.cfg used^^J% + *}}% + \@empty}} +\fi +% \end{macrocode}% +% \end{macro} % -% The code for additive counters is somewhat tricky and it's based on -% the fact the arguments just before |\@@| collects digits which have -% been left ‘unused’ in previous arguments, the first of them being the -% 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). +% \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). % % \begin{macrocode} -\newcommand\localenumeral[2]{\bbl@cs{cntr@#1@\languagename}{#2}} -\def\bbl@localecntr#1#2{\localenumeral{#2}{#1}} -\newcommand\localecounter[2]{% - \expandafter\bbl@localecntr - \expandafter{\number\csname c@#2\endcsname}{#1}} -\def\bbl@alphnumeral#1#2{% - \expandafter\bbl@alphnumeral@i\number#2 76543210\@@{#1}} -\def\bbl@alphnumeral@i#1#2#3#4#5#6#7#8\@@#9{% - \ifcase\@car#8\@nil\or % Currenty <10000, but prepared for bigger - \bbl@alphnumeral@ii{#9}000000#1\or - \bbl@alphnumeral@ii{#9}00000#1#2\or - \bbl@alphnumeral@ii{#9}0000#1#2#3\or - \bbl@alphnumeral@ii{#9}000#1#2#3#4\else - \bbl@alphnum@invalid{>9999}% - \fi} -\def\bbl@alphnumeral@ii#1#2#3#4#5#6#7#8{% - \bbl@ifunset{bbl@cntr@#1.F.\number#5#6#7#8@\languagename}% - {\bbl@cs{cntr@#1.4@\languagename}#5% - \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@ % TODO. An ad hoc rule for Greek. Ugly. - \bbl@ifunset{bbl@cntr@#1.S.321@\languagename}{}% - {\bbl@cs{cntr@#1.S.321@\languagename}}% - \fi}% - {\bbl@cs{cntr@#1.F.\number#5#6#7#8@\languagename}}} -\def\bbl@alphnum@invalid#1{% - \bbl@error{Alphabetic numeral too large (#1)}% - {Currently this is the limit.}} +\bbl@trace{Language options} +\let\bbl@afterlang\relax +\let\BabelModifiers\relax +\let\bbl@loaded\@empty +\def\bbl@load@language#1{% + \InputIfFileExists{#1.ldf}% + {\edef\bbl@loaded{\CurrentOption + \ifx\bbl@loaded\@empty\else,\bbl@loaded\fi}% + \expandafter\let\expandafter\bbl@afterlang + \csname\CurrentOption.ldf-h@@k\endcsname + \expandafter\let\expandafter\BabelModifiers + \csname bbl@mod@\CurrentOption\endcsname}% + {\bbl@error{% + Unknown option '\CurrentOption'. Either you misspelled it\\% + or the language definition file \CurrentOption.ldf was not found}{% + Valid options are, among others: shorthands=, KeepShorthandsActive,\\% + activeacute, activegrave, noconfigs, safe=, main=, math=\\% + headfoot=, strings=, config=, hyphenmap=, or a language name.}}} % \end{macrocode} % -% The information in the identification section can be useful, so the -% following macro just exposes it with a user command. +% 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} -\newcommand\localeinfo[1]{% - \bbl@ifunset{bbl@\csname bbl@info@#1\endcsname @\languagename}% - {\bbl@error{I've found no info for the current locale.\\% - The corresponding ini file has not been loaded\\% - Perhaps it doesn't exist}% - {See the manual for details.}}% - {\bbl@cs{\csname bbl@info@#1\endcsname @\languagename}}} -% \@namedef{bbl@info@name.locale}{lcname} -\@namedef{bbl@info@tag.ini}{lini} -\@namedef{bbl@info@name.english}{elname} -\@namedef{bbl@info@name.opentype}{lname} -\@namedef{bbl@info@tag.bcp47}{tbcp} -\@namedef{bbl@info@language.tag.bcp47}{lbcp} -\@namedef{bbl@info@tag.opentype}{lotf} -\@namedef{bbl@info@script.name}{esname} -\@namedef{bbl@info@script.name.opentype}{sname} -\@namedef{bbl@info@script.tag.bcp47}{sbcp} -\@namedef{bbl@info@script.tag.opentype}{sotf} -\let\bbl@ensureinfo\@gobble -\newcommand\BabelEnsureInfo{% - \ifx\InputIfFileExists\@undefined\else - \def\bbl@ensureinfo##1{% - \bbl@ifunset{bbl@lname@##1}{\bbl@load@info{##1}}{}}% - \fi - \bbl@foreach\bbl@loaded{{% - \def\languagename{##1}% - \bbl@ensureinfo{##1}}}} -% \end{macrocode} +\def\bbl@try@load@lang#1#2#3{% + \IfFileExists{\CurrentOption.ldf}% + {\bbl@load@language{\CurrentOption}}% + {#1\bbl@load@language{#2}#3}} % -% More general, but non-expandable, is |\getlocaleproperty|. To inspect -% every possible loaded |ini|, we define |\LocaleForEach|, where -% |\bbl@ini@loaded| is a comma-separated list of locales, built by -% |\bbl@read@ini|. +\DeclareOption{hebrew}{% + \input{rlbabel.def}% + \bbl@load@language{hebrew}} +\DeclareOption{hungarian}{\bbl@try@load@lang{}{magyar}{}} +\DeclareOption{lowersorbian}{\bbl@try@load@lang{}{lsorbian}{}} +\DeclareOption{nynorsk}{\bbl@try@load@lang{}{norsk}{}} +\DeclareOption{polutonikogreek}{% + \bbl@try@load@lang{}{greek}{\languageattribute{greek}{polutoniko}}} +\DeclareOption{russian}{\bbl@try@load@lang{}{russianb}{}} +\DeclareOption{ukrainian}{\bbl@try@load@lang{}{ukraineb}{}} +\DeclareOption{uppersorbian}{\bbl@try@load@lang{}{usorbian}{}} +% \end{macrocode} % -% \begin{macrocode} -\newcommand\getlocaleproperty{% - \@ifstar\bbl@getproperty@s\bbl@getproperty@x} -\def\bbl@getproperty@s#1#2#3{% - \let#1\relax - \def\bbl@elt##1##2##3{% - \bbl@ifsamestring{##1/##2}{#3}% - {\providecommand#1{##3}% - \def\bbl@elt####1####2####3{}}% +% 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=|, which will +% load |.cfg| instead. +% +% \begin{macrocode} +\ifx\bbl@opt@config\@nnil + \@ifpackagewith{babel}{noconfigs}{}% + {\InputIfFileExists{bblopts.cfg}% + {\typeout{*************************************^^J% + * Local config file bblopts.cfg used^^J% + *}}% {}}% - \bbl@cs{inidata@#2}}% -\def\bbl@getproperty@x#1#2#3{% - \bbl@getproperty@s{#1}{#2}{#3}% - \ifx#1\relax - \bbl@error - {Unknown key for locale '#2':\\% - #3\\% - \string#1 will be set to \relax}% - {Perhaps you misspelled it.}% - \fi} -\let\bbl@ini@loaded\@empty -\newcommand\LocaleForEach{\bbl@foreach\bbl@ini@loaded} +\else + \InputIfFileExists{\bbl@opt@config.cfg}% + {\typeout{*************************************^^J% + * Local config file \bbl@opt@config.cfg used^^J% + *}}% + {\bbl@error{% + Local config file '\bbl@opt@config.cfg' not found}{% + Perhaps you misspelled it.}}% +\fi % \end{macrocode} % -% \section{Adjusting the Babel bahavior} +% 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 existing languages (note +% this list also contains the language given with |main| as the last +% element). If not declared above, the names of the option and the file +% are the same. There are two steps -- first process option names and +% collect the result, which then do the actual declarations. % -% A generic high level inteface is provided to adjust some global -% and general settings. +% To allow multiple overlapping replacements, commas in +% |\bbl@language@opts| are doubled. % % \begin{macrocode} -\newcommand\babeladjust[1]{% TODO. Error handling. - \bbl@forkv{#1}{% - \bbl@ifunset{bbl@ADJ@##1@##2}% - {\bbl@cs{ADJ@##1}{##2}}% - {\bbl@cs{ADJ@##1@##2}}}} +\let\bbl@elt\relax +\let\bbl@tempe\@empty +\bbl@foreach\@classoptionslist{% + \bbl@xin@{,#1,$}{\bbl@language@opts$}% Match last + \ifin@\else + \bbl@xin@{,#1,}{\bbl@language@opts}% Match non-last + \ifin@ + \bbl@replace\bbl@language@opts{,#1,}{,,}% + \edef\bbl@tempe{\bbl@tempe\bbl@elt{3}{#1}}% + \else + \babel@savecnt\z@ % Use as temp + \ifnum\bbl@iniflag<\thr@@ % Optimization: 3 = always ini + \IfFileExists{#1.ldf}{\advance\babel@savecnt\@ne}{}% + \fi + \ifnum\bbl@iniflag>\z@ % Optimization: 0 = always ldf + \IfFileExists{babel-#1.tex}{\advance\babel@savecnt\tw@}{}% + \fi + \ifnum\babel@savecnt>\z@ + \edef\bbl@tempe{\bbl@tempe\bbl@elt{\the\babel@savecnt}{#1}}% + \fi + \fi + \fi} % -\def\bbl@adjust@lua#1#2{% - \ifvmode - \ifnum\currentgrouplevel=\z@ - \directlua{ Babel.#2 }% - \expandafter\expandafter\expandafter\@gobble +\let\bbl@savemain\@empty +\bbl@foreach\bbl@language@opts{% + \edef\bbl@tempe{\bbl@tempe\bbl@elt{3}{#1}}} +\def\bbl@elt#1#2#3{% + \ifx#3\relax % if last + \bbl@ifunset{ds@#2}{}% + {\bbl@exp{\def\\\bbl@savemain{\\\DeclareOption{#2}{\[ds@#2]}}}}% + \bbl@add\bbl@savemain{\bbl@elt{#1}{#2}}% Save main + \DeclareOption{#2}{}% + \else + \ifnum\bbl@iniflag<\tw@ % other as ldf + \ifodd#1\relax % Class: if ldf exists 1,3. Package: always 3 + \bbl@ifunset{ds@#2}% + {\DeclareOption{#2}{\bbl@load@language{#2}}}% + {}% + \fi + \else % other as ini + \ifnum#1>\@ne % % Class: if ini exists 2,3. Package: always 3 + \DeclareOption{#2}{% + \bbl@ldfinit + \babelprovide[import]{#2}% + \bbl@afterldf{}}% + \fi \fi - \fi - {\bbl@error % The error is gobbled if everything went ok. - {Currently, #1 related features can be adjusted only\\% - in the main vertical list.}% - {Maybe things change in the future, but this is what it is.}}} -\@namedef{bbl@ADJ@bidi.mirroring@on}{% - \bbl@adjust@lua{bidi}{mirroring_enabled=true}} -\@namedef{bbl@ADJ@bidi.mirroring@off}{% - \bbl@adjust@lua{bidi}{mirroring_enabled=false}} -\@namedef{bbl@ADJ@bidi.text@on}{% - \bbl@adjust@lua{bidi}{bidi_enabled=true}} -\@namedef{bbl@ADJ@bidi.text@off}{% - \bbl@adjust@lua{bidi}{bidi_enabled=false}} -\@namedef{bbl@ADJ@bidi.mapdigits@on}{% - \bbl@adjust@lua{bidi}{digits_mapped=true}} -\@namedef{bbl@ADJ@bidi.mapdigits@off}{% - \bbl@adjust@lua{bidi}{digits_mapped=false}} + \fi + #3} +\bbl@tempe\relax % \relax catches last +% \end{macrocode} % -\@namedef{bbl@ADJ@linebreak.sea@on}{% - \bbl@adjust@lua{linebreak}{sea_enabled=true}} -\@namedef{bbl@ADJ@linebreak.sea@off}{% - \bbl@adjust@lua{linebreak}{sea_enabled=false}} -\@namedef{bbl@ADJ@linebreak.cjk@on}{% - \bbl@adjust@lua{linebreak}{cjk_enabled=true}} -\@namedef{bbl@ADJ@linebreak.cjk@off}{% - \bbl@adjust@lua{linebreak}{cjk_enabled=false}} -\@namedef{bbl@ADJ@justify.arabic@on}{% - \bbl@adjust@lua{linebreak}{arabic.justify_enabled=true}} -\@namedef{bbl@ADJ@justify.arabic@off}{% - \bbl@adjust@lua{linebreak}{arabic.justify_enabled=false}} +% 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 +% accessing the file system just to see if the option could be a +% language. % -\def\bbl@adjust@layout#1{% - \ifvmode - #1% - \expandafter\@gobble - \fi - {\bbl@error % The error is gobbled if everything went ok. - {Currently, layout related features can be adjusted only\\% - in vertical mode.}% - {Maybe things change in the future, but this is what it is.}}} -\@namedef{bbl@ADJ@layout.tabular@on}{% - \bbl@adjust@layout{\let\@tabular\bbl@NL@@tabular}} -\@namedef{bbl@ADJ@layout.tabular@off}{% - \bbl@adjust@layout{\let\@tabular\bbl@OL@@tabular}} -\@namedef{bbl@ADJ@layout.lists@on}{% - \bbl@adjust@layout{\let\list\bbl@NL@list}} -\@namedef{bbl@ADJ@layout.lists@off}{% - \bbl@adjust@layout{\let\list\bbl@OL@list}} -\@namedef{bbl@ADJ@hyphenation.extra@on}{% - \bbl@activateposthyphen} +% If a main language has been set, store it for the third pass. +% And we are done, because all options for this pass has been +% declared. Those already processed in the first pass are just +% ignored. % -\@namedef{bbl@ADJ@autoload.bcp47@on}{% - \bbl@bcpallowedtrue} -\@namedef{bbl@ADJ@autoload.bcp47@off}{% - \bbl@bcpallowedfalse} -\@namedef{bbl@ADJ@autoload.bcp47.prefix}#1{% - \def\bbl@bcp@prefix{#1}} -\def\bbl@bcp@prefix{bcp47-} -\@namedef{bbl@ADJ@autoload.options}#1{% - \def\bbl@autoload@options{#1}} -\let\bbl@autoload@bcpoptions\@empty -\@namedef{bbl@ADJ@autoload.bcp47.options}#1{% - \def\bbl@autoload@bcpoptions{#1}} -\newif\ifbbl@bcptoname -\@namedef{bbl@ADJ@bcp47.toname@on}{% - \bbl@bcptonametrue - \BabelEnsureInfo} -\@namedef{bbl@ADJ@bcp47.toname@off}{% - \bbl@bcptonamefalse} -\@namedef{bbl@ADJ@prehyphenation.disable@nohyphenation}{% - \directlua{ Babel.ignore_pre_char = function(node) - return (node.lang == \the\csname l@nohyphenation\endcsname) - end }} -\@namedef{bbl@ADJ@prehyphenation.disable@off}{% - \directlua{ Babel.ignore_pre_char = function(node) - return false - end }} +% 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{% + \bbl@ifsamestring\CurrentOption{#1}{\global\bbl@add\bbl@afterlang}{}} +\DeclareOption*{} +\ProcessOptions* % \end{macrocode} % -% As the final task, load the code for lua. TODO: use babel name, override +% 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} -\ifx\directlua\@undefined\else - \ifx\bbl@luapatterns\@undefined - \input luababel.def +\bbl@trace{Option 'main'} +\ifx\bbl@opt@main\@nnil + \edef\bbl@tempa{\@classoptionslist,\bbl@language@opts} + \let\bbl@tempc\@empty + \bbl@for\bbl@tempb\bbl@tempa{% + \bbl@xin@{,\bbl@tempb,}{,\bbl@loaded,}% + \ifin@\edef\bbl@tempc{\bbl@tempb}\fi} + \def\bbl@tempa#1,#2\@nnil{\def\bbl@tempb{#1}} + \expandafter\bbl@tempa\bbl@loaded,\@nnil + \ifx\bbl@tempb\bbl@tempc\else + \bbl@warning{% + Last declared language option is '\bbl@tempc',\\% + but the last processed one was '\bbl@tempb'.\\% + The main language can't be set as both a global\\% + and a package option. Use 'main=\bbl@tempc' as\\% + option. Reported}% \fi \fi -% +\def\bbl@elt#1#2{% main + \ifodd\bbl@iniflag % as ini = 1(=), 3(*=) + \ifnum#1>\@ne % % Class: if ini exists 2,3. Package: always 3 + \def\CurrentOption{#2}% Directly, because luatexbase + \bbl@ldfinit + \babelprovide[\bbl@opt@provide,main,import]{#2}% + \bbl@afterldf{}% + \DeclareOption{#2}{}% + \fi + \else % as ldf = 0(no), 2(+=) + \ifodd#1\relax % Class: if ldf exists 1,3. Package: always 3 + \bbl@ifunset{ds@#2}% + {\DeclareOption{#2}{\bbl@load@language{#2}}}% + {}% + \ExecuteOptions{#2}% + \fi + \fi} +\bbl@savemain +\DeclareOption*{}% +\ProcessOptions* +\def\AfterBabelLanguage{% + \bbl@error + {Too late for \string\AfterBabelLanguage}% + {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. +% +% \begin{macrocode} +\ifx\bbl@main@language\@undefined + \bbl@info{% + You haven't specified a language. I'll use 'nil'\\% + as the main language. Reported} + \bbl@load@language{nil} +\fi +% % \end{macrocode} % +% \section{The kernel of Babel (\texttt{babel.def}, common)} +% +% The kernel of the \babel\ system is currently stored in +% \file{babel.def}. The file \file{babel.def} contains most of the +% code. The file \file{hyphen.cfg} is a file that can be loaded into +% the format, which is necessary when you want to be able to switch +% hyphenation patterns. +% +% Because plain \TeX\ users might want to use some of the features of +% the \babel{} system too, care has to be taken that plain \TeX\ can +% process the files. For this reason the current format will have to +% be checked in a number of places. Some of the code below is common +% to plain \TeX\ and \LaTeX, some of it is for the \LaTeX\ case only. +% +% Plain formats based on etex (etex, xetex, luatex) don't load +% |hyphen.cfg| but |etex.src|, which follows a different naming +% convention, so we need to define the babel names. It presumes +% |language.def| exists and it is the same file used when formats were +% created. +% % A proxy file for switch.def % % \begin{macrocode} @@ -12891,7 +12779,7 @@ help from Bernd Raichle, for which I am grateful. \{fontspec-opentype}{Language/\bbl@cl{lname}}% {\\\newfontlanguage{\bbl@cl{lname}}{\bbl@cl{lotf}}}% \\\renewfontfamily\\#4% - [\bbl@cs{lsys@\languagename},#2]}{#3}% ie \bbl@exp{..}{#3} + [\bbl@cl{lsys},#2]}{#3}% ie \bbl@exp{..}{#3} \begingroup #4% \xdef#1{\f@family}% eg, \bbl@rmdflt@lang{FreeSerif(0)} @@ -14635,6 +14523,7 @@ end {\ifx\tikz@atbegin@node\@undefined\else \ifx\AddToHook\@undefined\else % TODO. Still tentative. \AddToHook{env/pgfpicture/begin}{\bbl@pictsetdir\@ne}% + % \AddToHook{env/tikzpicture/begin}{\bbl@pictsetdir\z@}% \bbl@add\pgfinterruptpicture{\bbl@pictresetdir}% \fi \let\bbl@OL@pgfpicture\pgfpicture @@ -22462,12 +22351,17 @@ Babel.cjk_breaks = { % % \subsection{Emulating some \LaTeX{} features} % -% The following code duplicates or emulates parts of \LaTeXe\ that -% are needed for \babel. +% The file |babel.def| expects some definitions made in the \LaTeXe{} +% style file. So, in Plain{} we must provide at least +% some predefined values as well some tools to set them (even if not +% all options are available). There are no package options, and +% therefore and alternative mechanism is provided. For the moment, +% only |\babeloptionstrings| and |\babeloptionmath| are provided, +% which can be defined before loading \babel. |\BabelModifiers| can be +% set too (but not sure it works). % % \begin{macrocode} %<<*Emulate LaTeX>> - % == Code for plain == \def\@empty{} \def\loadlocalcfg#1{% \openin0#1.cfg @@ -22525,6 +22419,25 @@ Babel.cjk_breaks = { \ifx#2\@empty\else\expandafter\zap@space\fi #2} \let\bbl@trace\@gobble +\def\bbl@error#1#2{% + \begingroup + \newlinechar=`\^^J + \def\\{^^J(babel) }% + \errhelp{#2}\errmessage{\\#1}% + \endgroup} +\def\bbl@warning#1{% + \begingroup + \newlinechar=`\^^J + \def\\{^^J(babel) }% + \message{\\#1}% + \endgroup} +\let\bbl@infowarn\bbl@warning +\def\bbl@info#1{% + \begingroup + \newlinechar=`\^^J + \def\\{^^J}% + \wlog{#1}% + \endgroup} % \end{macrocode} % % \LaTeXe\ has the command |\@onlypreamble| which adds commands to @@ -22879,7 +22792,7 @@ Babel.cjk_breaks = { \def\cf@encoding{OT1} % \end{macrocode} % -% Currently we only use the \LaTeXe\ method for accents for those +% Currently we only use the \LaTeXe\ method for accents for those % that are known to be made active in \emph{some} language % definition file. % @@ -22903,20 +22816,47 @@ Babel.cjk_breaks = { \DeclareTextSymbol{\ss}{OT1}{25} % \end{macrocode} % -% For a couple of languages we need the \LaTeX-control sequence -% |\scriptsize| to be available. Because plain \TeX\ doesn't have -% such a sofisticated font mechanism as \LaTeX\ has, we just |\let| -% it to |\sevenrm|. +% For a couple of languages we need the \LaTeX-control sequence +% |\scriptsize| to be available. Because plain \TeX\ doesn't have such +% a sofisticated font mechanism as \LaTeX\ has, we just |\let| it to +% |\sevenrm|. % % \begin{macrocode} \ifx\scriptsize\@undefined \let\scriptsize\sevenrm \fi - % End of code for plain +% \end{macrocode} +% +% And a few more “dummy” definitions. +% +% \begin{macrocode} +\def\languagename{english}% +\let\bbl@opt@shorthands\@nnil +\def\bbl@ifshorthand#1#2#3{#2}% +\let\bbl@language@opts\@empty +\ifx\babeloptionstrings\@undefined + \let\bbl@opt@strings\@nnil +\else + \let\bbl@opt@strings\babeloptionstrings +\fi +\def\BabelStringsDefault{generic} +\def\bbl@tempa{normal} +\ifx\babeloptionmath\bbl@tempa + \def\bbl@mathnormal{\noexpand\textormath} +\fi +\def\AfterBabelLanguage#1#2{} +\ifx\BabelModifiers\@undefined\let\BabelModifiers\relax\fi +\let\bbl@afterlang\relax +\def\bbl@opt@safe{BR} +\ifx\@uclclist\@undefined\let\@uclclist\@empty\fi +\ifx\bbl@trace\@undefined\def\bbl@trace#1{}\fi +\expandafter\newif\csname ifbbl@single\endcsname +\chardef\bbl@bidimode\z@ %<> % \end{macrocode} % % A proxy file: +% % \begin{macrocode} %<*plain> \input babel.def -- cgit v1.2.3