diff options
author | Karl Berry <karl@freefriends.org> | 2010-11-18 00:35:41 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-11-18 00:35:41 +0000 |
commit | 75a9ad6b597ca31c07f38850761832951b0f6224 (patch) | |
tree | d09aa23cca95f7ea69dfbd5f2683ec1869f9d0aa /Master/texmf-dist/source/luatex/luatexbase | |
parent | e1353b47437cbc7c93c601670ce39cc2bfede42d (diff) |
luatexbase (17nov10)
git-svn-id: svn://tug.org/texlive/trunk@20476 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/luatex/luatexbase')
9 files changed, 1015 insertions, 652 deletions
diff --git a/Master/texmf-dist/source/luatex/luatexbase/Makefile b/Master/texmf-dist/source/luatex/luatexbase/Makefile index 0b854b07500..03784a546cd 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/Makefile +++ b/Master/texmf-dist/source/luatex/luatexbase/Makefile @@ -7,20 +7,21 @@ DTXSTY = lltxb-dtxstyle.tex # Files grouped by generation mode UNPACKED_MCB = luatexbase-mcb.sty mcb.lua \ - test-mcb-latex.tex test-mcb-plain.tex + test-mcb-latex.tex test-mcb-plain.tex \ + test-mcb.lua $(TEST_MCB) UNPACKED_REGS = luatexbase-regs.sty \ - test-regs-plain.tex test-regs-latex.tex + test-regs-plain.tex test-regs-latex.tex UNPACKED_ATTR = luatexbase-attr.sty attr.lua \ - test-attr-plain.tex test-attr-latex.tex + test-attr-plain.tex test-attr-latex.tex UNPACKED_CCTB = luatexbase-cctb.sty cctb.lua \ - test-cctb-plain.tex test-cctb-latex.tex + 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 + 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 + test-modutils-plain.tex test-modutils-latex.tex UNPACKED_COMPAT = luatexbase-compat.sty \ - test-compat-plain.tex test-compat-latex.tex + test-compat-plain.tex test-compat-latex.tex UNPACKED_BASE = luatexbase.sty test-base-plain.tex test-base-latex.tex UNPACKED = $(UNPACKED_MCB) $(UNPACKED_REGS) $(UNPACKED_ATTR) $(UNPACKED_CCTB) \ $(UNPACKED_LOADER) $(UNPACKED_MODUTILS) $(UNPACKED_COMPAT) \ @@ -32,6 +33,7 @@ SOURCE = $(DTX) $(DTXSTY) README TODO Changes Makefile # used for check TEST_LOADER = test-loader TMP_LOADER = $(TEST_LOADER).tex +TEST_MCB = test-mcb-aux.tex # Files grouped by installation location RUNFILES = $(filter-out test-%, $(UNPACKED)) @@ -60,7 +62,7 @@ TDS_ZIP = $(NAME).tds.zip ZIPS = $(CTAN_ZIP) $(TDS_ZIP) DO_TEX = tex --interaction=batchmode $< >/dev/null -DO_LATEXMK = latexmk -silent $< >/dev/null +DO_LATEXMK = latexmk -pdf -silent $< >/dev/null # Main targets definition all: $(GENERATED) @@ -80,6 +82,7 @@ luatexbase.%.lua: %.lua $(UNPACKED_MCB): luatexbase-mcb.dtx $(DO_TEX) + echo \\\\relax > $(TEST_MCB) $(UNPACKED_REGS): luatexbase-regs.dtx $(DO_TEX) @@ -123,7 +126,7 @@ 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 +check-mcb: install-runfiles $(UNPACKED_MCB) $(TESTENV) luatex --interaction=batchmode test-mcb-plain.tex >/dev/null $(TESTENV) lualatex --interaction=batchmode test-mcb-latex.tex >/dev/null @@ -170,7 +173,7 @@ manifest: clean: @latexmk -silent -c *.dtx >/dev/null - @# for tex-only runs + @#for non-latexmk runs @$(RM) -- *.log mrproper: clean diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx index 5847daec422..d377f7c619f 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-attr.dtx @@ -113,11 +113,7 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase-attr} package} -% \date{v0.2a 2010-05-27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and -% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-attr}{v0.3 2010-05-27} % % \maketitle % @@ -238,7 +234,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-attr}[2010/05/27 v0.2a Attributes allocation for LuaTeX] +\x{luatexbase-attr}[2010/10/10 v0.3 Attributes allocation for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -252,14 +248,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@attr@AtEnd \expandafter\endinput \fi diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx index 4b7b8c64231..c60cdc0c709 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-cctb.dtx @@ -113,11 +113,7 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase-cctb} package} -% \date{v0.2a 2010-05-27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \texttt{mpg@elzevir.fr} \and -% \'Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-cctb}{v0.3 2010-05-27} % % \maketitle % @@ -246,7 +242,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-cctb}[2010/05/27 v0.2a Catcodetable allocation for LuaTeX] +\x{luatexbase-cctb}[2010/10/10 v0.3 Catcodetable allocation for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -260,14 +256,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-cctb}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@cctb@AtEnd \expandafter\endinput \fi @@ -505,6 +504,7 @@ end % Plain TeX. % % \begin{macrocode} +%<testplain,testlatex>\catcode00 15 %<testplain>\input luatexbase-cctb.sty %<testlatex>\RequirePackage{luatexbase-cctb} %<*testplain,testlatex> @@ -524,13 +524,29 @@ end \lua{assert(luatexbase.catcodetables.anothercctb)} % \end{macrocode} % -% Now, play a little bit with predefined tables. +% Now, play a little bit with predefined tables. Be careful to change +% catcodes only inside a group to avoid chaos. % % \begin{macrocode} -\luatexcatcodetable\CatcodeTableLaTeXAtLetter -\ifnum\catcode64=11 \else \ERROR \fi -\luatexcatcodetable\CatcodeTableLaTeX -\ifnum\catcode64=12 \else \ERROR \fi +\def\test#1#2#3{% + \begingroup + \ifcsname CatcodeTable#1\endcsname \else \INTERR \fi + \luatexcatcodetable\csname CatcodeTable#1\endcsname + \ifnum\catcode#2=#3 \else \ERROR \fi + \endgroup} +\test {IniTeX} {00} {09} +\test {IniTeX} {92} {00} +\test {IniTeX} {64} {12} +\test {IniTeX} {65} {11} +\test {String} {92} {12} +\test {String} {65} {12} +\test {String} {32} {10} +\test {Other} {92} {12} +\test {Other} {65} {12} +\test {Other} {32} {12} +\test {LaTeXAtLetter} {64} {11} +\test {LaTeX} {64} {12} +\test {Expl} {32} {09} %<testlatex>\documentclass{minimal} \lua{% tex.sprint('\string\\setbox0=\string\\hbox{') diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx index f4a903b74be..e7d29b2b107 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-compat.dtx @@ -102,11 +102,7 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase-compat} package} -% \date{v0.2a 2010/05/27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and -% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-compat}{2010/10/10 v0.3} % % \maketitle % @@ -258,7 +254,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-compat}[2010/05/27 v0.2a Compatibility tools for LuaTeX] +\x{luatexbase-compat}[2010/10/10 v0.3 Compatibility tools for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -272,14 +268,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-compat}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@compat@AtEnd \expandafter\endinput \fi diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx index bd900c26969..9d57ac57c86 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-loader.dtx @@ -116,11 +116,7 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase-loader} package} -% \date{v0.2a 2010-05-27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \texttt{mpg@elzevir.fr} \and -% \'Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-loader}{v0.3 2010-05-27} % % \maketitle % @@ -230,7 +226,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-loader}[2010/05/27 v0.2a Lua module loader for LuaTeX] +\x{luatexbase-loader}[2010/10/10 v0.3 Lua module loader for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -244,14 +240,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-loader}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@loader@AtEnd \expandafter\endinput \fi diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx index 09c8c1c53dd..b944cd261e4 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-mcb.dtx @@ -69,6 +69,11 @@ See source file '\inFileName' for details. \file{mcb.lua}{\from{luatexbase-mcb.dtx}{lua}}% } +\generate{% + \usedir{doc/luatex/luatexbase}% + \file{test-mcb.lua}{\from{luatexbase-mcb.dtx}{testlua}}% +} + \obeyspaces \Msg{************************************************************************} \Msg{*} @@ -113,73 +118,163 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \textsf{luatexbase-mcb} package} -% \date{2010/05/27 v0.2a} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and -% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-mcb}{2010/10/10 v0.3} % % \maketitle % % \begin{abstract} -% This package manages the callback adding and removing, by providing new -% functions and overwriting \texttt{callback.register}. It also allows to -% create and call new callbacks.\par -% The user part of this documentation is currently very incomplete, and will -% be expanded later. Sorry for this and thanks for your patience.\par -% \textbf{Warning.} Currently assumes that \textsf{luatexbase-modutils} -% has been previously loaded. (This is a temporary limitation.) +% The primary feature of this package is to allow many functions to be +% registered in the same callback. Depending of the type of the callback, the +% functions will be combined in some way when the callback is called. Functions +% are provided for addition and removal of individual functions from a +% callback's list, with a priority system.\par +% Additionally, you can create new callbacks that will be handled the same way +% as predefined callbacks, except that they must be called explicitly. % \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 +% Before we start, let me mention that test files are provided (they should be +% in the same directory as this PDF file). You can have a look at them, +% compile them and have a look at the log, if you want examples of how this +% module works. +% +% \subsection{Managing functions in callbacks} +% +% \luatex 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 +% The \luatex 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 -% \verb+luatexbase.add_to_callback+ 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. There are -% also functions to remove one or all functions from a callback. -% See comments in the implementation section for details. -% -% 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. -% See comments in the implementation section for details. -% -% This package also privides a way to create and call new callbacks, in -% addition to the default Lua\TeX\ callbacks. -% See comments in the implementation section for details. -% -% \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}. +% The problem with |callback.register| is that is registers only one function +% in a callback. This package solves the problem by disabling +% |callback.register| and providing a new interface allowing many functions to +% be registered in a single callback. +% +% The way the functions are combined together depends on +% the type of the callback. There are currently 4 types of callback, depending +% on the calling convention of the functions the callback can hold: +% \begin{description} +% \item[simple] is for functions that don't return anything: they are called +% in order, all with the same argument; +% \item[data] is for functions receiving a piece of data of nay type +% except node list head (and possibly other arguments) and returning it +% (possibly modified): the functions are called in order, and each is +% passed the return value of the previous (and the other arguments +% untouched, if any). The return value is that of the last function; +% \item[list] is a specialized variant of \emph{data} for functions +% filtering node lists. Such functions may return either the head of a +% modified node list, or the boolean values |true| or |false|. The +% functions are chained the same way as for \emph{data} except that for +% the following. If +% one function returns |false|, then |false| is immediately return and the +% following functions are \emph{not} called. If one function returns +% |true|, then the same head is passed to the next function. If all +% functions return |true|, then |true| is returned, otherwise the return +% value of the last function not returning |true| is used. +% \item[first] is for functions with more complex signatures; functions in +% this type of callback are \emph{not} combined: only the first one +% (according to priorities) is executed. +% \end{description} +% +% To add a function to a callback, use: +% \begin{verbatim} +% luatexbase.add_to_callback(name, func, description, priority) +% \end{verbatim} +% The first argument is the name of the callback, the second is a function, +% the third one is a string used to identify the function later, and the +% optional priority is a positive integer, representing the rank of the +% function in the list of functions to be executing for this callback. So, +% |1| is the highest priority. If no priority is specified, the function is +% appended to the list, that is, its priority is the one of the last function +% plus one. +% +% The priority system is intended to help resolving conflicts between packages +% competing on the same callback, but it cannot solve every possible issue. If +% two packages request priority |1| on the same callback, then the last one +% loaded will win. +% +% To remove a function from a callback, use: +% \begin{verbatim} +% luatexbase.remove_from_callback(name, description) +% \end{verbatim} +% The first argument must be the name of the callback, and the second one the +% description used when adding the function to this callback. You can also +% remove all functions from a callback at once using +% \begin{verbatim} +% luatexbase.reset_callback(name, make_false) +% \end{verbatim} +% The |make_false| argument is optional. If it is |true| (repeat: |true|, not +% |false|) then the value |false| is registered in the callback, which has a +% special meaning for some callback. +% +% Note that |reset_callback| is very invasive since it removes all functions +% possibly installed by other packages in this callback. So, use it with care +% if there is any chance that another package wants to share this callback +% with you. +% +% When new functions are added at the beginning of the list, other functions +% are shifted down the list. To get the current rank of a function in a +% callback's list, use: +% \begin{verbatim} +% priority = luatexbase.priority_in_callback(name, description) +% \end{verbatim} +% Again, the description is the string used when adding the function. If the +% function identified by this string is not in this callback's list, the +% priority returned is the boolean value |false|. +% +% \subsection{Creating new callbacks} +% +% This package also provides a way to create and call new callbacks, in +% addition to the default \luatex callbacks. +% \begin{verbatim} +% luatexbase.create_callback(name, type, default) +% \end{verbatim} +% The first argument is the callback's name, it must be unique. Then, the type +% goes as explained above, it is given as a string. Finally all user-defined +% callbacks have a default function which must\footnote{You can obviously +% provide a dummy function. If you're doing so often, please tell me, I may +% want to make this argument optional.} be provided as the third +% argument. It will be used when no other function is registered for this +% callback. +% +% Functions are added to and removed from user-defined callbacks just the same +% way as predefined callback, so the previous section still applies. There is +% one difference, however: user-defined callbacks must be called explicitly at +% some point in your code, while predefined callbacks are called automatically +% by \luatex. To do so, use: +% \begin{verbatim} +% luatexbase.call_callback(name, arguments...) +% \end{verbatim} +% The functions registered for this callback (or the default function) will be +% called with |arguments...| as arguments. +% +% \subsubsection{Limitations} +% +% For callbacks of type |first|, our new management system isn't actually +% better than good old |callback.register|. For some of them, is may be +% possible to split them into many callbacks, so that these callbacks can +% accept multiple functions. However, its seems risky and limited in use and +% is therefore nor implemented. +% +% At some point, \pk{luatextra} used to split |open_read_file| that way, but +% support for this was removed. It may be added back (as well as support for +% other split callbacks) if it appears there is an actual need for it. +% +% \subsection{Compatibility} +% +% Some callbacks have a calling convention that varies depending on the +% version of \luatex used. This package \emph{does not} try to track the type +% of the callbacks in every possible version of \luatex. The types are based +% on the last stable beta version (0.60.2 at the time this doc is written). +% +% However, for callbacks that have the same calling convention for every +% version of \luatex, this package should work with the same range of \luatex +% version as other packages in the \pk{luatexbase} bundle (currently, 0.25.4 +% to 0.60.2). % % \section{Implementation} % @@ -245,7 +340,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-mcb}[2010/05/27 v0.2a Callback management for LuaTeX] +\x{luatexbase-mcb}[2010/10/10 v0.3 Callback management for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -259,14 +354,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-mcb}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@mcb@AtEnd \expandafter\endinput \fi @@ -304,309 +402,280 @@ See source file '\inFileName' for details. % % \begin{macrocode} module('luatexbase', package.seeall) -luatexbase.provides_module({ - name = "luamcallbacks", +local err, warning, info = luatexbase.provides_module({ + name = "luatexbase-mcb", 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", + author = "Hans Hagen, Elie Roux and Manuel Pegourie-Gonnard", + copyright = "Hans Hagen, Elie Roux and Manuel Pegourie-Gonnard", license = "CC0", }) % \end{macrocode} % -% Shortcuts for error functions. +% \subsubsection{Housekeeping} +% +% The main table: keys are callback names, and values are the associated +% lists of functions. More precisely, the entries in the list are tables +% holding the actual function as |func| and the identifying description as +% |description|. Only callbacks with a non-empty list of functions have an +% entry in this list. % % \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 +local callbacklist = callbacklist or { } % \end{macrocode} % -% \subsubsection{Initialisations} +% Numerical codes for callback types, and name to value association (the +% table keys are strings, the values are numbers). % -% \texttt{callbacklist} is the main list, that contains the callbacks as -% keys and a table of the registered functions a values. +% \begin{macrocode} +local list, data, first, simple = 1, 2, 3, 4 +local types = { + list = list, + data = data, + first = first, + simple = simple, +} +% \end{macrocode} +% +% Now, list all predefined callbacks with their current type, based on the +% LuaTeX manual version 0.60.2. % % \begin{macrocode} -local callbacklist = callbacklist or { } +local callbacktypes = callbacktypes or { % \end{macrocode} % -% A table with the default functions of the created callbacks. See -% \texttt{create} for further informations. +% Section 4.1.1: file discovery callbacks. % % \begin{macrocode} -local lua_callbacks_defaults = { } + find_read_file = first, + find_write_file = first, + find_font_file = data, + find_output_file = data, + find_format_file = data, + find_vf_file = data, + find_ocp_file = data, + find_map_file = data, + find_enc_file = data, + find_sfd_file = data, + find_pk_file = data, + find_data_file = data, + find_opentype_file = data, + find_truetype_file = data, + find_type1_file = data, + find_image_file = data, % \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} +% Section 4.1.2: file reading callbacks. % % \begin{macrocode} -local list = 1 -local data = 2 -local first = 3 -local simple = 4 + open_read_file = first, + read_font_file = first, + read_vf_file = first, + read_ocp_file = first, + read_map_file = first, + read_enc_file = first, + read_sfd_file = first, + read_pk_file = first, + read_data_file = first, + read_truetype_file = first, + read_type1_file = first, + read_opentype_file = first, % \end{macrocode} % -% \texttt{callbacktypes} is the list that contains the callbacks as keys -% and the type (list or data) as values. +% Section 4.1.3: data processing callbacks. % % \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, -} + process_input_buffer = data, + process_output_buffer = data, + token_filter = 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. +% Section 4.1.4: node list processiong callbacks. % % \begin{macrocode} -if luatexbase.luatexversion > 42 then - callbacktypes["process_output_buffer"] = data -end + buildpage_filter = simple, + pre_linebreak_filter = list, + linebreak_filter = list, + post_linebreak_filter = list, + hpack_filter = list, + vpack_filter = list, + pre_output_filter = list, + hyphenate = simple, + ligaturing = simple, + kerning = simple, + mlist_to_hlist = list, % \end{macrocode} % -% As we overwrite \texttt{callback.register}, we save it as -% \texttt{internalregister}. +% Section 4.1.5: information reporting callbacks. % % \begin{macrocode} -local internalregister = internalregister or callback.register + start_run = simple, + stop_run = simple, + start_page_number = simple, + stop_page_number = simple, + show_error_hook = simple, % \end{macrocode} % -% \subsubsection{Unsorted stuff} +% Section 4.1.6: font-related callbacks. % -% 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} + define_font = first, +} +% \end{macrocode} +% +% All user-defined callbacks have a default function. The following table's +% keys are the names of the user-defined callback, the associated value is +% the default functon for this callback. This table is also used to +% identify the user-defined callbacks. % % \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 +local lua_callbacks_defaults = { } +% \end{macrocode} +% +% Overwrite |callback.register|, but save it first. Also define a wrapper +% that automatically raise an error when something goes wrong. +% +% \begin{macrocode} +local original_register = original_register or callback.register +callback.register = function () + err("function callback.register has been trapped,\n" + .."please use luatexbase.add_to_callback instead.") +end +local function register_callback(...) + return assert(original_register(...)) 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. +% \subsubsection{Handlers} +% +% Normal (as opposed to user-defined) callbacks have handlers depending on +% their type. The handler function is registered into the callback when the +% first function is added to this callback's list. Then, when the callback +% is called, then handler takes care of running all functions in the list. +% When the last function is removed from the callback's list, the handler +% is unregistered. +% +% More precisely, the functions below are used to generate a specialized +% function (closure) for a given callback, which is the actual handler. +% +% Handler for |list| callbacks. % % \begin{macrocode} --- local -function listhandler (name) +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 + local ret + local alltrue = true + for _, f in ipairs(callbacklist[name]) do + ret = f.func(head, ...) + if ret == false then + warn("function '%s' returned false\nin callback '%s'", + f.description, name) + break + end + if ret ~= true then + alltrue = false + head = ret end - return head, done - else - return head, false end + return alltrue and true or head end end % \end{macrocode} % -% The handler for callbacks taking datas and returning modified ones. +% Handler for |data| callbacks. % % \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 + return function(data, ...) + for _, f in ipairs(callbacklist[name]) do + data = f.func(data, ...) 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. +% Handler for |first| callbacks. We can assume |callbacklist[name]| is not +% empty: otherwise, the function wouldn't be registered in the callback any +% more. % % \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 + return callbacklist[name][1].func(...) end end % \end{macrocode} % -% Handler for simple functions that don't return anything. +% Handler for |simple| callbacks. % % \begin{macrocode} local function simplehandler (name) return function(...) - local l = callbacklist[name] - if l then - for _, f in ipairs(l) do - f.func(...) - end + for _, f in ipairs(callbacklist[name]) do + f.func(...) end end end % \end{macrocode} % -% \subsubsection{Public functions} +% Finally, keep a handlers table for indexed access. % -% 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. +% \begin{macrocode} +local handlers = { + [list] = listhandler, + [data] = datahandler, + [first] = firsthandler, + [simple] = simplehandler, +} +% \end{macrocode} % -% 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. +% \subsubsection{Public functions for functions management} % -% 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. +% Add a function to a callback. First check arguments. % % \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 + return err("unable to add function:\nno proper function passed") end if not name or name == "" then - err("unable to add function, no proper callback name passed") + err("unable to add function:\nno proper callback name passed") return elseif not callbacktypes[name] then - err("unable to add function, '%s' is not a valid callback", name) + err("unable to add function:\n'%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", + err("unable to add function to '%s':\nno proper description passed", name) return end - if priority_in_callback(name, description) ~= 0 then - warning("function '%s' already registered in callback '%s'", + if priority_in_callback(name, description) then + err("function '%s' already registered\nin callback '%s'", description, name) + return end +% \end{macrocode} +% +% Then test if this callback is already in use. If not, initialise its list +% and register the proper handler. +% +% \begin{macrocode} 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 + register_callback(name, handlers[callbacktypes[name]](name)) end end +% \end{macrocode} +% +% Actually register the function. +% +% \begin{macrocode} local f = { func = func, description = description, @@ -617,33 +686,35 @@ function add_to_callback (name,func,description,priority) 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'", +% \end{macrocode} +% +% Keep user informed. +% +% \begin{macrocode} + if callbacktypes[name] == first and #l ~= 1 then + warning("several functions in '%s',\n" + .."only one will be active.", name) + end + info("inserting '%s'\nat position %s in '%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}. +% Remove a function from a callback. First check arguments. % % \begin{macrocode} function remove_from_callback (name, description) if not name or name == "" then - err("unable to remove function, no proper callback name passed") + err("unable to remove function:\nno proper callback name passed") return elseif not callbacktypes[name] then - err("unable to remove function, '%s' is not a valid callback", name) + err("unable to remove function:\n'%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", + "unable to remove function from '%s':\nno proper description passed", name) return end @@ -652,45 +723,84 @@ function remove_from_callback (name, description) err("no callback list for '%s'",name) return end +% \end{macrocode} +% +% Then loop over the callback's function list until we find a matching +% entry. Remove it and check if the list gets empty: if so, unregister the +% callback handler unless the callback is user-defined. +% +% \begin{macrocode} + local index = false 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 + index = k + break + end + end + if not index then + err("unable to remove '%s'\nfrom '%s'", description, name) + return + end + table.remove(l, index) + info("removing '%s'\nfrom '%s'", description, name) + if table.maxn(l) == 0 then + callbacklist[name] = nil + if not lua_callbacks_defaults[name] then + register_callback(name, nil) end end - warning("unable to remove function '%s' from '%s'",description,name) + return end % \end{macrocode} % -% This function removes all the functions registered in a callback. +% Remove all the functions registered in a callback. Unregisters the +% callback handler unless the callback is user-defined. % % \begin{macrocode} -function reset_callback (name) +function reset_callback (name, make_false) if not name or name == "" then - err("unable to reset, no proper callback name passed") + err("unable to reset:\nno proper callback name passed") return elseif not callbacktypes[name] then - err("reset error, '%s' is not a valid callback", name) + err("unable to reset '%s':\nis not a valid callback", name) return end + info("resetting callback '%s'", name) + callbacklist[name] = nil if not lua_callbacks_defaults[name] then - internalregister(name, nil) + if make_false == true then + info("setting '%s' to false", name) + register_callback(name, false) + else + register_callback(name, nil) + end + end +end +% \end{macrocode} +% +% Get a function's priority in a callback list, or false if the function is +% not in the list. +% +% \begin{macrocode} +function priority_in_callback (name, description) + if not name or name == "" + or not callbacktypes[name] + or not description then + return false end local l = callbacklist[name] - if l then - log("resetting callback list '%s'",name) - callbacklist[name] = nil + if not l then return false end + for p, f in pairs(l) do + if f.description == description then + return p + end end + return false end % \end{macrocode} % +% \subsubsection{Public functions for user-defined callbacks} +% % 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 @@ -705,24 +815,24 @@ end % \begin{macrocode} function create_callback(name, ctype, default) if not name then - err("unable to call callback, no proper name passed", name) + err("unable to call callback:\nno proper name passed", name) return nil end if not ctype or not default then - err("unable to create callback '%s': " + err("unable to create callback '%s':\n" .."callbacktype or default function not specified", name) return nil end if callbacktypes[name] then - err("unable to create callback '%s', callback already exists", name) + err("unable to create callback '%s':\ncallback 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) + ctype = types[ctype] + if not ctype then + err("unable to create callback '%s':\ntype '%s' undefined", name, ctype) return nil end - ctype = temp + info("creating '%s' type %s", name, ctype) lua_callbacks_defaults[name] = default callbacktypes[name] = ctype end @@ -734,11 +844,11 @@ end % \begin{macrocode} function call_callback(name, ...) if not name then - err("unable to call callback, no proper name passed", name) + err("unable to call callback:\nno proper name passed", name) return nil end if not lua_callbacks_defaults[name] then - err("unable to call lua callback '%s', unknown callback", name) + err("unable to call lua callback '%s':\nunknown callback", name) return nil end local l = callbacklist[name] @@ -746,92 +856,254 @@ function call_callback(name, ...) 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 + f = handlers[callbacktypes[name]](name) + if not f then err("unknown callback type") + return 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. +% That's all folks! % % \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 +%</lua> +% \end{macrocode} +% +% \section{Test files} +% +% A few basic tests for Plain and LaTeX. Use a separate Lua file for +% convenience, since this package works on the Lua side of the force. +% +% \begin{macrocode} +%<*testlua> +local msg = texio.write_nl +% \end{macrocode} +% +% Test the management functions with a predefined callback. +% +% \begin{macrocode} +local function sample(head,...) + return head, true end +local prio = luatexbase.priority_in_callback +msg("\n*********\n* Testing management functions\n*********") +luatexbase.add_to_callback("hpack_filter", sample, "sample one", 1) +luatexbase.add_to_callback("hpack_filter", sample, "sample two", 2) +luatexbase.add_to_callback("hpack_filter", sample, "sample three", 1) +assert(prio("hpack_filter", "sample three")) +luatexbase.remove_from_callback("hpack_filter", "sample three") +assert(not prio("hpack_filter", "sample three")) +luatexbase.reset_callback("hpack_filter") +assert(not prio("hpack_filter", "sample one")) % \end{macrocode} % -% Finally we -% overwrite \texttt{callback.register} so that it outputs an error. +% Create a callback, and check that the managment functions work with this +% callback too. % % \begin{macrocode} -callback.register = function () -err("function callback.register has been deleted by luamcallbacks, " -.."please use luatexbase.add_to_callback instead.") +local function data_one(s) + texio.write_nl("I'm data 1 whith argument: "..s) + return s end +local function data_two(s) + texio.write_nl("I'm data 2 whith argument: "..s) + return s +end +local function data_three(s) + texio.write_nl("I'm data 3 whith argument: "..s) + return s +end +msg("\n*********\n* Testing user-defined callbacks\n*********") +msg("* create one") +luatexbase.create_callback("fooback", "data", data_one) +msg("* call it") +luatexbase.call_callback("fooback", "default") +msg("* add two functions") +luatexbase.add_to_callback("fooback", data_two, "function two", 2) +luatexbase.add_to_callback("fooback", data_three, "function three", 1) +msg("* call") +luatexbase.call_callback("fooback", "all") +msg("* rm one function") +luatexbase.remove_from_callback("fooback", "function three") +msg("* call") +luatexbase.call_callback("fooback", "all but three") +msg("* reset") +luatexbase.reset_callback("fooback") +msg("* call") +luatexbase.call_callback("fooback", "default") % \end{macrocode} % -% That's all folks! +% Now, we want to make each handler run at least once. So, define dummy +% functions and register them in various callbacks. We will make sure the +% callbacks are executed on the \tex end. Also, we want to check that +% everything works when we unload the functions either one by one, or using +% reset. +% +% A |list| callback. % % \begin{macrocode} -%</lua> +function add_hpack_filter() + luatexbase.add_to_callback('hpack_filter', function(head, ...) + texio.write_nl("I'm a dummy hpack_filter") + return head + end, + 'dummy hpack filter') + luatexbase.add_to_callback('hpack_filter', function(head, ...) + texio.write_nl("I'm an optimized dummy hpack_filter") + return true + end, + 'optimized dummy hpack filter') +end +function rm_one_hpack_filter() + luatexbase.remove_from_callback('hpack_filter', 'dummy hpack filter') +end +function rm_two_hpack_filter() + luatexbase.remove_from_callback('hpack_filter', + 'optimized dummy hpack filter') +end % \end{macrocode} % -% \section{Test files} +% A |simple| callback. +% +% \begin{macrocode} +function add_hyphenate() + luatexbase.add_to_callback('hyphenate', function(head, tail) + texio.write_nl("I'm a dummy hyphenate") + end, + 'dummy hyphenate') + luatexbase.add_to_callback('hyphenate', function(head, tail) + texio.write_nl("I'm an other dummy hyphenate") + end, + 'other dummy hyphenate') +end +function rm_one_hyphenate() + luatexbase.remove_from_callback('hyphenate', 'dummy hyphenate') +end +function rm_two_hyphenate() + luatexbase.remove_from_callback('hyphenate', 'other dummy hyphenate') +end +% \end{macrocode} +% +% A |first| callback. +% +% \begin{macrocode} +function add_find_write_file() + luatexbase.add_to_callback('find_write_file', function(id, name) + texio.write_nl("I'm a dummy find_write_file") + return "dummy-"..name + end, + 'dummy find_write_file') + luatexbase.add_to_callback('find_write_file', function(id, name) + texio.write_nl("I'm an other dummy find_write_file") + return "dummy-other-"..name + end, + 'other dummy find_write_file') +end +function rm_one_find_write_file() + luatexbase.remove_from_callback('find_write_file', + 'dummy find_write_file') +end +function rm_two_find_write_file() + luatexbase.remove_from_callback('find_write_file', + 'other dummy find_write_file') +end +% \end{macrocode} % -% A few basic tests for Plain and LaTeX. +% A |data| callback. +% +% \begin{macrocode} +function add_process_input_buffer() + luatexbase.add_to_callback('process_input_buffer', function(buffer) + return buffer.."\\msg{dummy}" + end, + 'dummy process_input_buffer') + luatexbase.add_to_callback('process_input_buffer', function(buffer) + return buffer.."\\msg{otherdummy}" + end, + 'other dummy process_input_buffer') +end +function rm_one_process_input_buffer() + luatexbase.remove_from_callback('process_input_buffer', + 'dummy process_input_buffer') +end +function rm_two_process_input_buffer() + luatexbase.remove_from_callback('process_input_buffer', + 'other dummy process_input_buffer') +end +% \end{macrocode} +% +% \begin{macrocode} +%</testlua> +% \end{macrocode} % % \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") +\def\msg{\immediate\write16} +\msg{===== BEGIN =====} +% \end{macrocode} +% +% Loading the lua files tests that the management functions can be called +% without raising errors. +% +% \begin{macrocode} +\luatexbase@directlua{dofile('test-mcb.lua')} +% \end{macrocode} +% +% We now want to load and unload stuff from the various callbacks have them +% called to test the handlers. Here is a helper macro for that. +% +% \begin{macrocode} +\def\test#1#2{% + \msg{^^J*********^^J* Testing #1 (type #2)^^J*********} + \msg{* Add two functions} + \luatexbase@directlua{add_#1()} + \csname test_#1\endcsname + \msg{* Remove one} + \luatexbase@directlua{rm_one_#1()} + \csname test_#1\endcsname + \msg{* Remove the second} + \luatexbase@directlua{rm_two_#1()} + \csname test_#1\endcsname + \msg{* Add two functions again} + \luatexbase@directlua{add_#1()} + \csname test_#1\endcsname + \msg{* Remove all functions} + \luatexbase@directlua{luatexbase.reset_callback("#1")} + \csname test_#1\endcsname } +% \end{macrocode} +% +% For each callback, we need a specific macro that triggers it. For the +% hyphenate test, we need to untrap |\everypar| first, in the \latex case. +% +% \begin{macrocode} +\catcode`\_ 11 +%<testlatex>\everypar{} +\def\test_hpack_filter{\setbox0=\hbox{bla}} +\def\test_hyphenate{\showhyphens{hyphenation}} +\def\test_find_write_file{\immediate\openout15 test-mcb-out.log} +\def\test_process_input_buffer{\input test-mcb-aux.tex} +% \end{macrocode} +% +% Now actually test them +% +% \begin{macrocode} +\test{hpack_filter}{list} +\test{hyphenate}{simple} +\test{find_write_file}{first} +\test{process_input_buffer}{data} +% \end{macrocode} +% +% Done. +% +% \begin{macrocode} +\msg{===== END =====} %</testplain,testlatex> %<testplain>\bye %<testlatex>\stop diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx index dd5b118f9aa..81394be2f93 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-modutils.dtx @@ -115,11 +115,7 @@ See source file '\inFileName' for details. % 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}} +% \pkdate{luatexbase-modutils}{v0.2 2010-05-12} % % \maketitle % @@ -129,15 +125,16 @@ See source file '\inFileName' for details. % \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}. +% an option mechanism). It also provides functions for reporting errors and +% warnings in a standardised format. % \end{abstract} % % \tableofcontents % % \section{Documentation} % +% \subsection{Scope of this package} +% % 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 @@ -147,57 +144,148 @@ See source file '\inFileName' for details. % 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. +% \latex's system. % -% This package also provides Lua functions for reporting errors, warnings, -% etc. +% \medskip % % 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()|. +% completely orthogonal with the present package. It has nothing to do with +% identification and deals only with namespaces: more precisely, it +% modifies the current environment. So, you should continue to +% use it normally regardless of whether you chose to use this package's +% features for identification. +% +% It is recommended to always use |module()| or any other method that ensure +% the global name space remains clean. For example, you may heavily use the +% |local| keyword and explicitly qualify the name of every non-local symbol. +% Chapter 15 of \href{http://www.lua.org/pil/}{Programming in Lua, 1st ed.} +% discusses various methods for managing packages. % % \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. +% \begin{qcode} +% \cs{RequireLuaModule}\marg{name}\oarg{date} +% \end{qcode} +% +% The macro |\RequireLuaModule| is an interface to the Lua function +% |require_module|; it take the same arguments with the same meaning. The +% second argument is optional. % % \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). +% \begin{qcode} +% luatexbase.require_module({\meta{name}} [, \meta{required date}]) +% \end{qcode} +% +% The function |luatexbase.require_module()| may be used as a replacement to +% |require()|. If only one argument is given, the only difference with +% |require()| is it checks that the module properly identifies itself (as +% explained below) with the same name. +% +% The second argument is optional; if used, it must be a +% string\footnote{Previous versions of the package supported floating-point +% version numbers as well, but it caused confusion with authors trying to use +% version strings such as |0.3a| and probably isn't worth the trouble.} +% containing a date in |YYYY//MM/DD| format which specifies the minimum +% version of the module required. +% +% \begin{qcode} +% luatexbase.provides_module(\meta{info}) +% \end{qcode} +% This function is used by modules to identify themselves; the argument is a +% table containing information about the module. The required field |name| +% must contain the name of the module. It is recommended to provide a field +% |date| with the same format as above. Optional fields |version| (number or +% string) and |description| may be used if present. Other fields are ignored. +% +% If a date was required, then a warning is issued if the required date is +% strictly newer than the declared date (or if no date was declared). A list +% of loaded modules and their associated information is kept, and used to +% check the date without reloading the module (since |require()| won't reload +% it anyway) if a module is required several times. +% +% \begin{qcode} +% luatexbase.module_error(\meta{name}, \meta{message}, ...) +% luatexbase.module_warning(\meta{name}, \meta{message}, ...) +% luatexbase.module_info(\meta{name}, \meta{message}, ...) +% luatexbase.module_log(\meta{name}, \meta{message}, ...) +% \end{qcode} +% These functions are similar to \latex's |\PackageError|, |\PackageWarning| +% and |\PackageInfo| in the way they format the output. No automatic line +% breaking is done, you may still use |\n| as usual for that, and the name of +% the package will be prepended to each output line (except for |log| which is +% intended for short messages in a non-verbose format). The first argument +% is the name of the current module; the remaining arguments are passed to +% |string.format()|. +% +% Note that |module_error| raises an actual Lua error with |error()|, which +% currently means a call stack will be dumped. While this may not look pretty, +% at least it provides useful information for tracking the error down. +% +% \begin{qcode} +% local err, warn, info, log = luatexbase.errwarinf(\meta{name}) +% local err, warn, info, log = luatexbase.provides_module(\meta{name}) +% \end{qcode} +% Customised versions of the above commands maybe obtained by invoking +% |errwarinf()| and are also returned by |provides_module()|. They don't take +% the name of the module as their first argument any more, so that you don't +% need to repeat it all over the place. (Notice that |error| is the name of a +% standard Lua function, so you may want to avoid overwriting it, hence the +% use of |err| in the above example.) +% +% \subsection{Templates} +% +% Let me emphasize again that, while |luatexbase.require_module()| is meant to +% be used as a replacement for |require()|, the function +% |luatexbase.provides_module()| \emph{is not} a replacement for |module()|: +% they just don't do the same thing (declaring information vs changing the +% current name space). +% +% Now, here is how you module may begin: +% \begin{verbatim} +% local err, warn, info, log = luatexbase.provides_module({ +% -- required +% name = 'mymodule', +% -- recommended +% date = '1970/01/01', +% version = 0.0, -- or version = '0.0a', +% description = 'a Lua module template', +% -- optional and ignored +% author = 'A. U. Thor', +% licence = 'LPPL v1.3+', +% }) +% +% module('mynamespace', package.seeall) +% -- or any other method (see chapter 15 of PIL for examples) +% \end{verbatim} +% +% Alternatively, if you don't want to assume \pk{luatexbase-modutils} is +% loaded, you may load your module with: +% \begin{verbatim} +% (luatexbase.require_module or require)('mymodule') +% \end{verbatim} +% and begin your module's code with: +% \begin{verbatim} +% if luatexbase._provides_module then +% luatexbase.provides_module({ +% -- required +% name = 'mymodule', +% -- recommended +% date = '1970/01/01', +% version = 0.0, -- or version = '0.0a', +% description = 'a Lua module template', +% -- optional and ignored +% author = 'A. U. Thor', +% licence = 'LPPL v1.3+', +% }) +% end +% +% module('mynamespace', package.seeall) +% -- or any other method (see chapter 15 of PIL for examples) +% +% local function err(msg) +% -- etc. +% \end{verbatim} % % \section{Implementation} % @@ -263,7 +351,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-modutils}[2010/05/27 v0.2a Module utilities for LuaTeX] +\x{luatexbase-modutils}[2010/10/10 v0.3 Module utilities for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -277,60 +365,94 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-modutils}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@modutils@AtEnd \expandafter\endinput \fi % \end{macrocode} % -% Load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}) and require -% supporting Lua module. +% Load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), require the +% supporting Lua module and make sure |luaescapestring| is available. % % \begin{macrocode} -\begingroup\expandafter\expandafter\expandafter\endgroup -\expandafter\ifx\csname RequirePackage\endcsname\relax - \input luatexbase-loader.sty -\else +\ifdefined\RequirePackage \RequirePackage{luatexbase-loader} +\else + \input luatexbase-loader.sty \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} +% \subsection{Auxiliary definitions} % -% Interface to |use_module()|. +% We need a version of |\@ifnextchar|. The definitions for the not-\latex +% case are stolen from \pk{ltxcmds} verbatim, only the prefix is changed. % % \begin{macrocode} -\def\luatexUseModule#1{\luatexbase@directlua{% - luatexbase.use_module("\luatexluaescapestring{#1}")}} +\ifdefined\kernel@ifnextchar + \let\lltxb@ifnextchar\kernel@ifnextchar +\else + \chardef\lltxb@zero0 + \chardef\lltxb@two2 + \long\def\lltxb@ifnextchar#1#2#3{% + \begingroup + \let\lltxb@CharToken= #1\relax + \toks\lltxb@zero{#2}% + \toks\lltxb@two{#3}% + \futurelet\lltxb@LetToken\lltxb@ifnextchar@ + } + \def\lltxb@ifnextchar@{% + \ifx\lltxb@LetToken\lltxb@CharToken + \expandafter\endgroup\the\toks\expandafter\lltxb@zero + \else + \ifx\lltxb@LetToken\lltxb@SpaceToken + \expandafter\expandafter\expandafter\lltxb@@ifnextchar + \else + \expandafter\endgroup\the\toks + \expandafter\expandafter\expandafter\lltxb@two + \fi + \fi + } + \begingroup + \def\x#1{\endgroup + \def\lltxb@@ifnextchar#1{% + \futurelet\lltxb@LetToken\lltxb@ifnextchar@ + }% + }% + \x{ } + \begingroup + \def\x#1{\endgroup + \let\lltxb@SpaceToken= #1% + }% + \x{ } +\fi % \end{macrocode} % -% Interface to |require_module()| with syntax depending on the format. +% \subsubsection{User macro} +% +% Interface to the Lua function for module loading. Avoid passing a second +% argument to the function if empty (most probably not specified). % % \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 +\def\RequireLuaModule#1{% + \lltxb@ifnextchar[{\lltxb@requirelua{#1}}{\lltxb@requirelua{#1}[]}} +\def\lltxb@requirelua#1[#2]{% + \luatexbase@directlua{luatexbase.require_module( + "\luatexluaescapestring{#1}" + \expandafter\ifx\expandafter\/\detokenize{#2}\/\else + , "\luatexluaescapestring{#2}" + \fi)}} % \end{macrocode} % % \begin{macrocode} @@ -348,75 +470,75 @@ module("luatexbase", package.seeall) % \subsection{Internal functions and data} % % Tables holding informations about the modules loaded and the versions -% required. +% required. Keys are module names and values are the info tables as passed +% to |provides_module()|. % % \begin{macrocode} local modules = modules or {} -local requiredversions = {} % \end{macrocode} % -% Convert a date in YYYY/MM/DD format into a number +% Convert a date in YYYY/MM/DD format into a number. % % \begin{macrocode} -local function datetonumber(date) +local function date_to_int(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. +% Here are the reporting functions for the modules. An internal function is +% used for error messages, so that the calling level (last argument of +% |error()| remains constant using either |module_error()| or a custom +% version as returned by |errwarinf()|. % % \begin{macrocode} +local function msg_format(msg_type, mod_name, ...) + local cont = '('..mod_name..')' .. ('Module: '..msg_type):gsub('.', ' ') + return 'Module '..mod_name..' '..msg_type..': ' + .. string.format(...):gsub('\n', '\n'..cont) .. '\n' +end local function module_error_int(mod, ...) - error('Module '..mod..' error: '..string.format(...), 3) + error(msg_format('error', mod, ...), 3) end function module_error(mod, ...) module_error_int(mod, ...) end +% \end{macrocode} +% +% Split the lines explicitly in order not to depend on the value of +% |\newlinechar|. +% +% \begin{macrocode} function module_warning(mod, ...) - texio.write_nl("Module "..mod.." warning: "..string.format(...)) + for _, line in ipairs(msg_format('warning', mod, ...):explode('\n')) do + texio.write_nl(line) + end end function module_info(mod, ...) - texio.write_nl(mod..": "..string.format(...)) + for _, line in ipairs(msg_format('info', mod, ...):explode('\n')) do + texio.write_nl(line) + end end -function module_log(mod, ...) - texio.write_nl('log', mod..": "..string.format(...)) +% \end{macrocode} +% +% No line splitting or advanced formating here. +% +% \begin{macrocode} +function module_log(mod, msg, ...) + texio.write_nl('log', mod..': '..msg:format(...)) end -function module_term(mod, ...) - texio.write_nl('term', mod..": "..string.format(...)) +% \end{macrocode} +% +% Produce custom versions of the reporting functions. +% +% \begin{macrocode} +function errwarinf(name) + return function(...) module_error_int(name, ...) end, + function(...) module_warning(name, ...) end, + function(...) module_info(name, ...) end, + function(...) module_log(name, ...) end end % \end{macrocode} % @@ -424,83 +546,42 @@ end % present module. % % \begin{macrocode} -local function err(...) module_error_int('luatexbase.modutils', ...) end -local function warn(...) module_warning('luatexbase.modutils', ...) end +local err, warn = errwarinf('luatexbase.modutils') % \end{macrocode} % % \subsubsection{module loading and providing functions} % -% Load a module without version checking. +% Load a module with mandatory name checking and optional version checking. % % \begin{macrocode} -function use_module(name) +function require_module(name, req_date) 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 + local info = modules[name] + if not info then + warn("module '%s' was not properly identified", name) + elseif version then + if not (info.date and date_to_int(info.date) > date_to_int(req_date)) + then + warn("module '%s' required in version '%s'\n" + .. "but found in version '%s'", name, req_date, info.date) end - else - requiredversions[name] = luaversion - use_module(name) end end % \end{macrocode} % -% Provide identification information for a module. +% Provide identification information for a module. As a bonus, custom +% reporting functions are returned. No need to do any check here, +% everything done in |require_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 +function provides_module(info) + if not (info and info.name) then + err('provides_module: missing information') end - modules[mod.name] = mod - texio.write_nl('log', string.format("Lua module: %s %s v%.02f %s\n", - mod.name, mod.date, mod.version, mod.description)) + texio.write_nl('log', string.format("Lua module: %s %s %s %s\n", + info.name, info.date or '', info.version or '', info.description or '')) + modules[info.name] = info + return errwarinf(info.name) end % \end{macrocode} % @@ -514,28 +595,26 @@ end % % \begin{macrocode} %<*testdummy> -luatexbase.provides_module { +local err, warn, info, log = luatexbase.provides_module { name = 'test-modutils', date = '2000/01/01', version = 1, description = 'dummy test package', } +info('It works!\nOh, rly?\nYeah rly!') +log("I'm a one-line info.") %</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 +% TeX, is able to load and identify the above dummy module. % % \begin{macrocode} %<testplain>\input luatexbase-modutils.sty %<testlatex>\RequirePackage{luatexbase-modutils} %<*testplain,testlatex> -\luatexUseModule{test-modutils} -\luatexRequireModule -%<testlatex>[1970/01/01] -{test-modutils} -%<testplain>{1970/01/01} +\RequireLuaModule{test-modutils} +\RequireLuaModule{test-modutils}[1970/01/01] %</testplain,testlatex> %<testplain>\bye %<testlatex>\stop diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx index 08d1060ab23..079b0045fba 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase-regs.dtx @@ -103,11 +103,7 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase-regs} package} -% \date{v0.2a 2010/05/27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and -% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase-regs}{2010/10/10 v0.3} % % \maketitle % @@ -211,7 +207,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase-regs}[2010/05/27 v0.2a Registers allocation for LuaTeX] +\x{luatexbase-regs}[2010/10/10 v0.3 Registers allocation for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -225,14 +221,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase-regs}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@regs@AtEnd \expandafter\endinput \fi @@ -267,7 +266,7 @@ See source file '\inFileName' for details. \let\x\PackageWarningNoLine \fi \expandafter\endgroup - \x{luatexbase-regs}{etex macros not loaded!^^J + \x{luatexbase-regs}{etex macros not loaded!^^J% Registers allocation scheme will not be extended.} \else % \end{macrocode} diff --git a/Master/texmf-dist/source/luatex/luatexbase/luatexbase.dtx b/Master/texmf-dist/source/luatex/luatexbase/luatexbase.dtx index 3e14f4cf1f4..405e72007de 100644 --- a/Master/texmf-dist/source/luatex/luatexbase/luatexbase.dtx +++ b/Master/texmf-dist/source/luatex/luatexbase/luatexbase.dtx @@ -96,24 +96,20 @@ See source file '\inFileName' for details. % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % -% \title{The \pk{luatexbase} package} -% \date{v0.2a 2010-05-27} -% \author{% -% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and -% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}} +% \pkdate{luatexbase}{v0.3 2010-05-27} % % \maketitle % % \begin{abstract} -% This convenience package loads all of the (stable) packages in the -% \pk{luatexbase} bundle. +% This package provides resource management for the LuaTeX macro programmer. +% It is divided in sub-packages which can be used independantly if desired. % \end{abstract} % % \tableofcontents % % \section{Documentation} % -% The \pk{luatexbase} package loads the following packages: +% The \pk{luatexbase} package consists of the following sub-packages: % \begin{description} % \subpk{compat} compatibility helpers for \verb+\directlua+, primitive % names and version information from Lua. @@ -124,25 +120,19 @@ See source file '\inFileName' for details. % \emph{\`a la} \pk{etex}. % \subpk{cctb} catcode table allocation. % \subpk{attr} attribute allocation. -% \end{description} -% -% These packages are almost stable: it is unlikely that backward-incompatible -% changes will be made in the future (other than necessary for merging with -% \pk{luatex.sty}, which strongly overlaps with the above). If they happen, -% such changes will be announced on \email{lualatex-dev@tug.org} before they -% are pushed to the master branch and then CTAN. -% -% Other packages included in the bundle, but currently not loaded by the -% present package, are: -% \begin{description} -% \subpk{modutils} Lua module declaration, including version checks. % \subpk{mcb} callbacks extensions allowing to register many functions in a % single callback, and declare new callbacks for packages. +% \subpk{modutils} Lua module declaration, including version checks. % \end{description} % -% All packages in this bundle are supposed to work with \luatex 0.25.4 to -% 0.60.x, with formats based on \plaintex or \latex, as included in \texlive -% 2008, 2009, and 2010. +% The package is mostly stable: it is unlikely that backward-incompatible +% changes will be made in the future, other than necessary for merging with +% \pk{luatex.sty}, with which a few sub-packages strongly overlap. If they do +% happen, such changes will be announced on the development list, and clearly +% identified in the \file{Changes} file. +% +% All sub-packages are tested with \luatex 0.25.4 to 0.60.x and formats based +% on \plaintex or \latex, as included in \texlive 2008, 2009, and 2010. % % \section{Implementation} % @@ -206,7 +196,7 @@ See source file '\inFileName' for details. \let\x\ProvidesPackage \fi \expandafter\endgroup -\x{luatexbase}[2010/05/27 v0.2a Module utilities for LuaTeX] +\x{luatexbase}[2010/10/06 v0.3 Module utilities for LuaTeX] % \end{macrocode} % % Make sure \luatex is used. @@ -220,14 +210,17 @@ See source file '\inFileName' for details. \fi \ifluatex\else \begingroup - \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax - \def\x#1#2{\begingroup\newlinechar10 - \immediate\write16{Package #1 warning: #2}\endgroup} + \expandafter\ifx\csname PackageError\endcsname\relax + \def\x#1#2#3{\begingroup \newlinechar10 + \errhelp{#3}\errmessage{Package #1 error: #2}\endgroup} \else - \let\x\PackageWarningNoLine + \let\x\PackageError \fi \expandafter\endgroup - \x{luatexbase}{LuaTeX is required for this package. Aborting.} + \x{luatexbase-attr}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine^^J% + (command `lualatex' or `luatex').^^J% + Package loading has been stopped to prevent additional errors.} \lltxb@core@AtEnd \expandafter\endinput \fi @@ -243,12 +236,16 @@ See source file '\inFileName' for details. \input luatexbase-regs.sty \input luatexbase-attr.sty \input luatexbase-cctb.sty + \input luatexbase-mcb.sty + \input luatexbase-modutils.sty \else \RequirePackage{luatexbase-compat} \RequirePackage{luatexbase-loader} \RequirePackage{luatexbase-regs} \RequirePackage{luatexbase-attr} \RequirePackage{luatexbase-cctb} + \RequirePackage{luatexbase-mcb} + \RequirePackage{luatexbase-modutils} \fi % \end{macrocode} % |