summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/Makefile172
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx386
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx549
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx410
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx447
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx837
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx544
-rw-r--r--Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx485
8 files changed, 3830 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/luatex/luatexbase/Makefile b/Master/texmf-dist/source/luatex/luatexbase/Makefile
new file mode 100644
index 00000000000..4f018590786
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/Makefile
@@ -0,0 +1,172 @@
+# Makefile for luatexbase
+
+NAME = luatexbase
+DTX = $(wildcard *.dtx)
+DOC = $(patsubst %.dtx, %.pdf, $(DTX))
+DTXSTY = lltxb-dtxstyle.tex
+
+# Files grouped by generation mode
+UNPACKED_MCB = luatexbase-mcb.sty mcb.lua \
+ test-mcb-latex.tex test-mcb-plain.tex
+UNPACKED_REGS = luatexbase-regs.sty \
+ test-regs-plain.tex test-regs-latex.tex
+UNPACKED_ATTR = luatexbase-attr.sty attr.lua \
+ test-attr-plain.tex test-attr-latex.tex
+UNPACKED_CCTB = luatexbase-cctb.sty cctb.lua \
+ test-cctb-plain.tex test-cctb-latex.tex
+UNPACKED_LOADER = luatexbase-loader.sty luatexbase.loader.lua \
+ test-loader-plain.tex test-loader-latex.tex \
+ $(TEST_LOADER).lua test-loader.sub.lua
+UNPACKED_MODUTILS = luatexbase-modutils.sty modutils.lua test-modutils.lua \
+ test-modutils-plain.tex test-modutils-latex.tex
+UNPACKED_COMPAT = luatexbase-compat.sty \
+ test-compat-plain.tex test-compat-latex.tex
+UNPACKED = $(UNPACKED_MCB) $(UNPACKED_REGS) $(UNPACKED_ATTR) $(UNPACKED_CCTB) \
+ $(UNPACKED_LOADER) $(UNPACKED_MODUTILS) $(UNPACKED_COMPAT)
+COMPILED = $(DOC)
+GENERATED = $(COMPILED) $(UNPACKED)
+SOURCE = $(DTX) $(DTXSTY) README TODO Changes Makefile
+
+# used for check
+TEST_LOADER = test-loader
+TMP_LOADER = $(TEST_LOADER).tex
+
+# Files grouped by installation location
+RUNFILES = $(filter-out test-%, $(UNPACKED))
+DOCFILES = $(DOC) $(filter test-%, $(UNPACKED)) README TODO Changes
+SRCFILES = $(DTX) Makefile
+
+# The following definitions should be equivalent
+# ALL_FILES = $(RUNFILES) $(DOCFILES) $(SRCFILES)
+ALL_FILES = $(GENERATED) $(SOURCE)
+
+# Installation locations
+FORMAT = luatex
+RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
+TEXMFROOT = ./texmf
+
+INSTALL_RUNFILES = @mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+INSTALL_DOCFILES = @mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+INSTALL_SRCFILES = @mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+
+TESTENV = TEXINPUTS=.:$(TEXMFROOT)/tex//:
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+DO_TEX = tex --interaction=batchmode $< >/dev/null
+DO_PDFLATEX = pdflatex --interaction=batchmode $< >/dev/null
+DO_MAKEINDEX = makeindex -s gind.ist $(subst .dtx,,$<) >/dev/null 2>&1
+
+# Main targets definition
+all: $(GENERATED)
+check: check-regs check-attr check-cctb check-loader check-modutils check-mcb \
+ check-compat
+doc: $(COMPILED)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP) Makefile
+world: all ctan
+
+%.pdf: %.dtx $(DTXSTY)
+ $(DO_PDFLATEX)
+ $(DO_MAKEINDEX) || true
+ $(DO_PDFLATEX)
+ $(DO_PDFLATEX)
+
+luatexbase.%.lua: %.lua
+ ln -sf $< $@
+
+$(UNPACKED_MCB): luatexbase-mcb.dtx
+ $(DO_TEX)
+
+$(UNPACKED_REGS): luatexbase-regs.dtx
+ $(DO_TEX)
+
+$(UNPACKED_ATTR): luatexbase-attr.dtx
+ $(DO_TEX)
+
+$(UNPACKED_CCTB): luatexbase-cctb.dtx
+ $(DO_TEX)
+
+$(UNPACKED_LOADER): luatexbase-loader.dtx
+ $(DO_TEX)
+
+$(UNPACKED_MODUTILS): luatexbase-modutils.dtx
+ $(DO_TEX)
+
+$(UNPACKED_COMPAT): luatexbase-compat.dtx
+ $(DO_TEX)
+
+check-regs: $(UNPACKED_REGS)
+ luatex --interaction=batchmode test-regs-plain.tex >/dev/null
+ lualatex --interaction=batchmode test-regs-latex.tex >/dev/null
+
+check-attr: install-runfiles
+ $(TESTENV) luatex --interaction=batchmode test-attr-plain.tex >/dev/null
+ $(TESTENV) lualatex --interaction=batchmode test-attr-latex.tex >/dev/null
+
+check-cctb: install-runfiles
+ $(TESTENV) luatex --interaction=batchmode test-cctb-plain.tex >/dev/null
+ $(TESTENV) lualatex --interaction=batchmode test-cctb-latex.tex >/dev/null
+
+check-loader: install-runfiles
+ echo "this is no lua code" > $(TMP_LOADER)
+ $(TESTENV) luatex --interaction=batchmode test-loader-plain.tex >/dev/null
+ $(TESTENV) lualatex --interaction=batchmode test-loader-latex.tex >/dev/null
+
+check-modutils: install-runfiles
+ $(TESTENV) luatex --interaction=batchmode test-modutils-plain.tex >/dev/null
+ $(TESTENV) lualatex --interaction=batchmode test-modutils-latex.tex >/dev/null
+
+check-mcb: install-runfiles
+ $(TESTENV) luatex --interaction=batchmode test-mcb-plain.tex >/dev/null
+ $(TESTENV) lualatex --interaction=batchmode test-mcb-latex.tex >/dev/null
+
+check-compat: $(UNPACKED_COMPAT)
+ luatex --interaction=batchmode test-compat-plain.tex >/dev/null
+ lualatex --interaction=batchmode test-compat-latex.tex >/dev/null
+
+$(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @zip -9 $@ $^ >/dev/null
+
+$(TDS_ZIP): TEXMFROOT=./tmp-texmf
+$(TDS_ZIP): $(ALL_FILES)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ $(INSTALL_RUNFILES)
+ $(INSTALL_DOCFILES)
+ $(INSTALL_SRCFILES)
+ @cd $(TEXMFROOT) && zip -9 ../$@ -r . >/dev/null
+ @$(RM) -r -- $(TEXMFROOT)
+
+.PHONY: install manifest clean mrproper install-runfiles
+
+install: $(ALL_FILES)
+ @echo "Installing in '$(TEXMFROOT)'."
+ $(INSTALL_RUNFILES)
+ $(INSTALL_DOCFILES)
+ $(INSTALL_SRCFILES)
+
+install-runfiles: $(RUNFILES)
+ $(INSTALL_RUNFILES)
+
+manifest:
+ @echo "Source files:"
+ @for f in $(SOURCE); do echo $$f; done
+ @echo ""
+ @echo "Derived files:"
+ @for f in $(GENERATED); do echo $$f; done
+
+clean:
+ @$(RM) -- *.log *.aux *.toc *.idx *.ind *.ilg *.out test-*.pdf
+
+mrproper: clean
+ @$(RM) -- $(GENERATED) $(ZIPS) $(TMP_LOADER)
+ @$(RM) -r $(TEXMFROOT)
+
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx
new file mode 100644
index 00000000000..cf310d06570
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx
@@ -0,0 +1,386 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-attr.dtx
+% and the derived files
+% luatexbase-attr.sty attr.lua
+% test-regs-plain.tex test-regs-latex.tex
+%
+% Unpacking:
+% tex luatexbase-attr.dtx
+% Documentation:
+% pdflatex luatexbase-attr.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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-attr.sty}{\from{luatexbase-attr.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-attr-plain.tex}{\from{luatexbase-attr.dtx}{testplain}}%
+ \file{test-attr-latex.tex}{\from{luatexbase-attr.dtx}{testlatex}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{attr.lua}{\from{luatexbase-attr.dtx}{luamodule}}%
+}
+
+\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-attr.sty attr.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\input lltxb-dtxstyle
+\begin{document}
+ \DocInput{luatexbase-attr.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-attr} package}
+% \date{v0.2 2010-05-12}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% In addition to the registers existing in \tex and \etex, \luatex introduces
+% a new concept: attributes. This package takes care of attribute allocation
+% just like Plain TeX and LaTeX do for other registers.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% The main macro defined here is |\newluatexattribute|. It behaves in the same
+% way as |\newcount|. There are also two helper macros: |\setluatexattibute|
+% sets an attribute's value (locally, but you can use |\global| in front of
+% it). |\unsetluatexattribute| unsets an atribute by giving it a special
+% value, depending on \luatex's version; you should always use this macro
+% in order to be sure the correct special value for your version of \luatex is
+% used.
+%
+% Due to the intended use of attributes, it makes no sense to locally
+% allocate an attribute the way you can locally allocate a counter using
+% \file{etex.sty}'s |\loccount|, so no corresponding macro is defined.
+%
+% The various Lua functions for manipulating attributes use a number to
+% designate the attribute. Hence, package writers need a way to know the
+% number of the attribute associated to |\fooattr| assuming it was defined
+% using |\newluatexattribute\fooattr|, something that \luatex currently
+% doesn't support (you can get the current value of the associated attribute
+% as |tex.atrribute.fooattr|, but not the attribute number).
+%
+% There are several ways to work around this. For example, it is possible to
+% extract the number at any time from the |\meaning| of |\foobar|.
+% Alternatively, one could look at |\the\allocationnumber| just after the
+% definition of |\fooattr| and remember it in a Lua variable. For your
+% convenience, this is automatically done by |\newluatexattribute|: the number
+% is remembered in a dedicated Lua table so that you can get it as
+% |luatexbase.attributes.foobar| (mind the absence of backslash here) at any
+% time.
+%
+% \section{Implementation}
+%
+% \subsection{\tex package}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsubsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@attr@loaded\endcsname
+\expandafter\let\csname lltxb@attr@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@attr@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-attr}[2010/05/12 v0.2 Attributes allocation 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-attr}{LuaTeX is required for this package. Aborting.}
+ \lltxb@attr@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsubsection{Primitives needed}
+%
+% Load \pk{luatexbase-compat}.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-compat.sty
+\else
+ \RequirePackage{luatexbase-compat}
+\fi
+% \end{macrocode}
+%
+% Make sure the primitives we need are available.
+%
+% \begin{macrocode}
+\luatexbase@ensure@primitive{luaescapestring}
+\luatexbase@ensure@primitive{attributedef}
+\luatexbase@ensure@primitive{attribute}
+% \end{macrocode}
+%
+% \subsubsection{Load supporting Lua module}
+%
+% First load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), then
+% the supporting Lua module.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-loader.sty
+\else
+ \RequirePackage{luatexbase-loader}
+\fi
+\luatexbase@directlua{require('luatexbase.attr')}
+% \end{macrocode}
+%
+% \subsection{User macros}
+%
+% The allocaton macro.
+%
+% \begin{macrocode}
+\newcount\lltxb@attribute@alloc
+\lltxb@attribute@alloc\m@ne
+\def\newluatexattribute#1{%
+ \ifnum\lltxb@attribute@alloc<65535\relax
+ \global\advance\lltxb@attribute@alloc\@ne
+ \allocationnumber\lltxb@attribute@alloc
+ \global\luatexattributedef#1=\allocationnumber
+ \unsetluatexattribute#1%
+ \begingroup\escapechar\m@ne
+ \luatexbase@directlua{luatexbase.attributedef_from_tex(
+ '\luatexluaescapestring{\string#1}', '\number\allocationnumber')}%
+ \endgroup
+ \wlog{\string#1=\string\luatexattribute\the\allocationnumber}%
+ \else
+ \errmessage{No room for a new \string\attribute}%
+ \fi}
+% \end{macrocode}
+%
+% Helper macro |\unsetluatexattribute|: depends on \luatex's version.
+%
+% \begin{macrocode}
+\def\unsetluatexattribute#1{%
+ \ifnum\luatexversion<37\relax
+ #1=-1\relax
+ \else
+ #1=-"7FFFFFFF\relax
+ \fi}
+% \end{macrocode}
+%
+% And now the trivial helper macro.
+%
+% \begin{macrocode}
+\def\setluatexattribute#1#2{%
+ #1=\numexpr#2\relax}
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \begin{macrocode}
+\lltxb@attr@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \subsection{Lua module}
+%
+% \begin{macrocode}
+%<*luamodule>
+module('luatexbase', package.seeall)
+% \end{macrocode}
+%
+% Record the allocation number in a Lua table.
+%
+% \begin{macrocode}
+attributes = {}
+function attributedef_from_tex(name, number)
+ attributes[name] = tonumber(number)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</luamodule>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% The tests done are very basic: we just make sure that the package loads
+% correctly and the macros don't generate any error, under both LaTeX en
+% Plain TeX. We also check that the attribute's number is remembered well,
+% independently of the current value of |\escapechar|.
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-attr.sty
+%<testlatex>\RequirePackage{luatexbase-attr}
+%<*testplain,testlatex>
+\newluatexattribute\testattr
+\setluatexattribute\testattr{1}
+\unsetluatexattribute\testattr
+\catcode64 11
+\luatexbase@directlua{assert(luatexbase.attributes.testattr)}
+\begingroup
+\escapechar64
+\newluatexattribute\anotherattr
+\endgroup
+\setluatexattribute\anotherattr{1}
+\luatexbase@directlua{assert(luatexbase.attributes.anotherattr)}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx
new file mode 100644
index 00000000000..141f1203bef
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx
@@ -0,0 +1,549 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-cctb.dtx
+% and the derived files
+% luatexbase-cctb.sty cctb.lua
+% test-cctb-plain.tex test-cctb-latex.tex
+%
+% Unpacking:
+% tex luatexbase-cctb.dtx
+% Documentation:
+% pdflatex luatexbase-cctb.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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-cctb.sty}{\from{luatexbase-cctb.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-cctb-plain.tex}{\from{luatexbase-cctb.dtx}{testplain}}%
+ \file{test-cctb-latex.tex}{\from{luatexbase-cctb.dtx}{testlatex}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{cctb.lua}{\from{luatexbase-cctb.dtx}{luamodule}}%
+}
+
+\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-cctb.sty cctb.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\input{lltxb-dtxstyle}
+\begin{document}
+ \DocInput{luatexbase-cctb.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-cctb} package}
+% \date{v0.2 2010-05-12}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \texttt{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% In addition to the registers existing in \tex and \etex, \luatex introduces
+% a new concept: catcode tables. This package takes care of catcode table
+% allocation just like Plain TeX and LaTeX do for other registers.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% The main macro defined here is |\newluatexcatcodetable|. It behaves the same
+% as |\newbox|. Additonally, the newly allocated catcode table is initialised
+% to the catcodes of Ini\tex. In order to help you define the catcode tables
+% (once they are allocated), two helper macros are available.
+%
+% \begin{quote}
+% \cs{setcatcoderange}\marg{from}\marg{to}\marg{value}
+% \end{quote}
+% Set all characters code in the range \meta{from}--\meta{to} to the given
+% catcode \meta{value}.
+%
+% \begin{quote}
+% \cs{setluatexcatcodetable}\marg{table}\marg{catcode statements}
+% \end{quote}
+% Set a previously allocated \meta{table} to the catcodes given by executing
+% \meta{catcode statements}. Note that \meta{table} must not be the current
+% active catcode table. You may, however, load another catcode table in your
+% \meta{catcode statements}.
+%
+% For your convenience, a few catcode tables are prefined:
+% \begin{itemize}
+% \item |\CatcodeTableIniTeX|: Ini\tex catcodes.
+% \item |\CatcodeTableString|: the catcode regime used by |\string| and
+% |\meaning|: everything has catcode 12, except space (U+0020) that has
+% catcode 10.
+% \item |\CatcodeTableOther|: everything (included space) has catcode 12.
+% \item |\CatcodeTableLaTeX|: basic \LaTeXe\ catcodes.
+% \item |\CatcodeTableLaTeXAtLetter|: same as above, but |@| is a letter.
+% \item |\CatcodeTableExpl|: catcodes used by \latex{}3 with |\ExplSyntaxOn|.
+% Be aware that this does not provide the exact same environment as
+% |\ExplSyntaxOn|: most noticibly, some booleans are not set, and
+% |\endlinechar| is not adjusted (it should be 32).
+% \end{itemize}
+%
+% Various Lua function accept a catcode table number as argument. In order to
+% use them, the package writer needs to know the number of an allocated
+% catcode table. Since |\chardef| is used for the definition of the control
+% sequence, this is rather easy to do. However, for extra ease of use, the
+% numbers are also directly accessible from Lua as the value of the table
+% |luatexbase.catcodetables|, whose keys is the name of the control sequence
+% (without any leading backslash). Moreover, nickames are available for the
+% predefined catcode tables:
+% \begin{itemize}
+% \item |CatcodeTableIniTeX| = |ini|,
+% \item |CatcodeTableString| = |string|,
+% \item |CatcodeTableOther| = |other|,
+% \item |CatcodeTableLaTeX| = |latex|,
+% \item |CatcodeTableLaTeXAtLetter| = |latex-atletter| = |latex-package|,
+% \item |CatcodeTableExpl| = |expl| = |expl3|,
+% \end{itemize}
+%
+% \section{Implementation}
+%
+% \subsection{\tex package}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsubsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@cctb@loaded\endcsname
+\expandafter\let\csname lltxb@cctb@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@cctb@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-cctb}[2010/05/11 v0.2 Catcodetable allocation 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-cctb}{LuaTeX is required for this package. Aborting.}
+ \lltxb@cctb@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsubsection{Load supporting Lua module}
+%
+% First load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), then
+% the supporting Lua module.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-loader.sty
+\else
+ \RequirePackage{luatexbase-loader}
+\fi
+\luatexbase@directlua{require('luatexbase.cctb')}
+% \end{macrocode}
+%
+% \subsubsection{Primitives needed}
+%
+% Load \pk{luatexbase-compat}.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-compat.sty
+\else
+ \RequirePackage{luatexbase-compat}
+\fi
+% \end{macrocode}
+%
+% Make sure the primitives we need are available.
+%
+% \begin{macrocode}
+\luatexbase@ensure@primitive{luaescapestring}
+\luatexbase@ensure@primitive{catcodetable}
+\luatexbase@ensure@primitive{initcatcodetable}
+\luatexbase@ensure@primitive{savecatcodetable}
+% \end{macrocode}
+%
+% \subsubsection{User macros}
+%
+% The allocation macro. Allocate tables starting with 1, since table 0 is
+% reserved for IniTeX catcodes by LuaTeX.
+%
+% \begin{macrocode}
+\newcount\lltxb@catcodetable@alloc
+\lltxb@catcodetable@alloc\z@
+\def\newluatexcatcodetable#1{%
+ \ifnum\lltxb@catcodetable@alloc<65535\relax
+ \global\advance\lltxb@catcodetable@alloc\@ne
+ \allocationnumber\lltxb@catcodetable@alloc
+ \global\chardef#1\allocationnumber
+ \luatexinitcatcodetable\allocationnumber
+ \begingroup\escapechar\m@ne
+ \luatexbase@directlua{luatexbase.catcodetabledef_from_tex(
+ '\luatexluaescapestring{\string#1}', '\number\allocationnumber')}%
+ \endgroup
+ \wlog{\string#1=\string\luatexcatcodetable\the\allocationnumber}%
+ \else
+ \errmessage{No room for a new \string\luatexcatcodetable}%
+ \fi}
+% \end{macrocode}
+%
+% A small patch to get two new counters in Plain too.
+%
+% \begin{macrocode}
+\expandafter\ifx\csname @tempcnta\endcsname\relax
+ \csname newcount\endcsname\@tempcnta
+\fi
+\expandafter\ifx\csname @tempcntb\endcsname\relax
+ \csname newcount\endcsname\@tempcntb
+\fi
+% \end{macrocode}
+%
+% Set the catcodes for a range of characters.
+%
+% \begin{macrocode}
+\def\setcatcoderange#1#2#3{%
+ \edef\luaSCR@temp{%
+ \noexpand\@tempcnta=\the\@tempcnta
+ \noexpand\@tempcntb=\the\@tempcntb
+ \noexpand\count@=\the\count@
+ \relax}%
+ \@tempcnta=#1\relax
+ \@tempcntb=#2\relax
+ \count@=#3\relax
+ \loop\unless\ifnum\@tempcnta>\@tempcntb
+ \catcode\@tempcnta=\count@
+ \advance\@tempcnta\@ne
+ \repeat
+ \luaSCR@temp}
+% \end{macrocode}
+%
+% Set a catcode table.
+%
+% \begin{macrocode}
+\def\setluatexcatcodetable#1#2{%
+ \begingroup
+ #2%
+ \luatexsavecatcodetable#1%
+ \endgroup}
+% \end{macrocode}
+%
+% \subsubsection{Predefined tables}
+%
+% The |IniTeX| catcode table needs no extra initialisation.
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableIniTeX
+% \end{macrocode}
+%
+% The |String| and |Other| catcode tables.
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableString
+\setluatexcatcodetable\CatcodeTableString{%
+ \luatexcatcodetable\CatcodeTableIniTeX
+ \catcode0 12 % nul
+ \catcode13 12 % carriage return
+ \catcode37 12 % percent
+ \setcatcoderange{65}{90}{12}% A-Z
+ \setcatcoderange{97}{122}{12}% a-z
+ \catcode92 12 % backslash
+ \catcode127 12 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableOther
+\setluatexcatcodetable\CatcodeTableOther{%
+ \luatexcatcodetable\CatcodeTableString
+ \catcode32 12 }
+% \end{macrocode}
+%
+% Tables for \LaTeXe.
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableLaTeX
+\setluatexcatcodetable\CatcodeTableLaTeX{%
+ \luatexcatcodetable\CatcodeTableIniTeX
+ \setcatcoderange{0}{31}{15}%
+ \catcode9 10 % tab
+ \catcode12 13 % form feed
+ \catcode13 5 % carriage return
+ \catcode35 6 % hash
+ \catcode36 3 % dollar
+ \catcode38 4 % ampersand
+ \catcode94 7 % circumflex
+ \catcode95 8 % underscore
+ \catcode123 1 % brace left
+ \catcode125 2 % brace right
+ \catcode126 13 % tilde
+ \catcode127 15 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableLaTeXAtLetter
+\setluatexcatcodetable\CatcodeTableLaTeXAtLetter{%
+ \luatexcatcodetable\CatcodeTableLaTeX
+ \catcode64=11 }
+% \end{macrocode}
+%
+% A table for \pk{expl3}.
+%
+% \begin{macrocode}
+\newluatexcatcodetable\CatcodeTableExpl
+\setluatexcatcodetable\CatcodeTableExpl{%
+ \luatexcatcodetable\CatcodeTableLaTeX
+ \catcode126 10 % tilde is a space char
+ \catcode32 9 % space is ignored
+ \catcode9 9 % tab also ignored
+ \catcode95 11 % underscore letter
+ \catcode58 11 % colon letter
+ }
+% \end{macrocode}
+%
+% Finally do the shortcuts.
+%
+% \begin{macrocode}
+\luatexbase@directlua{luatexbase.catcodetable_do_shortcuts()}
+% \end{macrocode}
+%
+% That's all, folks!
+%
+% \begin{macrocode}
+\lltxb@cctb@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \subsection{Lua module}
+%
+% \begin{macrocode}
+%<*luamodule>
+module('luatexbase', package.seeall)
+% \end{macrocode}
+%
+% The number associated to a CS name is remembered in the |catcodetables|
+% table.
+%
+% \begin{macrocode}
+catcodetables = {}
+function catcodetabledef_from_tex(name, number)
+ catcodetables[name] = tonumber(number)
+end
+% \end{macrocode}
+%
+% The next function creates some shortcuts for better readability in lua
+% code. This makes |luatexbase.catcodetables.latex| equivalent to
+% |luatexbase.catcodetables.CatcodeTableLaTeX|.
+%
+% \begin{macrocode}
+function catcodetable_do_shortcuts()
+ local cat = catcodetables
+ cat['latex'] = cat.CatcodeTableLaTeX
+ cat['latex-package'] = cat.CatcodeTableLaTeXAtLetter
+ cat['latex-atletter'] = cat.CatcodeTableLaTeXAtLetter
+ cat['ini'] = cat.CatcodeTableIniTeX
+ cat['expl3'] = cat.CatcodeTableExpl
+ cat['expl'] = cat.CatcodeTableExpl
+ cat['string'] = cat.CatcodeTableString
+ cat['other'] = cat.CatcodeTableOther
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</luamodule>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% The tests done are very basic: we just make sure that the package loads
+% correctly and the macros don't generate any error, under both LaTeX en
+% Plain TeX.
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-cctb.sty
+%<testlatex>\RequirePackage{luatexbase-cctb}
+%<*testplain,testlatex>
+\begingroup \catcode64 11 \global\let\lua\luatexbase@directlua \endgroup
+% \end{macrocode}
+%
+% Also check that the catcodetable's number is remembered well,
+% independently of the current value of |\escapechar|.
+
+% \begin{macrocode}
+\newluatexcatcodetable\testcctb
+\lua{assert(luatexbase.catcodetables.testcctb)}
+\begingroup
+\escapechar64
+\newluatexcatcodetable\anothercctb
+\endgroup
+\lua{assert(luatexbase.catcodetables.anothercctb)}
+% \end{macrocode}
+%
+% Now, play a little bit with predefined tables.
+%
+% \begin{macrocode}
+\luatexcatcodetable\CatcodeTableLaTeXAtLetter
+\ifnum\catcode64=11 \else \ERROR \fi
+\luatexcatcodetable\CatcodeTableLaTeX
+\ifnum\catcode64=12 \else \ERROR \fi
+%<testlatex>\documentclass{minimal}
+\lua{%
+ tex.sprint('\string\\setbox0=\string\\hbox{')
+ tex.sprint(luatexbase.catcodetables.string, "\string\\undef # _^&")
+ tex.sprint('}')
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx
new file mode 100644
index 00000000000..dbff084195c
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/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{v0.2 2010/05/12}
+% \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/05/12 v0.2 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
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx
new file mode 100644
index 00000000000..8fe81acb6d5
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx
@@ -0,0 +1,447 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-loader.dtx
+% and the derived files
+% luatexbase-loader.sty luatexbase.loader.lua
+% test-loader-plain.tex test-loader-latex.tex
+%
+% Unpacking:
+% tex luatexbase-loader.dtx
+% Documentation:
+% pdflatex luatexbase-loader.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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-loader.sty}{\from{luatexbase-loader.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-loader-plain.tex}{\from{luatexbase-loader.dtx}{testplain}}%
+ \file{test-loader-latex.tex}{\from{luatexbase-loader.dtx}{testlatex}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase.loader.lua}{\from{luatexbase-loader.dtx}{luamodule}}%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-loader.lua}{\from{luatexbase-loader.dtx}{testdummy}}%
+ \file{test-loader.sub.lua}{\from{luatexbase-loader.dtx}{testdummy}}%
+}
+
+\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-loader.sty luatex.loader.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\input{lltxb-dtxstyle}
+\begin{document}
+ \DocInput{luatexbase-loader.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-loader} package}
+% \date{v0.2 2010-05-12}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \texttt{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% Lua modules are loaded using the |require()| function which, similarly to
+% \tex's |\input|, takes care of locating the file and load it, but also makes
+% a few supplementary checks, for example to avoid loading the same module
+% twice. This package adapts the way the files are searched in order to
+% accommodate the TDS as well as usual Lua naming conventions.
+%
+% For higher-level functions related to Lua modules, see
+% \href{file:luatexbase-modutils.pdf}{\pk{luatexbase-modutils}}, which also
+% loads the present package.
+% \end{abstract}
+%
+% \section{Documentation}
+%
+% Starting with \luatex 0.45.0, |require()| uses Kpathsea for file searching
+% when the library is initialised (which is always the case in \tex mode,
+% unless explicitly disabled by the user). However, it does not respect the
+% Lua convention that |require("foo.bar")| should look for |foo/bar.lua|.
+% \footnote{Support for that has been added in rev 3558 of \luatex, currently
+% unreleased but probably part of \luatex 0.54.} This package implements such
+% behaviour.
+%
+% More precisely, it implements a new kpse searcher that looks for file
+% |foo/bar| using Kpathsea with the format |lua| (that is, search along
+% |LUAINPUTS| and try the following extensions: |.luc|, |.luctex|, |.texluc|,
+% |.lua|, |.luatex|, |.texlua|). If this search fails, it falls back to
+% |foo.bar| (along the same path with the same extensions).
+%
+% Also, older versions of \luatex, such as 0.25.4 (\texlive 2008), don't know
+% about the |lua| format for kpse searching. So, an emulator for this function
+% is provided. The emulator is not perfect, in particular it may find more
+% results than the normal |lua| format search.\footnote{An may also fail to
+% find the file in particular cases, see comments in the implementation for
+% details.} In order to ensure more homogeneous results across versions, this
+% emulator is used as a fall-back when the real |lua| format search doesn't
+% find any result.
+%
+% Finally, a combined version of this new kpse searcher and the original
+% function at |package.loaders[2]| (using first the new loader, then the old
+% one if the new doesn't return any result) is installed as
+% |package.loaders[2]|.
+%
+% \section{Implementation}
+%
+% \subsection{\tex package}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsubsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@loader@loaded\endcsname
+\expandafter\let\csname lltxb@loader@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@loader@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-loader}[2010/05/12 v0.2 Lua module loader 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-loader}{LuaTeX is required for this package. Aborting.}
+ \lltxb@loader@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsubsection{Main content}
+%
+% First load \pk{luatexbase-compat}.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-compat.sty
+\else
+ \RequirePackage{luatexbase-compat}
+\fi
+% \end{macrocode}
+%
+% Load the supporting Lua module. This one doesn't follow the usual naming
+% conventions, since it won't be loaded with the usual functions for
+% obvious bootstraping reasons.
+%
+% \begin{macrocode}
+\luatexbase@directlua{%
+ local file = "luatexbase.loader.lua"
+ local path = assert(kpse.find_file(file, 'tex'),
+ "File '"..file.."' no found")
+ texio.write_nl("("..path..")")
+ dofile(path)}
+% \end{macrocode}
+%
+% That's all, folks!
+%
+% \begin{macrocode}
+\lltxb@loader@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \subsection{Lua module}
+%
+% \begin{macrocode}
+%<*luamodule>
+module('luatexbase', package.seeall)
+% \end{macrocode}
+%
+% Emulate (approximatively) kpse's lua format search. More precisely,
+% combine the search path of |texmfscripts| and |tex| in order to
+% approximate |LUAINPUTS|. But we need to handle suffixes ourselves.
+%
+% |lua_suffixes| is taken verbatim from Kpathsea's source
+% (\file{tex-file.c}, constant |LUA_SUFFIXES|),\footnote{Unchanged since
+% 2007-07-06, last checked 2010-05-10.}.
+%
+% \begin{macrocode}
+local lua_suffixes = {
+ ".luc", ".luctex", ".texluc", ".lua", ".luatex", ".texlua",
+}
+% \end{macrocode}
+%
+% Auxiliary function for suffixes: says if |suffix| is a suffix of |name|.
+%
+% \begin{macrocode}
+local function ends_with(suffix, name)
+ return name:sub(-suffix:len()) == suffix
+end
+% \end{macrocode}
+%
+% The search function first builds the list of filenames to be search. For
+% the lua format, kpse always adds a suffix if no (known) suffix is
+% present, so we do the same.
+%
+% \begin{macrocode}
+function find_file_lua_emul(name)
+ local search_list = {}
+ for _, suffix in ipairs(lua_suffixes) do
+ if ends_with(suffix, name) then
+ search_list = { name }
+ break
+ else
+ table.insert(search_list, name..suffix)
+ end
+ end
+% \end{macrocode}
+%
+% Now look for each file in this list.
+%
+% \begin{macrocode}
+ for _, search_name in ipairs(search_list) do
+ local f = kpse.find_file(search_name, 'texmfscripts')
+ or kpse.find_file(search_name, 'tex')
+% \end{macrocode}
+%
+% There is a problem with using the |tex| search format: kpse will try to
+% add suffixes from the |TEX_SUFFIXES| list, which may lead to problems
+% if a file like \meta{name}|.lua.tex| exists. We prevent that by checking if
+% the file found ends with the required name. So \meta{name}|.lua| will
+% still be hidden by \meta{name}.|lua.tex| but it seems less bad not to
+% find it than to return an incorrect result.
+%
+% \begin{macrocode}
+ if f and ends_with(search_name, f) then
+ return f
+ end
+ end
+end
+% \end{macrocode}
+%
+% If lua search format is available, use it with emulation as a fall-back,
+% or just use emulation.
+%
+% \begin{macrocode}
+local find_file_lua
+if pcall('kpse.find_file', 'dummy', 'lua') then
+ find_file_lua = function (name)
+ return kpse.find_file(name, 'lua') or find_file_lua_emul(name)
+ end
+else
+ find_file_lua = function (name)
+ return find_file_lua_emul(name)
+ end
+end
+% \end{macrocode}
+%
+% Find the full path corresponding to a module name.
+%
+% \begin{macrocode}
+local function find_module_file(mod)
+ return find_file_lua(mod:gsub('%.', '/'), 'lua')
+ or find_file_lua(mod, 'lua')
+end
+% \end{macrocode}
+%
+% Combined searcher, using primarily the new kpse searcher, and the
+% original as a fall-back.
+%
+% \begin{macrocode}
+local package_loader_two = package.loaders[2]
+local function load_module(mod)
+ local file = find_module_file(mod)
+ if not file then
+ local msg = "\n\t[luatexbase.loader] Search failed"
+ local ret = package_loader_two(mod)
+ if type(ret) == 'string' then
+ return msg..ret
+ elseif type(ret) == 'nil' then
+ return msg
+ else
+ return ret
+ end
+ end
+ local loader, error = loadfile(file)
+ if not loader then
+ return "\n\t[luatexbase.loader] Loading error:\n\t"..error
+ end
+ texio.write_nl("("..file..")")
+ return loader
+end
+% \end{macrocode}
+%
+% Finally install this combined loader as loader 2.
+%
+% \begin{macrocode}
+package.loaders[2] = load_module
+%</luamodule>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% A dummy lua file for tests.
+%
+% \begin{macrocode}
+%<*testdummy>
+return true
+%</testdummy>
+% \end{macrocode}
+%
+% Check that the package loads properly, under both LaTeX and Plain TeX,
+% and load a dummy module in the current diretory.
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-loader.sty
+%<testlatex>\RequirePackage{luatexbase-loader}
+%<*testplain,testlatex>
+\catcode64 11
+\luatexbase@directlua{require "test-loader"}
+\luatexbase@directlua{require "test-loader.sub"}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx
new file mode 100644
index 00000000000..f30753c737f
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx
@@ -0,0 +1,837 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-mcb.dtx
+% and the derived files
+% luatexbase-mcb.sty, mcb.lua, luatexbase-mcb.pdf,
+% test-mcb-plain.tex test-mcb-latex.tex
+%
+% Unpacking:
+% tex luatexbase-mcb.dtx
+% Documentation:
+% pdflatex luatexbase-mcb.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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+Copyright (C) 2009 by Elie Roux <elie.roux@telecom-bretagne.eu>
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-mcb.sty}{\from{luatexbase-mcb.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-mcb-plain.tex}{\from{luatexbase-mcb.dtx}{testplain}}%
+ \file{test-mcb-latex.tex}{\from{luatexbase-mcb.dtx}{testlatex}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{mcb.lua}{\from{luatexbase-mcb.dtx}{lua}}%
+}
+
+\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-mcb.sty mcb.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\input{lltxb-dtxstyle}
+\begin{document}
+ \DocInput{luatexbase-mcb.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 \textsf{luatexbase-mcb} package}
+% \date{2010/05/12 v0.2}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This package manages the callback adding and removing, by adding
+% \texttt{callback.add} and \texttt{callback.remove}, and overwriting
+% \texttt{callback.register}. It also allows to create and call new callbacks.
+% For an introduction on this package (among others), please refer to the
+% document \texttt{luatextra-reference.pdf}.
+% \par\textbf{Warning.} Currently assumes that \textsf{luatexbase-modutils}
+% has been previously loaded. (This is a temporary limitation.)
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% Lua\TeX\ provides an extremely interesting feature, named callbacks. It
+% allows to call some lua functions at some points of the \TeX\ algorithm (a
+% \emph{callback}), like when \TeX\ breaks likes, puts vertical spaces, etc.
+% The Lua\TeX\ core offers a function called \texttt{callback.register} that
+% enables to register a function in a callback.
+%
+% The problem with \texttt{callback.register} is that is registers only one
+% function in a callback. For a lot of callbacks it can be common to have
+% several packages registering their function in a callback, and thus it is
+% impossible with them to be compatible with each other.
+%
+% This package solves this problem by adding mainly one new function
+% \texttt{callback.\\add} that adds a function in a callback. With this
+% function it is possible for packages to register their function in a
+% callback without overwriting the functions of the other packages.
+%
+% The functions are called in a certain order, and when a package registers a
+% callback it can assign a priority to its function. Conflicts can still
+% remain even with the priority mechanism, for example in the case where two
+% packages want to have the highest priority. In these cases the packages have
+% to solve the conflicts themselves.
+%
+% This package also privides a way to create and call new callbacks, in
+% addition to the default Lua\TeX\ callbacks.
+%
+% \subsubsection*{Limitations}
+%
+% This package only works for callbacks where it's safe to add multiple
+% functions without changing the functions' signatures. There are callbacks,
+% though, where registering several functions is not possible without changing
+% the function's signatures, like for example the readers callbacks. These
+% callbacks take a filename and give the datas in it. One solution would be to
+% change the functions' signature to open it when the function is the first,
+% and to take the datas and modify them eventually if they are called after
+% the first. But it seems rather fragile and useless, so it's not implemented.
+% With these callbacks, in this package we simply execute the first function
+% in the list.
+%
+% Other callbacks in this case are \texttt{define\_font} and
+% \texttt{open\_read\_file}. There is though a solution for several packages
+% to use these callbacks, see the implementation of \texttt{luatextra}.
+%
+% \section{Implementation}
+%
+% \subsection{\tex package}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsubsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@mcb@loaded\endcsname
+\expandafter\let\csname lltxb@mcb@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@mcb@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-mcb}[2010/05/12 v0.2 Callback management 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-mcb}{LuaTeX is required for this package. Aborting.}
+ \lltxb@mcb@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsubsection{Load supporting Lua module}
+%
+% First load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), then
+% the supporting Lua module.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-modutils.sty
+\else
+ \RequirePackage{luatexbase-modutils}
+\fi
+\luatexbase@directlua{require('luatexbase.mcb')}
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \begin{macrocode}
+\lltxb@mcb@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \subsection{Lua module}
+%
+% \begin{macrocode}
+%<*lua>
+% \end{macrocode}
+%
+% \subsubsection{Module identification}
+%
+% \begin{macrocode}
+module('luatexbase', package.seeall)
+luatexbase.provides_module({
+ name = "luamcallbacks",
+ version = 0.2,
+ date = "2010/05/12",
+ description = "register several functions in a callback",
+ author = "Hans Hagen, Elie Roux and Manuel Pégourie-Gonnard",
+ copyright = "Hans Hagen, Elie Roux and Manuel Pégourie-Gonnard",
+ license = "CC0",
+})
+% \end{macrocode}
+%
+% Shortcuts for error functions.
+%
+% \begin{macrocode}
+local log = log or function(...)
+ luatexbase.module_log('luamcallbacks', string.format(...))
+end
+local info = info or function(...)
+ luatexbase.module_info('luamcallbacks', string.format(...))
+end
+local warning = warning or function(...)
+ luatexbase.module_warning('luamcallbacks', string.format(...))
+end
+local err = err or function(...)
+ luatexbase.module_error('luamcallbacks', string.format(...))
+end
+% \end{macrocode}
+%
+% \subsubsection{Initialisations}
+%
+% \texttt{callbacklist} is the main list, that contains the callbacks as
+% keys and a table of the registered functions a values.
+%
+% \begin{macrocode}
+local callbacklist = callbacklist or { }
+% \end{macrocode}
+%
+% A table with the default functions of the created callbacks. See
+% \texttt{create} for further informations.
+%
+% \begin{macrocode}
+local lua_callbacks_defaults = { }
+% \end{macrocode}
+%
+% There are 4 types of callback:
+% \begin{itemize}
+% \item the ones taking a list of nodes and returning a boolean and
+% eventually a new head (\texttt{list})
+% \item the ones taking datas and returning the modified ones
+% (\texttt{data})
+% \item the ones that can't have multiple functions registered in them
+% (\texttt{first})
+% \item the ones for functions that don't return anything (\texttt{simple})
+% \end{itemize}
+%
+% \begin{macrocode}
+local list = 1
+local data = 2
+local first = 3
+local simple = 4
+% \end{macrocode}
+%
+% \texttt{callbacktypes} is the list that contains the callbacks as keys
+% and the type (list or data) as values.
+%
+% \begin{macrocode}
+local callbacktypes = callbacktypes or {
+ buildpage_filter = simple,
+ token_filter = first,
+ pre_output_filter = list,
+ hpack_filter = list,
+ process_input_buffer = data,
+ mlist_to_hlist = list,
+ vpack_filter = list,
+ define_font = first,
+ open_read_file = first,
+ linebreak_filter = list,
+ post_linebreak_filter = list,
+ pre_linebreak_filter = list,
+ start_page_number = simple,
+ stop_page_number = simple,
+ start_run = simple,
+ show_error_hook = simple,
+ stop_run = simple,
+ hyphenate = simple,
+ ligaturing = simple,
+ kerning = data,
+ find_write_file = first,
+ find_read_file = first,
+ find_vf_file = data,
+ find_map_file = data,
+ find_format_file = data,
+ find_opentype_file = data,
+ find_output_file = data,
+ find_truetype_file = data,
+ find_type1_file = data,
+ find_data_file = data,
+ find_pk_file = data,
+ find_font_file = data,
+ find_image_file = data,
+ find_ocp_file = data,
+ find_sfd_file = data,
+ find_enc_file = data,
+ read_sfd_file = first,
+ read_map_file = first,
+ read_pk_file = first,
+ read_enc_file = first,
+ read_vf_file = first,
+ read_ocp_file = first,
+ read_opentype_file = first,
+ read_truetype_file = first,
+ read_font_file = first,
+ read_type1_file = first,
+ read_data_file = first,
+}
+% \end{macrocode}
+%
+% In Lua\TeX\ version 0.43, a new callback called |process_output_buffer|
+% appeared, so we enable it. Test the version using the compat package for,
+% well, compatibility.
+%
+% \begin{macrocode}
+if luatexbase.luatexversion > 42 then
+ callbacktypes["process_output_buffer"] = data
+end
+% \end{macrocode}
+%
+% As we overwrite \texttt{callback.register}, we save it as
+% \texttt{internalregister}.
+%
+% \begin{macrocode}
+local internalregister = internalregister or callback.register
+% \end{macrocode}
+%
+% \subsubsection{Unsorted stuff}
+%
+% A simple function we'll use later to understand the arguments of the
+% \texttt{create} function. It takes a string and returns the type
+% corresponding to the string or nil.
+%
+% \begin{macrocode}
+local function str_to_type(str)
+ if str == 'list' then
+ return list
+ elseif str == 'data' then
+ return data
+ elseif str == 'first' then
+ return first
+ elseif str == 'simple' then
+ return simple
+ else
+ return nil
+ end
+end
+% \end{macrocode}
+%
+% This function and the following ones are only internal. This one is the
+% handler for the first type of callbacks: the ones that take a list head
+% and return true, false, or a new list head.
+%
+% \begin{macrocode}
+-- local
+function listhandler (name)
+ return function(head,...)
+ local l = callbacklist[name]
+ if l then
+ local done = true
+ for _, f in ipairs(l) do
+ -- the returned value is either true or a new head plus true
+ rtv1, rtv2 = f.func(head,...)
+ if type(rtv1) == 'boolean' then
+ done = rtv1
+ elseif type (rtv1) == 'userdata' then
+ head = rtv1
+ end
+ if type(rtv2) == 'boolean' then
+ done = rtv2
+ elseif type(rtv2) == 'userdata' then
+ head = rtv2
+ end
+ if done == false then
+ err("function \"%s\" returned false in callback '%s'",
+ f.description, name)
+ end
+ end
+ return head, done
+ else
+ return head, false
+ end
+ end
+end
+% \end{macrocode}
+%
+% The handler for callbacks taking datas and returning modified ones.
+%
+% \begin{macrocode}
+local function datahandler (name)
+ return function(data,...)
+ local l = callbacklist[name]
+ if l then
+ for _, f in ipairs(l) do
+ data = f.func(data,...)
+ end
+ end
+ return data
+ end
+end
+% \end{macrocode}
+%
+% This function is for the handlers that don't support more than one
+% functions in them. In this case we only call the first function of the
+% list.
+%
+% \begin{macrocode}
+local function firsthandler (name)
+ return function(...)
+ local l = callbacklist[name]
+ if l then
+ local f = l[1].func
+ return f(...)
+ else
+ return nil, false
+ end
+ end
+end
+% \end{macrocode}
+%
+% Handler for simple functions that don't return anything.
+%
+% \begin{macrocode}
+local function simplehandler (name)
+ return function(...)
+ local l = callbacklist[name]
+ if l then
+ for _, f in ipairs(l) do
+ f.func(...)
+ end
+ end
+ end
+end
+% \end{macrocode}
+%
+% \subsubsection{Public functions}
+%
+% The main function. The signature is \texttt{add (name,
+% func, description, priority)} with \texttt{name} being the name of the
+% callback in which the function is added; \texttt{func} is the added
+% function; \texttt{description} is a small character string describing the
+% function, and \texttt{priority} an optional argument describing the
+% priority the function will have.
+%
+% The functions for a callbacks are added in a list (in
+% \texttt{callbacklist\\.callbackname}). If they have no
+% priority or a high priority number, they will be added at the end of the
+% list, and will be called after the others. If they have a low priority
+% number, the will be added at the beginning of the list and will be called
+% before the others.
+%
+% Something that must be made clear, is that there is absolutely no
+% solution for packages conflicts: if two packages want the top priority on
+% a certain callback, they will have to decide the priority they will give
+% to their function themselves. Most of the time, the priority is not needed.
+%
+% \begin{macrocode}
+function add_to_callback (name,func,description,priority)
+ if type(func) ~= "function" then
+ err("unable to add function, no proper function passed")
+ return
+ end
+ if not name or name == "" then
+ err("unable to add function, no proper callback name passed")
+ return
+ elseif not callbacktypes[name] then
+ err("unable to add function, '%s' is not a valid callback", name)
+ return
+ end
+ if not description or description == "" then
+ err("unable to add function to '%s', no proper description passed",
+ name)
+ return
+ end
+ if priority_in_callback(name, description) ~= 0 then
+ warning("function '%s' already registered in callback '%s'",
+ description, name)
+ end
+ local l = callbacklist[name]
+ if not l then
+ l = {}
+ callbacklist[name] = l
+ if not lua_callbacks_defaults[name] then
+ if callbacktypes[name] == list then
+ internalregister(name, listhandler(name))
+ elseif callbacktypes[name] == data then
+ internalregister(name, datahandler(name))
+ elseif callbacktypes[name] == simple then
+ internalregister(name, simplehandler(name))
+ elseif callbacktypes[name] == first then
+ internalregister(name, firsthandler(name))
+ else
+ err("unknown callback type")
+ end
+ end
+ end
+ local f = {
+ func = func,
+ description = description,
+ }
+ priority = tonumber(priority)
+ if not priority or priority > #l then
+ priority = #l+1
+ elseif priority < 1 then
+ priority = 1
+ end
+ if callbacktypes[name] == first and (priority ~= 1 or #l ~= 0) then
+ warning("several callbacks registered in callback '%s', "
+ .."only the first function will be active.", name)
+ end
+ table.insert(l,priority,f)
+ log("inserting function '%s' at position %s in callback list for '%s'",
+ description, priority, name)
+end
+% \end{macrocode}
+%
+% The function that removes a function from a callback. The signature is
+% \texttt{remove (name, description)} with \texttt{name} being
+% the name of callbacks, and description the description passed to
+% \texttt{add}.
+%
+% \begin{macrocode}
+function remove_from_callback (name, description)
+ if not name or name == "" then
+ err("unable to remove function, no proper callback name passed")
+ return
+ elseif not callbacktypes[name] then
+ err("unable to remove function, '%s' is not a valid callback", name)
+ return
+ end
+ if not description or description == "" then
+ err(
+ "unable to remove function from '%s', no proper description passed",
+ name)
+ return
+ end
+ local l = callbacklist[name]
+ if not l then
+ err("no callback list for '%s'",name)
+ return
+ end
+ for k,v in ipairs(l) do
+ if v.description == description then
+ table.remove(l,k)
+ log("removing function '%s' from '%s'",description,name)
+ if not next(l) then
+ callbacklist[name] = nil
+ if not lua_callbacks_defaults[name] then
+ internalregister(name, nil)
+ end
+ end
+ return
+ end
+ end
+ warning("unable to remove function '%s' from '%s'",description,name)
+end
+% \end{macrocode}
+%
+% This function removes all the functions registered in a callback.
+%
+% \begin{macrocode}
+function reset_callback (name)
+ if not name or name == "" then
+ err("unable to reset, no proper callback name passed")
+ return
+ elseif not callbacktypes[name] then
+ err("reset error, '%s' is not a valid callback", name)
+ return
+ end
+ if not lua_callbacks_defaults[name] then
+ internalregister(name, nil)
+ end
+ local l = callbacklist[name]
+ if l then
+ log("resetting callback list '%s'",name)
+ callbacklist[name] = nil
+ end
+end
+% \end{macrocode}
+%
+% This first function creates a new callback. The signature is
+% \texttt{create(name, ctype, default)} where \texttt{name} is the name of
+% the new callback to create, \texttt{ctype} is the type of callback, and
+% \texttt{default} is the default function to call if no function is
+% registered in this callback.
+%
+% The created callback will behave the same way Lua\TeX\ callbacks do, you
+% can add and remove functions in it. The difference is that the callback
+% is not automatically called, the package developer creating a new
+% callback must also call it, see next function.
+%
+% \begin{macrocode}
+function create_callback(name, ctype, default)
+ if not name then
+ err("unable to call callback, no proper name passed", name)
+ return nil
+ end
+ if not ctype or not default then
+ err("unable to create callback '%s': "
+ .."callbacktype or default function not specified", name)
+ return nil
+ end
+ if callbacktypes[name] then
+ err("unable to create callback '%s', callback already exists", name)
+ return nil
+ end
+ local temp = str_to_type(ctype)
+ if not temp then
+ err("unable to create callback '%s', type '%s' undefined", name, ctype)
+ return nil
+ end
+ ctype = temp
+ lua_callbacks_defaults[name] = default
+ callbacktypes[name] = ctype
+end
+% \end{macrocode}
+%
+% This function calls a callback. It can only call a callback created by
+% the \texttt{create} function.
+%
+% \begin{macrocode}
+function call_callback(name, ...)
+ if not name then
+ err("unable to call callback, no proper name passed", name)
+ return nil
+ end
+ if not lua_callbacks_defaults[name] then
+ err("unable to call lua callback '%s', unknown callback", name)
+ return nil
+ end
+ local l = callbacklist[name]
+ local f
+ if not l then
+ f = lua_callbacks_defaults[name]
+ else
+ if callbacktypes[name] == list then
+ f = listhandler(name)
+ elseif callbacktypes[name] == data then
+ f = datahandler(name)
+ elseif callbacktypes[name] == simple then
+ f = simplehandler(name)
+ elseif callbacktypes[name] == first then
+ f = firsthandler(name)
+ else
+ err("unknown callback type")
+ end
+ end
+ return f(...)
+end
+% \end{macrocode}
+%
+% This function tells if a function has already been registered in a
+% callback, and gives its current priority. The arguments are the name of
+% the callback and the description of the function. If it has already been
+% registered, it gives its priority, and if not it returns false.
+%
+% \begin{macrocode}
+function priority_in_callback (name, description)
+ if not name or name == ""
+ or not callbacktypes[name]
+ or not description then
+ return 0
+ end
+ local l = callbacklist[name]
+ if not l then return 0 end
+ for p, f in pairs(l) do
+ if f.description == description then
+ return p
+ end
+ end
+ return 0
+end
+% \end{macrocode}
+%
+% Finally we
+% overwrite \texttt{callback.register} so that it outputs an error.
+%
+% \begin{macrocode}
+callback.register = function ()
+err("function callback.register has been deleted by luamcallbacks, "
+.."please use callback.add instead.")
+end
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \begin{macrocode}
+%</lua>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% A few basic tests for Plain and LaTeX.
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-mcb.sty
+%<testlatex>\RequirePackage{luatexbase-mcb}
+%<*testplain,testlatex>
+\catcode 64 11
+\luatexbase@directlua{
+ local function one(head,...)
+ texio.write_nl("I'm number 1")
+ return head, true
+ end
+
+ local function two(head,...)
+ texio.write_nl("I'm number 2")
+ return head, true
+ end
+
+ local function three(head,...)
+ texio.write_nl("I'm number 3")
+ return head, true
+ end
+
+ luatexbase.add_to_callback("hpack_filter",one,"my sample function one",1)
+ luatexbase.add_to_callback("hpack_filter",two,"my sample function two",2)
+ luatexbase.add_to_callback("hpack_filter",three,"my sample function three",1)
+
+ luatexbase.remove_from_callback("hpack_filter","my sample function three")
+}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx
new file mode 100644
index 00000000000..9c2936f4ce8
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx
@@ -0,0 +1,544 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-modutils.dtx
+% and the derived files
+% luatexbase-modutils.sty modutils.lua
+% test-modutils-plain.tex test-modutils-latex.tex test-modutils.lua
+%
+% Unpacking:
+% tex luatexbase-modutils.dtx
+% Documentation:
+% pdflatex luatexbase-modutils.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
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-modutils.sty}{\from{luatexbase-modutils.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-modutils-plain.tex}{\from{luatexbase-modutils.dtx}{testplain}}%
+ \file{test-modutils-latex.tex}{\from{luatexbase-modutils.dtx}{testlatex}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{modutils.lua}{\from{luatexbase-modutils.dtx}{luamodule}}%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-modutils.lua}{\from{luatexbase-modutils.dtx}{testdummy}}%
+}
+
+\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-modutils.sty modutils.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\input{lltxb-dtxstyle}
+\begin{document}
+ \DocInput{luatexbase-modutils.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-modutils} package}
+% \date{v0.2 2010-05-12}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This package provides functions similar to \latex's |\usepackage| and
+% |\ProvidesPackage| macros,\footnote{and their variants or synonyms such as
+% \cs{documentclass} and \cs{RequirePackage} or \cs{ProvidesClass} and
+% \cs{ProvidesFiles}} or more precisely the part of these macros that deals
+% with identification and version checking (no attempt is done at implementing
+% an option mechanism). Functions for error reporting are provided too.
+%
+% It also loads \pk{luatexbase-loader}.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% Lua's standard function |require()| is similar to \tex's |\input| primitive
+% but is somehow more evolved in that it makes a few checks to avoid loading
+% the same module twice. In the \tex world, this needs to be taken care of by
+% macro packages; in the \latex world this is done by |\usepackage|.
+%
+% But |\usepackage| also takes care of many other things. Most notably, it
+% implements a complex option system, and does some identification and version
+% checking. The present package doesn't try to provide anything for options,
+% but implements a system for identification and version checking similar to
+% \latex's system. Both \tex macros and Lua functions are provided.
+%
+% This package also provides Lua functions for reporting errors, warnings,
+% etc.
+%
+% It is important to notice that Lua's standard function |module()| is
+% completely unrelated to the present package. It has nothing to do with
+% identification and deals only with namespaces.\footnote{More precisely, it
+% modifies the current environment.} So, you should continue to
+% use it normally, unlike the |require()| function which can be replaced with
+% this package's |luatexbase.require_module()|.
+%
+% \subsection{\tex macros}
+%
+% The two macros |\luatexUseModule| and |\luatexRequireModule| are very
+% similar and are interfaces to the Lua functions |use_module| and
+% |require_module|. The only difference between those macros is the number of
+% arguments (just as the underlying Lua functions): |\luatexUseModule| only
+% take one argument: the module name\footnote{without extension} while
+% |\luatexRequireModule| takes another argument for specifying a minimal
+% version (see below). With \latex, this argument is the first and is
+% optional. Otherwise, it's the second one and it's mandatory.
+%
+% \subsection{Lua functions}
+%
+% The main functions are |luatexbase.require_module| and
+% |luatexbase.use_module| which may be used as a replacement to |require()|.
+% The only difference between these functions is, |require_module| accepts a
+% second, optional argument in order to specify a minimal version. They do the
+% same as |require()| but also make sure the module loaded correctly
+% identifies itself with the name given, and its version is greater than the
+% minimal version required. The version can be given either as a (floating
+% point) number or as a date in YYYY/MM/DD format.
+%
+% Modules identify themselves using |luatexbase.provides_module|, whose only
+% argument is a table with some information about the module. The mandatory
+% fields are |name| (a string), |version| (a number), |date| (a string) and
+% |description| (a string). Other fields are optional and ignored, and usually
+% include |copyright|, |author| and |license|.
+%
+% \bigskip
+%
+% Functions for reporting are provided; similarly to \latex's |\PackageError|
+% etc. they take the module name as their first argument and include it in the
+% printed message in an appropriate way. The remaining arguments are passed to
+% |string.format()| before being printed.
+%
+% The functions provided (all found in the |luatexbase| table) are
+% |module_error|, |module_warning|, |module_info| (writes to terminal and
+% log), |module_log| (writes only to the log file) and |module_term| (writes
+% only to the terminal).
+%
+% \section{Implementation}
+%
+% \subsection{\tex package}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsubsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@modutils@loaded\endcsname
+\expandafter\let\csname lltxb@modutils@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@modutils@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-modutils}[2010/05/12 v0.2 Module utilities 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-modutils}{LuaTeX is required for this package. Aborting.}
+ \lltxb@modutils@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% Load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}) and require
+% supporting Lua module.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input luatexbase-loader.sty
+\else
+ \RequirePackage{luatexbase-loader}
+\fi
+\luatexbase@directlua{require('luatexbase.modutils')}
+% \end{macrocode}
+%
+% Make sure the primitives we need are available.
+%
+% \begin{macrocode}
+\luatexbase@ensure@primitive{luaescapestring}
+% \end{macrocode}
+%
+% \subsubsection{User macros}
+%
+% Interface to |use_module()|.
+%
+% \begin{macrocode}
+\def\luatexUseModule#1{\luatexbase@directlua{%
+ luatexbase.use_module("\luatexluescapestring{#1}")}}
+% \end{macrocode}
+%
+% Interface to |require_module()| with syntax depending on the format.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname newcommand\endcsname\relax
+ \def\luatexRequireModule#1#2{%
+ \luatexbase@directlua{luatexbase.require_module(
+ "\luatexluaescapestring{#1}", "\luatexluaescapestring{#2}")}}
+\else
+ \newcommand\luatexRequireModule[2][0]{%
+ \luatexbase@directlua{luatexbase.require_module(
+ "\luatexluaescapestring{#2}", "\luatexluaescapestring{#1}")}}
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\lltxb@modutils@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \subsection{Lua module}
+%
+% \begin{macrocode}
+%<*luamodule>
+module("luatexbase", package.seeall)
+% \end{macrocode}
+%
+% \subsection{Internal functions and data}
+%
+% Tables holding informations about the modules loaded and the versions
+% required.
+%
+% \begin{macrocode}
+local modules = modules or {}
+local requiredversions = {}
+% \end{macrocode}
+%
+% Convert a date in YYYY/MM/DD format into a number
+%
+% \begin{macrocode}
+local function datetonumber(date)
+ numbers = string.gsub(date, "(%d+)/(%d+)/(%d+)", "%1%2%3")
+ return tonumber(numbers)
+end
+% \end{macrocode}
+%
+% Say if a string is a date in YYYY//MM/DD format.
+%
+% \begin{macrocode}
+local function isdate(date)
+ for _, _ in string.gmatch(date, "%d+/%d+/%d+") do
+ return true
+ end
+ return false
+end
+% \end{macrocode}
+%
+% Parse a version into a table indicating a type (date or number), a
+% numeric version and the original version string.
+%
+% \begin{macrocode}
+local date, number = 1, 2
+local function parse_version(version)
+ if isdate(version) then
+ return {type = date, version = datetonumber(version), orig = version}
+ else
+ return {type = number, version = tonumber(version), orig = version}
+ end
+end
+% \end{macrocode}
+%
+% \subsubsection{Error, warning and info function for modules}
+%
+% Here are the reporting functions for the modules. For errors, Lua's
+% |error()| is used. For now, the error reports look less good than with
+% \tex's |\errmessage|, but hopefully it will be improved in future
+% versions of \luatex. We could invoke |\errmessage| using |tex.sprint()|,
+% but it may cause problems on the \tex end, and moreover |error()| will
+% still be used by Lua for other errors, so it makes messages more
+% consistent.
+%
+% \begin{macrocode}
+local function module_error_int(mod, ...)
+ error('Module '..mod..' error: '..string.format(...), 3)
+end
+function module_error(mod, ...)
+ module_error_int(mod, ...)
+end
+function module_warning(mod, ...)
+ texio.write_nl("Module "..mod.." warning: "..string.format(...))
+end
+function module_info(mod, ...)
+ texio.write_nl(mod..": "..string.format(...))
+end
+function module_log(mod, ...)
+ texio.write_nl('log', mod..": "..string.format(...))
+end
+function module_term(mod, ...)
+ texio.write_nl('term', mod..": "..string.format(...))
+end
+% \end{macrocode}
+%
+% For our own convenience, local functions for warning and errors in the
+% present module.
+%
+% \begin{macrocode}
+local function err(...) module_error_int('luatexbase.modutils', ...) end
+local function warn(...) module_warning('luatexbase.modutils', ...) end
+% \end{macrocode}
+%
+% \subsubsection{module loading and providing functions}
+%
+% Load a module without version checking.
+%
+% \begin{macrocode}
+function use_module(name)
+ require(name)
+ if not modules[name] then
+ warn("Module didn't properly identified itself: %s", name)
+ end
+end
+% \end{macrocode}
+%
+% Load a module with optional version checking.
+%
+% \begin{macrocode}
+function require_module(name, version)
+ if not version then
+ return use_module(name)
+ end
+ luaversion = parse_version(version)
+ if modules[name] then
+ if luaversion.type == date then
+ if datetonumber(modules[name].date) < luaversion.version then
+ err("found module `%s' loaded in version %s, "
+ .."but version %s was required",
+ name, modules[name].date, version)
+ end
+ else
+ if modules[name].version < luaversion.version then
+ err("found module `%s' loaded in version %.02f, "
+ .."but version %s was required",
+ name, modules[name].version, version)
+ end
+ end
+ else
+ requiredversions[name] = luaversion
+ use_module(name)
+ end
+end
+% \end{macrocode}
+%
+% Provide identification information for a module.
+%
+% \begin{macrocode}
+function provides_module(mod)
+ if not mod then
+ err('cannot provide nil module')
+ return
+ end
+ if not mod.version or not mod.name or not mod.date
+ or not mod.description then
+ err("invalid module registered: "
+ .."fields name, version, date and description are mandatory")
+ return
+ end
+ requiredversion = requiredversions[mod.name]
+ if requiredversion then
+ if requiredversion.type == date
+ and requiredversion.version > datetonumber(mod.date) then
+ err("loading module %s in version %s, "
+ .."but version %s was required",
+ mod.name, mod.date, requiredversion.orig)
+ elseif requiredversion.type == number
+ and requiredversion.version > mod.version then
+ err("loading module %s in version %.02f, "
+ .."but version %s was required",
+ mod.name, mod.version, requiredversion.orig)
+ end
+ end
+ modules[mod.name] = module
+ texio.write_nl('log', string.format("Lua module: %s %s v%.02f %s\n",
+ mod.name, mod.date, mod.version, mod.description))
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</luamodule>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% A dummy lua file for tests.
+%
+% \begin{macrocode}
+%<*testdummy>
+luatexbase.provides_module {
+ name = 'test-modutils',
+ date = '2000/01/01',
+ version = 1,
+ description = 'dummy test package',
+}
+%</testdummy>
+% \end{macrocode}
+%
+% We just check that the package loads properly, under both LaTeX and Plain
+% TeX. Anyway, the test files of other modules using this one already are a
+% test\dots
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-modutils.sty
+%<testlatex>\RequirePackage{luatexbase-modutils}
+%<*testplain,testlatex>
+\luatexRequireModule
+%<testlatex>[1970/01/01]
+{test-modutils}
+%<testplain>{1970/01/01}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx
new file mode 100644
index 00000000000..313af007c97
--- /dev/null
+++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx
@@ -0,0 +1,485 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-regs.dtx
+% and the derived files
+% luatexbase-regs.pdf luatexbase-regs.sty
+% test-regs-plain.tex test-regs-latex.tex
+%
+% Unpacking:
+% tex luatexbase-regs.dtx
+% Documentation:
+% pdflatex luatexbase-regs.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 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-regs.sty}{\from{luatexbase-regs.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-regs-plain.tex}{\from{luatexbase-regs.dtx}{testplain}}%
+ \file{test-regs-latex.tex}{\from{luatexbase-regs.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-regs.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-regs.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-regs} package}
+% \date{v0.2 2010/05/12}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This package extends the register allocation scheme of \plaintex and
+% \latex to take advantage of the increased number of registers available in
+% \luatex.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% Since the \plaintex and \latex formats are both frozen, they fail to take
+% into account the extended resources provided by newer \tex-like engines.
+% This package focuses on the allocation scheme for registers. \texe provides
+% $6$ kinds or registers: count, dimen, skip, muskip, box and toks and has
+% $256$ registers of each kind. \eTeX\ and most of its descendants add one
+% kind of register (marks) and offers $2^{15} = 32768$ of each kind. \luatex
+% provides $2^{16} = 65536$ registers of each kind. (It also provides new
+% register-like resources, but this package addresses only the resources
+% inherited from \eTeX.)
+%
+% More precisely, \pk{luatexbase-regs} loads the \pk{etex} package (or
+% makes sure it is preloaded in the format) and then adapts it to the new
+% limits of \luatex. Thus, all macros defined by the \pk{etex} package are
+% made available (most notably, |\loccount|, |\globcountblk|,
+% |\loccountblk| and alike). However, if a register of some kind has been
+% locally allocated before this package is loaded, then the number of
+% allocatable registers of this kind will not be extended to $65536$. To avoid
+% this, load \pk{luatexbase-regs} earlier.
+%
+% The \plaintex and \latex formats define a new kind of resource:
+% \emph{inserts} which are merely a family (count, dimen, skip, box) of
+% registers with the same number. Inserts allocation begins at $255$ and goes
+% toward $0$. Thus we can make room for more inserts by making allocation of
+% count-, dimen-, skip- and box-registers start from $256$. With real \etex,
+% it may be a bad idea since registers with index greater than $256$ have
+% degraded performance due to implementation details, but with \luatex the
+% performance is uniform, so we just do it.
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@regs@loaded\endcsname
+\expandafter\let\csname lltxb@regs@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@regs@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-regs}[2010/05/12 v0.2 Registers allocation 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-regs}{LuaTeX is required for this package. Aborting.}
+ \lltxb@regs@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsection{Ensure etex.sty is loaded}
+%
+% If running \latex, load \file{etex.sty}. If not, either
+% \file{etex.src} was loaded at format generation time, or we cannot do
+% anything.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax \else
+ \RequirePackage{etex}[1998/03/26]
+\fi
+% \end{macrocode}
+%
+% To the best of my (mpg) knowledge, all Plain-based formats built with
+% \etex-enabled engines in \texlive load \file{etex.src}. However,
+% let's be careful and check that \file{etex.sty} or \file{etex.src} is
+% loaded.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname et@xins\endcsname\relax
+ \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-regs}{etex macros not loaded!^^J
+ Registers allocation scheme will not be extended.}
+\else
+% \end{macrocode}
+%
+% \subsection{Adapt range}
+%
+% First, increase the upper bound for all kinds of registers. Copy code to
+% avoid defining a macro.
+%
+% \begin{macrocode}
+ \ifnum\count270=32768 \count270=65536 \fi
+ \ifnum\count271=32768 \count271=65536 \fi
+ \ifnum\count272=32768 \count272=65536 \fi
+ \ifnum\count273=32768 \count272=65536 \fi
+ \ifnum\count273=32768 \count273=65536 \fi
+ \ifnum\count274=32768 \count274=65536 \fi
+ \ifnum\count275=32768 \count275=65536 \fi
+ \ifnum\count276=32768 \count276=65536 \fi
+% \end{macrocode}
+%
+% \subsection{Patch macros that used \cs{mathchardef}}
+%
+% |\box| registers and |\mark|s were previously defined
+% using |\mathchardef| since it had the biggest range under \etex
+% (15-bit number). However, this is not enough for \luatex's extended
+% registers. Fortunately, |\chardef|'s range is extended, and now large
+% enough, so use it everywhere instead of |\mathchardef|. Do this
+% inside a group and use |\toks0| to store the list of actions.
+%
+% \begin{macrocode}
+ \begingroup \toks0{}
+ \def\@namedef #1{\expandafter \def\csname#1\endcsname}
+ \def\@outerdef#1{\expandafter\outer\expandafter\def\csname#1\endcsname}
+% \end{macrocode}
+%
+% Notice that the auxiliary macros will automatically expand to the desired
+% level when necessary, see below.
+%
+% First, here are the definitions from \file{etex.src}, in a form adapted
+% to our needs.
+%
+% \begin{macrocode}
+ \def\def@globbox #1#2{\@outerdef{#1}{\et@xglob 4 \box #2}}
+ \def\def@locbox #1#2{\@namedef {#1}{\et@xloc 4 \box #2}}
+ \def\def@globmarks #1#2{\@outerdef{#1}{\et@xglob 6 \marks #2}}
+ \def\def@locmarks #1#2{\@namedef {#1}{\et@xloc 6 \marks #2}}
+ \def\def@et@xgblk#1#2{\@namedef{#1}##1##2##3##4%
+ {\et@xchkblk ##1##2{##4}%
+ {\allocationnumber=\count 26##1
+ \global \advance \count 26##1 by ##4%
+ \global #2##3=\allocationnumber
+ \wlog {\string ##3=\string ##2blk{\number ##4}
+ at \the \allocationnumber}%
+ }%
+ }}
+ \def\def@et@xlblk#1#2{\@namedef{#1}##1##2##3##4%
+ {\et@xchkblk ##1##2{##4}%
+ {\advance \count 27##1 by -##4%
+ \allocationnumber=\count 27##1
+ #2##3=\allocationnumber
+ \wlog {\string ##3=\string ##2blk{\number ##4}
+ at \the \allocationnumber \space (local)%
+ }%
+ }%
+ }}
+% \end{macrocode}
+%
+% Then, the definitions from \file{etex.sty} since they are subtly
+% different (|\outer| status, but also optional spaces or |=|
+% signs).
+%
+% \begin{macrocode}
+ \def\alt@globbox #1#2{\@namedef{#1}{\et@xglob 4\box #2}}
+ \def\alt@locbox #1#2{\@namedef{#1}{\et@xloc 4\box #2}}
+ \def\alt@globmarks #1#2{\@namedef{#1}{\et@xglob 6\marks #2}}
+ \def\alt@locmarks #1#2{\@namedef{#1}{\et@xloc 6\marks #2}}
+ \def\alt@et@xgblk#1#2{\@namedef{#1}##1##2##3##4%
+ {\et@xchkblk##1##2{##4}%
+ {\allocationnumber\count26##1%
+ \global\advance\count26##1by##4%
+ \global#2##3\allocationnumber
+ \wlog{\string##3=\string##2blk{\number##4} at
+ \the\allocationnumber}%
+ }%
+ }}
+ \def\alt@et@xlblk#1#2{\@namedef{#1}##1##2##3##4%
+ {\et@xchkblk##1##2{##4}%
+ {\advance\count27##1-##4%
+ \allocationnumber\count27##1%
+ #2##3\allocationnumber
+ \et@xwlog{\string##3=\string##2blk{\number##4} at
+ \the\allocationnumber\space(local)}%
+ }%
+ }}
+% \end{macrocode}
+%
+% Now, a macro checking the definitions, and making the appropriate
+% re-definition.
+%
+% \begin{macrocode}
+ \def\check@def#1{%
+ \csname def@#1\endcsname{test@#1}\mathchardef
+ \expandafter\ifx\csname test@#1\expandafter\endcsname
+ \csname #1\endcsname
+ \expandafter\let\csname #1\endcsname\relax
+ \toks0\expandafter{\the\toks0\csname def@#1\endcsname{#1}\chardef}
+ \else
+ \csname alt@#1\endcsname{test@#1}\mathchardef
+ \expandafter\ifx\csname test@#1\expandafter\endcsname
+ \csname #1\endcsname
+ \toks0\expandafter{\the\toks0\csname alt@#1\endcsname{#1}\chardef}
+ \else
+ \expandafter\show\csname BAD#1\endcsname
+ \fi
+ \fi}
+% \end{macrocode}
+%
+% Now, actually do it.
+%
+% \begin{macrocode}
+ \check@def{globbox}
+ \check@def{locbox}
+ \check@def{globmarks}
+ \check@def{locmarks}
+ \check@def{et@xgblk}
+ \check@def{et@xlblk}
+ \expandafter \endgroup
+ \the\toks0
+% \end{macrocode}
+%
+% \subsection{Make room for inserts}
+%
+% Finally, make allocation of |\count|, |\dimen|, |skip| and
+% |\box| start with numbers $>255$, in order to free the lower numbers
+% for insertions. Be careful with |\new...| macros which are
+% |\outer| in Plain, since we're in the middle of an |\if| test.
+%
+% \begin{macrocode}
+ \expandafter\let\csname newcount\endcsname\globcount
+ \expandafter\let\csname newdimen\endcsname\globdimen
+ \expandafter\let\csname newskip\endcsname\globskip
+ \expandafter\let\csname newbox\endcsname\globbox
+\fi
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \begin{macrocode}
+\lltxb@regs@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% Here we test only the two main formats: \plaintex (with \file{etex.src}
+% loaded) and \latex, both with the \luatex engine. Those correspond to
+% the \cmdname{luatex} and \cmdname{lualatex} commands in \texlive.
+%
+% We want to make sure we can globally and locally allocate $30000$
+% registers of each kind, and still globally allocate $100$ |\insert|s.
+% Next we globally allocate a bloc of $3000$ registers of each kind, and
+% locally a block of $1000$. (Those numbers are not optimal, but they
+% should be enough for testing purposes.)
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-regs.sty
+%<testlatex>\RequirePackage{luatexbase-regs}
+%<*testplain,testlatex>
+\def\checkregister#1{%
+ \edef\newregister{\expandafter\noexpand\csname new#1\endcsname}%
+ \edef\locregister{\expandafter\noexpand\csname loc#1\endcsname}%
+ \count0 1
+ \loop
+ \newregister\dummy
+ \locregister\dummy
+ \ifnum\count0<30000
+ \advance\count0 1
+ \repeat}
+\checkregister{count}
+\checkregister{dimen}
+\checkregister{skip}
+\checkregister{muskip}
+\checkregister{box}
+\checkregister{toks}
+\checkregister{marks}
+
+\count0 1
+\loop \ifnum\count0<100
+ \csname newinsert\endcsname\dummy
+ \advance\count0 1
+\repeat
+
+\globcountblk \dummy{3000}
+\globdimenblk \dummy{3000}
+\globskipblk \dummy{3000}
+\globmuskipblk\dummy{3000}
+\globboxblk \dummy{3000}
+\globtoksblk \dummy{3000}
+\globmarksblk \dummy{3000}
+
+\loccountblk \dummy{1000}
+\locdimenblk \dummy{1000}
+\locskipblk \dummy{1000}
+\locmuskipblk \dummy{1000}
+\locboxblk \dummy{1000}
+\loctoksblk \dummy{1000}
+\locmarksblk \dummy{1000}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput