% \iffalse meta-comment % % Copyright 2010, 2011 by Manuel Pégourié-Gonnard % % This work is under the CC0 license. % % This work consists of the main source file luatexbase-compat.dtx % and the derived files % luatexbase-compat.pdf luatexbase-compat.sty % test-compat-plain.tex test-compat-latex.tex % % Unpacking: % tex luatexbase-compat.dtx % Documentation: % pdflatex luatexbase-compat.dtx % %<*ignore> \begingroup \def\x{LaTeX2e}% \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble See the aforementioned source file(s) for copyright and licensing information. \endpreamble \generate{% \usedir{tex/luatex/luatexbase}% \file{luatexbase-compat.sty}{\from{luatexbase-compat.dtx}{texpackage}}% } \generate{% \usedir{doc/luatex/luatexbase}% \file{test-compat-plain.tex}{\from{luatexbase-compat.dtx}{testplain}}% \file{test-compat-latex.tex}{\from{luatexbase-compat.dtx}{testlatex}}% } \obeyspaces \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* files into a directory searched by TeX:} \Msg{*} \Msg{* luatexbase-compat.sty} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile % %<*ignore> \fi % %<*driver> \NeedsTeXFormat{LaTeX2e} \documentclass{ltxdoc} \input lltxb-dtxstyle.tex \EnableCrossrefs \CodelineIndex \begin{document} \DocInput{luatexbase-compat.dtx}% \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \pkdate{luatexbase-compat}{2011/05/24 v0.4} % % \maketitle % % \begin{abstract} % The \luatex manual is very clear: everything may change. This package % provides tools to help package writers deal with the changes. It helps % supporting \luatex versions down to 0.25.4, and is tested with % \luatex 0.40.6 (\texlive 2009), \luatex 0.60.2 (\texlive 2010) and current % beta versions. % % The supported formats are Plain and \latex adapted for \luatex as provided % by \texlive and MiK\tex (see \file{lualatex-doc.pdf} section~4 for details % about these formats). % \end{abstract} % % \tableofcontents % % \section{Documentation} % % Three problems are currently addressed by this package: changes in the % syntax of |\directlua|, version information, and variable policies for % primitives activation and naming (in \luatex itself as well as in the % formats provided by distributions). % % \medskip % % Older versions of \luatex used to support multiple Lua states. A number was % mandatory with |\directlua| in order to specify the Lua state to be used. % Later, support for multiple Lua states was removed and the old syntax % resulted in a warning. Now (\luatex 0.50), |\directlua| again accepts a % number after |\directlua|, but with a different meaning (see the \luatex % manual for details). % % This package provides a macro |\luatexbase@directlua| that expands to % |\directlua0| on \luatex 0.35 and lower (where the number is mandatory), and % to |\directlua| otherwise. It is a macro in both cases so that it always % expands in exactly two steps. % % \medskip % % Current versions of \luatex make the version available directly from Lua as % |tex.luatexversion| and |tex.luatexrevision|. However, older versions (such % as 0.25.4) didn't, which makes it particularly uneasy to test the version % from within Lua. The present package makes this information available as % |luatexbase.luatexversion| and |luatexbase.luatexrevision|. % % \medskip % % Starting with \luatex 0.39.0, the only primitives available in Ini\tex mode % are the basic primitives from \tex{}82 and |\directlua|. All other % primitives are hidden by default and have to be activated using a Lua % function. In \texlive 2009 (\luatex 0.40.6), the following arrangement has % been made in order to try preserving usability while avoiding name clashes % in the \latex world: in \latex-based formats, all pdf\tex primitives are % enabled with their normal name, but the primitives specific to \luatex are % enabled with the |luatex| prefix.\footnote{The prefix is dropped for % primitives whose name already starts with \texttt{luatex}.} In Plain based % formats however, all the primitives are enabled with their natural name, but % are also provided with the same name as in \latex-based formats in order to % help writing generic packages. % % So, starting with \texlive 2009, the situation is clear: the prefixed % version of the \luatex primitives is always available. But in earlier % versions (\texlive 2008, \luatex 0.25.4) those primitives were available % only with their natural names. The primitives provided by \etex and pdf\tex % on the other hand, are always available. % % \begin{quote} % \cs{luatexbase@ensure@primitive}\marg{name} % \end{quote} % The tool provided to deal with that is \cs{luatexbase@ensure@primitive}, % whose argument is a \luatex primitive name (without a leading backslash nor % any |luatex| prefix, eg just |{latelua}|). It makes sure that the primitive % gets available as \cs{luatex\meta{name}}. % % \textbf{Warning.} In particular circumstances, this macro may fail silently % for primitives whose natural name starts with |luatex|, hence such % primitives shouldn't be used as arguments. This is actually not a problem, % since the only three such primitives are |\luatexversion|, |\luatexrevision| % and |\luatexdatestamp|. The first two are already activated by \pk{ifluatex} % which is loaded by this package, so you don't need to activated them % yourself. The third should never be used in production according to the % \luatex manual. % % \textit{Remark.} If you only aim at compatibility down to \texlive 2009 % (\luatex 0.40.6), then you can simply use the primitives with their prefixed % name (except for |\directlua| which never needs a prefix). If you want extra % security and/or compatibility down to \texlive 2008 (\luatex 0.25.4) then % you should use \cs{luatebase@ensure@primitive} for each primitive you intend % to use (except |\directlua| again). % % This package doesn't try to activate every primitive, since it would require % an extensive list of primitives for each version of \luatex, so it seems % simpler to leave that burden on package writers. % % \section{Implementation} % % \begin{macrocode} %<*texpackage> % \end{macrocode} % % \subsection{Preliminaries} % % Catcode defenses and reload protection. % % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% = and space \catcode123 1 % { \catcode125 2 % } \catcode 35 6 % # \toks0\expandafter{\expandafter\endlinechar\the\endlinechar}% \edef\x{\endlinechar13}% \def\y#1 #2 {% \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}% \edef\x{\x \catcode#1 #2}}% \y 13 5 % carriage return \y 61 12 % = \y 32 10 % space \y 123 1 % { \y 125 2 % } \y 35 6 % # \y 64 11 % @ (letter) \y 10 12 % new line ^^J \y 39 12 % ' \y 40 12 % ( \y 41 12 % ) \y 42 12 % * \y 44 12 % , \y 45 12 % - \y 46 12 % . \y 47 12 % / \y 58 12 % : \y 60 12 % < \y 91 12 % [ \y 93 12 % ] \y 94 7 % ^ \y 96 12 % ` \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}% \edef\y#1{\noexpand\expandafter\endgroup% \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax% \noexpand\else \noexpand\expandafter\noexpand\endinput% \noexpand\fi}% \expandafter\y\csname luatexbase@compat@sty@endinput\endcsname% % \end{macrocode} % % Package declaration. % % \begin{macrocode} \begingroup \expandafter\ifx\csname ProvidesPackage\endcsname\relax \def\x#1[#2]{\immediate\write16{Package: #1 #2}} \else \let\x\ProvidesPackage \fi \expandafter\endgroup \x{luatexbase-compat}[2011/05/24 v0.4 Compatibility tools for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. % % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname RequirePackage\endcsname\relax \input ifluatex.sty \else \RequirePackage{ifluatex} \fi \ifluatex\else \begingroup \expandafter\ifx\csname PackageError\endcsname\relax \def\x#1#2#3{\begingroup \newlinechar10 \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else \let\x\PackageError \fi \expandafter\endgroup \x{luatexbase-compat}{LuaTeX is required for this package. Aborting.}{% This package can only be used with the LuaTeX engine^^J% (command `lualatex' or `luatex').^^J% Package loading has been stopped to prevent additional errors.} \expandafter\luatexbase@compat@sty@endinput% \fi % \end{macrocode} % % \subsection{\cs{directlua} abstraction} % % Define |\luatexbase@directlua| to be either |\directlua0| or % |\directlua|, depending on the version of \luatex. % % \begin{macrocode} \begingroup \expandafter\ifx\csname newcommand\endcsname\relax \toks0{\long\def\luatexbase@directlua}% \else \toks0{\newcommand\luatexbase@directlua}% \fi \ifnum\luatexversion<36 \toks0\expandafter{\the\toks0{\directlua0}}% \else \toks0\expandafter{\the\toks0{\directlua}}% \fi \expandafter\endgroup \the\toks0 % \end{macrocode} % % \subsection{Version information} % % Make |\luatexversion| and |\luatexrevision| available from Lua. % % \begin{macrocode} \luatexbase@directlua{% luatexbase = luatexbase or {} luatexbase.luatexversion = \number\luatexversion\space luatexbase.luatexrevision = \number\luatexrevision\space} % \end{macrocode} % % \subsection{Primitives} % % Try reasonably hard to activate a primitive. First, check if it is % already activated an do nothing in this case. % % \begin{macrocode} \begingroup \expandafter\ifx\csname newcommand\endcsname\relax \toks0{\def\luatexbase@ensure@primitive#1} \else \toks0{\newcommand*\luatexbase@ensure@primitive[1]} \fi \toks2{}\def\x#1{\toks2\expandafter{\the\toks2 #1}} \x{% \ifcsname luatex#1\endcsname \else} \ifnum\luatexversion<37\relax % \end{macrocode} % % |tex.enableprimitives()| not available. If the unprefixed primitive is % undefined, issue an error. % % \begin{macrocode} \x{% \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname #1\endcsname\relax} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname PackageError\endcsname\relax \x{% \errmessage{% Package luatexbase-compat error: failed to enable `#1'.}} \else \x{% \PackageError{luatexbase-compat}{% Package luatexbase-compat error: failed to enable `#1'.}{}} \fi \x{% \else} % \end{macrocode} % % Use the unprefixed primitive to define the prefixed version. % % \begin{macrocode} \x{% \expandafter\let\csname luatex#1\expandafter\endcsname \csname#1\endcsname \fi} \else % \end{macrocode} % % |tex.enableprimitives()| available, use it. % % \begin{macrocode} \x{% \luatexbase@directlua{tex.enableprimitives('luatex', {'#1'})}} \fi \x{% \fi} \toks0\expandafter{\the\toks0\expandafter{\the\toks2}} \expandafter\endgroup \the\toks0 % \end{macrocode} % % That's all folks! % % \begin{macrocode} \luatexbase@compat@sty@endinput% % % \end{macrocode} % % \section{Test files} % % Test fils for Plain and LaTeX % % \begin{macrocode} %\input luatexbase-compat.sty %\RequirePackage{luatexbase-compat} %<*testplain,testlatex> \catcode64 11 \luatexbase@directlua{local answer = 42} \luatexbase@ensure@primitive{primitive} \luatexprimitive\relax \luatexbase@directlua{assert(type(luatexbase.luatexversion) == 'number')} \luatexbase@directlua{assert(type(luatexbase.luatexrevision) == 'number')} % %\bye %\stop % \end{macrocode} % % % \Finale \endinput