summaryrefslogtreecommitdiff
path: root/luatexbase-compat.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'luatexbase-compat.dtx')
-rw-r--r--luatexbase-compat.dtx410
1 files changed, 410 insertions, 0 deletions
diff --git a/luatexbase-compat.dtx b/luatexbase-compat.dtx
new file mode 100644
index 0000000..e1b6381
--- /dev/null
+++ b/luatexbase-compat.dtx
@@ -0,0 +1,410 @@
+% \iffalse meta-comment
+%
+% Written in 2010 by Manuel Pégourié-Gonnard.
+% <mpg@elzevir.fr>
+%
+% 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
+%
+% The class ltxdoc loads the configuration file ltxdoc.cfg
+% if available. Here you can specify further options, e.g.
+% use A4 as paper format:
+% \PassOptionsToClass{a4paper}{article}
+%
+%<*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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+
+Written in 2010 by Manuel Pegourie-Gonnard.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\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
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\documentclass{ltxdoc}
+\input lltxb-dtxstyle.tex
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{luatexbase-compat.dtx}%
+\end{document}
+%</driver>
+% \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 \~}
+%
+% \title{The \pk{luatexbase-compat} package}
+% \date{2010/01/21 v0.1}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \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 regularly tested with
+% \luatex 0.40.6 (\texlive 2009) and from trunk.
+% \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 \texlive).
+%
+% \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 case so that the number of
+% expansion steps remains constant.
+%
+% \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. Also, it is theoretically possible, however
+% unlikely, that the prefixed primitives are not available for some reason.
+%
+% \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 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
+% and 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}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@compat@loaded\endcsname
+\expandafter\let\csname lltxb@compat@loaded\endcsname\endinput
+% \end{macrocode}
+%
+% Catcode defenses.
+%
+% \begin{macrocode}
+\begingroup
+ \catcode123 1 % {
+ \catcode125 2 % }
+ \catcode 35 6 % #
+ \toks0{}%
+ \def\x{}%
+ \def\y#1 #2 {%
+ \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}%
+ \edef\x{\x \catcode#1 #2}}%
+ \y 123 1 % {
+ \y 125 2 % }
+ \y 35 6 % #
+ \y 10 12 % ^^J
+ \y 34 12 % "
+ \y 36 3 % $ $
+ \y 39 12 % '
+ \y 40 12 % (
+ \y 41 12 % )
+ \y 42 12 % *
+ \y 43 12 % +
+ \y 44 12 % ,
+ \y 45 12 % -
+ \y 46 12 % .
+ \y 47 12 % /
+ \y 60 12 % <
+ \y 61 12 % =
+ \y 64 11 % @ (letter)
+ \y 62 12 % >
+ \y 95 12 % _ (other)
+ \y 96 12 % `
+ \edef\y#1{\endgroup\edef#1{\the\toks0\relax}\x}%
+\expandafter\y\csname lltxb@compat@AtEnd\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}[2010/01/21 v0.1 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 PackageWarningNoLine\endcsname\relax
+ \def\x#1#2{\begingroup\newlinechar10
+ \immediate\write16{Package #1 warning: #2}\endgroup}
+ \else
+ \let\x\PackageWarningNoLine
+ \fi
+ \expandafter\endgroup
+ \x{luatexbase-compat}{LuaTeX is required for this package. Aborting.}
+ \lltxb@compat@AtEnd
+ \expandafter\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}
+\lltxb@compat@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% Test fils for Plain and LaTeX
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-compat.sty
+%<testlatex>\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')}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput