summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Changes38
-rw-r--r--Makefile56
-rw-r--r--TODO53
-rw-r--r--lltxb-dtxstyle.tex5
-rw-r--r--luatexbase-attr.dtx55
-rw-r--r--luatexbase-cctb.dtx89
-rw-r--r--luatexbase-compat.dtx410
-rw-r--r--luatexbase-loader.dtx167
-rw-r--r--luatexbase-mcb.dtx (renamed from luamcallbacks.dtx)905
-rw-r--r--luatexbase-modutils.dtx241
-rw-r--r--luatexbase-regs.dtx14
12 files changed, 1320 insertions, 717 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d315825
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.lua
+*.pdf
+*.sty
+test-*
diff --git a/Changes b/Changes
index 3dc90ef..b80ae0c 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,43 @@
Changes in the luatexbase package/bundle
+Summary of backwards-incompatible interface changes between 0.1 and 0.2:
+ - Lua objects are now in table luatexbase, not luatextra.
+ - Lua tables tex.attributenumber and tex.catcodetablenumber are not
+ created any more, use their couterparts in luatexbase.
+ - \luatexsetcatcoderange has been renamed to \setcatcoderange.
+ - luamcallbacks has been renamed; Lua objects are now in luatexbase,
+ no more in callback.* or luamcallbacks.*
+ - module error/warning etc now apply string.format to the arguments.
+
+2010/03/29
+ all
+ - use luatexbase as the Lua module name
+ - change the filename of the lua module (suppress luatexbase.)
+ - load luatexbase-compat
+ luatexbase-compat
+ - new
+ luatexbase-attr
+ - don't create tex.attributenumber
+ - load luatexbase-compat
+ luatexbase-cctb
+ - don't create tex.catcodetablenumber
+ - rename \luatexsetcatcoderange to \setcatcoderange
+ - load lua-compat
+ luamcallbacks -> luatexbase-mcb
+ - rename package
+ - functions are now in luatexbase rather than luamcallbacks, they
+ are no more copied to callbacks either
+ - lua objects are now local (except for the public interface)
+ - test file now for plain and latex
+ luatexbase-loader
+ - require"foo.bar" now looks for foo/bar then foo.bar, see doc for
+ details
+ - better cooperation with the original package loader
+ - works with luatex 0.25.4
+ luatexbase-modutils
+ - module error/warning etc now apply string.format to the arguments.
+ - use error() instead of \errmessage.
+
2010/03/28
luatexbase-*
- add catcode defenses
diff --git a/Makefile b/Makefile
index 143f48a..b2972ba 100644
--- a/Makefile
+++ b/Makefile
@@ -4,24 +4,34 @@ NAME = luatexbase
DTX = $(wildcard *.dtx)
DOC = $(patsubst %.dtx, %.pdf, $(DTX))
DTXSTY = lltxb-dtxstyle.tex
+
+# used for check dependencies
+COMPAT_RUN = luatexbase-compat.sty
LOADER_RUN = luatexbase-loader.sty luatexbase.loader.lua
-MOD_RUN = luatexbase-modutils.sty luatexbase.modutils.lua
+MOD_RUN = luatexbase-modutils.sty modutils.lua
+LINKS = luatexbase.attr.lua luatexbase.cctb.lua \
+ luatexbase.mcb.lua luatexbase.modutils.lua
# Files grouped by generation mode
-UNPACKED_MCB = test-luamcallbacks.tex luamcallbacks.lua
+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 luatexbase.attr.lua \
+UNPACKED_ATTR = luatexbase-attr.sty attr.lua \
test-attr-plain.tex test-attr-latex.tex
-UNPACKED_CCTB = luatexbase-cctb.sty luatexbase.cctb.lua \
+UNPACKED_CCTB = luatexbase-cctb.sty cctb.lua \
test-cctb-plain.tex test-cctb-latex.tex
-TMP_LOADER = test-loader # temporary file for testing
+# temporary file for testing loader
+TMP_LOADER = test-loader
UNPACKED_LOADER = $(LOADER_RUN) \
+ test-loader-plain.tex test-loader-latex.tex \
$(TMP_LOADER).lua test-loader.sub.lua
-UNPACKED_MODUTILS = $(MOD_RUN) \
- test-modutils-plain.tex test-modutils-latex.tex test-modutils.lua
+UNPACKED_MODUTILS = $(MOD_RUN) test-modutils.lua \
+ test-modutils-plain.tex test-modutils-latex.tex
+UNPACKED_COMPAT = $(COMPAT_RUN) \
+ test-compat-plain.tex test-compat-latex.tex
UNPACKED = $(UNPACKED_MCB) $(UNPACKED_REGS) $(UNPACKED_ATTR) $(UNPACKED_CCTB) \
- $(UNPACKED_LOADER) $(UNPACKED_MODUTILS)
+ $(UNPACKED_LOADER) $(UNPACKED_MODUTILS) $(UNPACKED_COMPAT)
COMPILED = $(DOC)
GENERATED = $(COMPILED) $(UNPACKED)
SOURCE = $(DTX) $(DTXSTY) README TODO Changes Makefile
@@ -52,7 +62,8 @@ 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: check-regs check-attr check-cctb check-loader check-modutils check-mcb \
+ check-compat
doc: $(COMPILED)
unpack: $(UNPACKED)
ctan: check $(CTAN_ZIP)
@@ -65,7 +76,10 @@ world: all ctan
$(DO_PDFLATEX)
$(DO_PDFLATEX)
-$(UNPACKED_MCB): luamcallbacks.dtx
+luatexbase.%.lua: %.lua
+ ln -sf $< $@
+
+$(UNPACKED_MCB): luatexbase-mcb.dtx
$(DO_TEX)
$(UNPACKED_REGS): luatexbase-regs.dtx
@@ -83,29 +97,37 @@ $(UNPACKED_LOADER): luatexbase-loader.dtx
$(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: $(UNPACKED_ATTR) $(LOADER_RUN)
+check-attr: $(UNPACKED_ATTR) $(LOADER_RUN) $(LINKS) $(COMPAT_RUN)
luatex --interaction=batchmode test-attr-plain.tex >/dev/null
lualatex --interaction=batchmode test-attr-latex.tex >/dev/null
-check-cctb: $(UNPACKED_CCTB) $(LOADER_RUN)
+check-cctb: $(UNPACKED_CCTB) $(LOADER_RUN) $(LINKS) $(COMPAT_RUN)
luatex --interaction=batchmode test-cctb-plain.tex >/dev/null
lualatex --interaction=batchmode test-cctb-latex.tex >/dev/null
-check-loader: $(UNPACKED_LOADER)
+check-loader: $(UNPACKED_LOADER) $(COMPAT_RUN)
echo "this is no lua code" > $(TMP_LOADER).tex
luatex --interaction=batchmode test-loader-plain.tex >/dev/null
lualatex --interaction=batchmode test-loader-latex.tex >/dev/null
-check-modutils: $(UNPACKED_MODUTILS) $(LOADER_RUN)
+check-modutils: $(UNPACKED_MODUTILS) $(LOADER_RUN) $(LINKS) $(COMPAT_RUN)
luatex --interaction=batchmode test-modutils-plain.tex >/dev/null
lualatex --interaction=batchmode test-modutils-latex.tex >/dev/null
-check-mcb: $(UNPACKED_MCB) $(LOADER_RUN) $(MOD_RUN)
- luatex --interaction=batchmode test-luamcallbacks.tex >/dev/null
+check-mcb: $(UNPACKED_MCB) $(LOADER_RUN) $(MOD_RUN) $(LINKS) $(COMPAT_RUN)
+ luatex --interaction=batchmode test-mcb-plain.tex >/dev/null
+ 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."
@@ -143,5 +165,5 @@ clean:
@$(RM) -- *.log *.aux *.toc *.idx *.ind *.ilg *.out test-*.pdf
mrproper: clean
- @$(RM) -- $(GENERATED) $(ZIPS) $(TMP_LOADER).tex
+ @$(RM) -- $(GENERATED) $(ZIPS) $(LINKS) $(TMP_LOADER).tex
diff --git a/TODO b/TODO
index b105d41..3ef3b70 100644
--- a/TODO
+++ b/TODO
@@ -1,37 +1,32 @@
-Later
-=====
-
-- check for user macros starting with \luatex
-- change lua module name(s) (luatexbase or luatexbase.regs etc)
-- compat with LuaTeX 0.25.4? (Means problems with \directlua, primitive names,
- kpse.find_file(..., 'lua'), etc.) Maybe do a compat package?
-
-attr
-----
-
-- don't write in the tex table!
-
-cctb
-----
-
-- don't write in the tex table!
-- don't define macros starting with \luatex
-
-loader
-------
-
-- a.b.c -> a/b/c or a/b.c or a.b.c? What do to with files under texmf/scripts?
-- adujst names of the modules afterwards
-- write doc
-- make a real test using a fake texmf tree as TEXMFHOME?
-
modutils
--------
-Review extensively.
+- Renaming:
+ \luatexUseModule
+ \luatexRequireModule
+- syntax of public TeX macros and Lua functions
+- create private functions for infwarrerr?
+- review logic (see what LaTeX2e does)
+- General review of code and comments.
+- Update user documentation.
mcallbacks
----------
-Review extensively.
+- Incorporate remaining bits from luatextra?
+- Enhance test file?
+- General review of code and comments.
+- Update user documentation.
+
+luatexbase
+----------
+
+- create it, make it load the others (except maybe mcb for now)
+- create general documentation
+
+afterwards
+----------
+- check/adapt luatextra
+- Bump version number, make zip, announce.
+- engage discussion with Heiko
diff --git a/lltxb-dtxstyle.tex b/lltxb-dtxstyle.tex
index f3bafb4..50eb0da 100644
--- a/lltxb-dtxstyle.tex
+++ b/lltxb-dtxstyle.tex
@@ -32,5 +32,10 @@
\newcommand\pk{\textsf}
\newcommand\cmdname{\texttt}
+% for hyperref
+\pdfstringdefDisableCommands{%
+ \def\cs#1{\@backslashchar #1}%
+ }
+
% easy verbatim
\MakeShortVerb\|
diff --git a/luatexbase-attr.dtx b/luatexbase-attr.dtx
index 6332260..194cb8d 100644
--- a/luatexbase-attr.dtx
+++ b/luatexbase-attr.dtx
@@ -8,7 +8,7 @@
%
% This work consists of the main source file luatexbase-attr.dtx
% and the derived files
-% luatexbase-attr.sty luatexbase.attr.lua
+% luatexbase-attr.sty attr.lua
% test-regs-plain.tex test-regs-latex.tex
%
% Unpacking:
@@ -66,7 +66,7 @@ See source file '\inFileName' for details.
\generate{%
\usedir{tex/luatex/luatexbase}%
- \file{luatexbase.attr.lua}{\from{luatexbase-attr.dtx}{luamodule}}%
+ \file{attr.lua}{\from{luatexbase-attr.dtx}{luamodule}}%
}
\obeyspaces
@@ -75,7 +75,7 @@ See source file '\inFileName' for details.
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
-\Msg{* luatexbase-attr.sty luatexbase.attr.lua}
+\Msg{* luatexbase-attr.sty attr.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
@@ -127,6 +127,8 @@ See source file '\inFileName' for details.
% 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
@@ -154,7 +156,7 @@ See source file '\inFileName' for details.
% 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
-% |luatextra.attributes.foobar| (mind the absence of backslash here) at any
+% |luatexbase.attributes.foobar| (mind the absence of backslash here) at any
% time.
%
% \section{Implementation}
@@ -221,7 +223,7 @@ See source file '\inFileName' for details.
\let\x\ProvidesPackage
\fi
\expandafter\endgroup
-\x{luatexbase-attr}[2010/03/11 v0.1 Attributes allocation for LuaTeX (mpg)]
+\x{luatexbase-attr}[2010/03/11 v0.1 Attributes allocation for LuaTeX]
% \end{macrocode}
%
% Make sure \luatex is used.
@@ -248,9 +250,31 @@ See source file '\inFileName' for details.
\fi
% \end{macrocode}
%
-% \subsubsection{Main content}
+% \subsubsection{Primitives needed}
%
-% Load the supporting Lua module.
+% 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
@@ -259,9 +283,11 @@ See source file '\inFileName' for details.
\else
\RequirePackage{luatexbase-loader}
\fi
-\directlua{require('luatexbase.attr.lua')}
+\luatexbase@directlua{require('luatexbase.attr')}
% \end{macrocode}
%
+% \subsection{User macros}
+%
% The allocaton macro.
%
% \begin{macrocode}
@@ -273,9 +299,10 @@ See source file '\inFileName' for details.
\allocationnumber\lltxb@attribute@alloc
\global\luatexattributedef#1=\allocationnumber
\unsetluatexattribute#1%
- \begingroup\escapechar\m@ne \expandafter\endgroup
- \directlua{luatextra.attributedef_from_tex(
+ \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}%
@@ -311,14 +338,13 @@ See source file '\inFileName' for details.
%
% \begin{macrocode}
%<*luamodule>
-module('luatextra', package.seeall)
+module('luatexbase', package.seeall)
% \end{macrocode}
%
% Record the allocation number in a Lua table.
%
% \begin{macrocode}
attributes = {}
-tex.attributenumber = attributes
function attributedef_from_tex(name, number)
attributes[name] = tonumber(number)
end
@@ -342,13 +368,14 @@ end
\newluatexattribute\testattr
\setluatexattribute\testattr{1}
\unsetluatexattribute\testattr
-\directlua{assert(luatextra.attributes.testattr)}
+\catcode64 11
+\luatexbase@directlua{assert(luatexbase.attributes.testattr)}
\begingroup
\escapechar64
\newluatexattribute\anotherattr
\endgroup
\setluatexattribute\anotherattr{1}
-\directlua{assert(luatextra.attributes.anotherattr)}
+\luatexbase@directlua{assert(luatexbase.attributes.anotherattr)}
%</testplain,testlatex>
%<testplain>\bye
%<testlatex>\stop
diff --git a/luatexbase-cctb.dtx b/luatexbase-cctb.dtx
index 09ff77f..90dab94 100644
--- a/luatexbase-cctb.dtx
+++ b/luatexbase-cctb.dtx
@@ -8,7 +8,7 @@
%
% This work consists of the main source file luatexbase-cctb.dtx
% and the derived files
-% luatexbase-cctb.sty luatexbase.cctb.lua
+% luatexbase-cctb.sty cctb.lua
% test-cctb-plain.tex test-cctb-latex.tex
%
% Unpacking:
@@ -66,7 +66,7 @@ See source file '\inFileName' for details.
\generate{%
\usedir{tex/luatex/luatexbase}%
- \file{luatexbase.cctb.lua}{\from{luatexbase-cctb.dtx}{luamodule}}%
+ \file{cctb.lua}{\from{luatexbase-cctb.dtx}{luamodule}}%
}
\obeyspaces
@@ -75,7 +75,7 @@ See source file '\inFileName' for details.
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
-\Msg{* luatexbase-cctb.sty luatexbase.cctb.lua}
+\Msg{* luatexbase-cctb.sty cctb.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
@@ -127,6 +127,8 @@ See source file '\inFileName' for details.
% 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
@@ -135,7 +137,7 @@ See source file '\inFileName' for details.
% (once they are allocated), two helper macros are available.
%
% \begin{quote}
-% \cs{luatexsetcatcoderange}\marg{from}\marg{to}\marg{value}
+% \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}.
@@ -168,7 +170,7 @@ See source file '\inFileName' for details.
% 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
-% |luatextra.catcodetables|, whose keys is the name of the control sequence
+% |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}
@@ -244,7 +246,7 @@ See source file '\inFileName' for details.
\let\x\ProvidesPackage
\fi
\expandafter\endgroup
-\x{luatexbase-cctb}[2010/03/26 v0.1 Catcodetable allocation for LuaTeX (mpg)]
+\x{luatexbase-cctb}[2010/03/26 v0.1 Catcodetable allocation for LuaTeX]
% \end{macrocode}
%
% Make sure \luatex is used.
@@ -271,9 +273,10 @@ See source file '\inFileName' for details.
\fi
% \end{macrocode}
%
-% \subsubsection{Main content}
+% \subsubsection{Load supporting Lua module}
%
-% Load the supporting Lua module.
+% First load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}), then
+% the supporting Lua module.
%
% \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
@@ -282,9 +285,33 @@ See source file '\inFileName' for details.
\else
\RequirePackage{luatexbase-loader}
\fi
-\directlua{require('luatexbase.cctb.lua')}
+\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.
%
@@ -297,9 +324,10 @@ See source file '\inFileName' for details.
\allocationnumber\lltxb@catcodetable@alloc
\global\chardef#1\allocationnumber
\luatexinitcatcodetable\allocationnumber
- \begingroup\escapechar\m@ne \expandafter\endgroup
- \directlua{luatextra.catcodetabledef_from_tex(
+ \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}%
@@ -320,7 +348,7 @@ See source file '\inFileName' for details.
% Set the catcodes for a range of characters.
%
% \begin{macrocode}
-\def\luatexsetcatcoderange#1#2#3{%
+\def\setcatcoderange#1#2#3{%
\edef\luaSCR@temp{%
\noexpand\@tempcnta=\the\@tempcnta
\noexpand\@tempcntb=\the\@tempcntb
@@ -346,6 +374,8 @@ See source file '\inFileName' for details.
\endgroup}
% \end{macrocode}
%
+% \subsubsection{Predefined tables}
+%
% The |IniTeX| catcode table needs no extra initialisation.
%
% \begin{macrocode}
@@ -361,8 +391,8 @@ See source file '\inFileName' for details.
\catcode0 12 % nul
\catcode13 12 % carriage return
\catcode37 12 % percent
- \luatexsetcatcoderange{65}{90}{12}% A-Z
- \luatexsetcatcoderange{97}{122}{12}% a-z
+ \setcatcoderange{65}{90}{12}% A-Z
+ \setcatcoderange{97}{122}{12}% a-z
\catcode92 12 % backslash
\catcode127 12 }
% \end{macrocode}
@@ -380,7 +410,7 @@ See source file '\inFileName' for details.
\newluatexcatcodetable\CatcodeTableLaTeX
\setluatexcatcodetable\CatcodeTableLaTeX{%
\luatexcatcodetable\CatcodeTableIniTeX
- \luatexsetcatcoderange{0}{31}{15}%
+ \setcatcoderange{0}{31}{15}%
\catcode9 10 % tab
\catcode12 13 % form feed
\catcode13 5 % carriage return
@@ -419,7 +449,7 @@ See source file '\inFileName' for details.
% Finally do the shortcuts.
%
% \begin{macrocode}
-\directlua{luatextra.catcodetable_do_shortcuts()}
+\luatexbase@directlua{luatexbase.catcodetable_do_shortcuts()}
% \end{macrocode}
%
% That's all, folks!
@@ -433,28 +463,26 @@ See source file '\inFileName' for details.
%
% \begin{macrocode}
%<*luamodule>
-module('luatextra', package.seeall)
+module('luatexbase', package.seeall)
% \end{macrocode}
%
-% In the same way, the table \texttt{tex.catcodetablenumber} contains the
-% numbers of the catcodetables registered with
-% \texttt{\string\newluacatcodetable}.
+% The number associated to a CS name is remembered in the |catcodetables|
+% table.
%
% \begin{macrocode}
catcodetables = {}
-tex.catcodetablenumber = catcodetables
function catcodetabledef_from_tex(name, number)
catcodetables[name] = tonumber(number)
end
% \end{macrocode}
%
-% With this function we create some shortcuts for a better readability in
-% lua code. This makes |tex.catcodetablenumber.latex| equivalent to
-% |tex.catcodetablenumber['CatcodeTableLaTeX']|.
+% 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 = luatextra.catcodetables
+ local cat = catcodetables
cat['latex'] = cat.CatcodeTableLaTeX
cat['latex-package'] = cat.CatcodeTableLaTeXAtLetter
cat['latex-atletter'] = cat.CatcodeTableLaTeXAtLetter
@@ -480,19 +508,20 @@ end
%<testplain>\input luatexbase-cctb.sty
%<testlatex>\RequirePackage{luatexbase-cctb}
%<*testplain,testlatex>
-\newluatexcatcodetable\testcctb
-\directlua{assert(luatextra.catcodetables.testcctb)}
+\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
-\directlua{assert(luatextra.catcodetables.anothercctb)}
+\lua{assert(luatexbase.catcodetables.anothercctb)}
% \end{macrocode}
%
% Now, play a little bit with predefined tables.
@@ -503,9 +532,9 @@ end
\luatexcatcodetable\CatcodeTableLaTeX
\ifnum\catcode64=12 \else \ERROR \fi
%<testlatex>\documentclass{minimal}
-\directlua{%
+\lua{%
tex.sprint('\string\\setbox0=\string\\hbox{')
- tex.sprint(luatextra.catcodetables.string, "\string\\undef # _^&")
+ tex.sprint(luatexbase.catcodetables.string, "\string\\undef # _^&")
tex.sprint('}')
}
% \end{macrocode}
diff --git a/luatexbase-compat.dtx b/luatexbase-compat.dtx
new file mode 100644
index 0000000..e1b6381
--- /dev/null
+++ b/luatexbase-compat.dtx
@@ -0,0 +1,410 @@
+% \iffalse meta-comment
+%
+% Written in 2010 by Manuel Pégourié-Gonnard.
+% <mpg@elzevir.fr>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatexbase-compat.dtx
+% and the derived files
+% luatexbase-compat.pdf luatexbase-compat.sty
+% test-compat-plain.tex test-compat-latex.tex
+%
+% Unpacking:
+% tex luatexbase-compat.dtx
+% Documentation:
+% pdflatex luatexbase-compat.dtx
+%
+% The class ltxdoc loads the configuration file ltxdoc.cfg
+% if available. Here you can specify further options, e.g.
+% use A4 as paper format:
+% \PassOptionsToClass{a4paper}{article}
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+
+Written in 2010 by Manuel Pegourie-Gonnard.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-compat.sty}{\from{luatexbase-compat.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatexbase}%
+ \file{test-compat-plain.tex}{\from{luatexbase-compat.dtx}{testplain}}%
+ \file{test-compat-latex.tex}{\from{luatexbase-compat.dtx}{testlatex}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luatexbase-compat.sty}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\documentclass{ltxdoc}
+\input lltxb-dtxstyle.tex
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{luatexbase-compat.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \title{The \pk{luatexbase-compat} package}
+% \date{2010/01/21 v0.1}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The \luatex manual is very clear: everything may change. This package
+% provides tools to help package writers deal with the changes. It helps
+% supporting \luatex versions down to 0.25.4, and is regularly tested with
+% \luatex 0.40.6 (\texlive 2009) and from trunk.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% Three problems are currently addressed by this package: changes in the
+% syntax of |\directlua|, version information, and variable policies for
+% primitives activation and naming (in \luatex itself as well as in \texlive).
+%
+% \medskip
+%
+% Older versions of \luatex used to support multiple Lua states. A number was
+% mandatory with |\directlua| in order to specify the Lua state to be used.
+% Later, support for multiple Lua states was removed and the old syntax
+% resulted in a warning. Now (\luatex 0.50), |\directlua| again accepts a
+% number after |\directlua|, but with a different meaning (see the \luatex
+% manual for details).
+%
+% This package provides a macro |\luatexbase@directlua| that expands to
+% |\directlua0| on \luatex 0.35 and lower (where the number is mandatory), and
+% to |\directlua| otherwise. It is a macro in both case so that the number of
+% expansion steps remains constant.
+%
+% \medskip
+%
+% Current versions of \luatex make the version available directly from Lua as
+% |tex.luatexversion| and |tex.luatexrevision|. However, older versions (such
+% as 0.25.4) didn't, which makes it particularly uneasy to test the version
+% from within Lua. The present package makes this information available as
+% |luatexbase.luatexversion| and |luatexbase.luatexrevision|.
+%
+% \medskip
+%
+% Starting with \luatex 0.39.0, the only primitives available in Ini\tex mode
+% are the basic primitives from \tex{}82 and |\directlua|. All other
+% primitives are hidden by default and have to be activated using a Lua
+% function. In \texlive 2009 (\luatex 0.40.6), the following arrangement has
+% been made in order to try preserving usability while avoiding name clashes
+% in the \latex world: in \latex-based formats, all pdf\tex primitives are
+% enabled with their normal name, but the primitives specific to \luatex are
+% enabled with the |luatex| prefix.\footnote{The prefix is dropped for
+% primitives whose name already starts with \texttt{luatex}.} In Plain based
+% formats however, all the primitives are enabled with their natural name, but
+% are also provided with the same name as in \latex-based formats in order to
+% help writing generic packages.
+%
+% So, starting with \texlive 2009, the situation is clear: the prefixed
+% version of the \luatex primitives is always available. But in earlier
+% versions (\texlive 2008, \luatex 0.25.4) those primitives were available
+% only with their natural names. Also, it is theoretically possible, however
+% unlikely, that the prefixed primitives are not available for some reason.
+%
+% \begin{quote}
+% \cs{luatexbase@ensure@primitive}\marg{name}
+% \end{quote}
+% The tool provided to deal with that is \cs{luatexbase@ensure@primitive},
+% whose argument is a primitive name (without a leading backslash nor any
+% |luatex| prefix, eg just |{latelua}|). It makes sure that the primitive gets
+% available as \cs{luatex\meta{name}}.
+%
+% \textbf{Warning.} In particular circumstances, this macro may fail silently
+% for primitives whose natural name starts with |luatex|, hence such
+% primitives shouldn't be used as arguments. This is actually not a problem,
+% since the only three such primitives are |\luatexversion|, |\luatexrevision|
+% and |\luatexdatestamp|. The first two are already activated by \pk{ifluatex}
+% which is loaded by this package, so you don't need to activated them
+% yourself. The third should never be used in production according to the
+% \luatex manual.
+%
+% \textit{Remark.} If you only aim at compatibility down to \texlive 2009
+% (\luatex 0.40.6), then you can simply use the primitives with their prefixed
+% name (except for |\directlua| which never needs a prefix). If you want extra
+% security and/or compatibility down to \texlive 2008 (\luatex 0.25.4) then
+% you should use \cs{luatebase@ensure@primitive} for each primitive you intend
+% to use (except |\directlua| again).
+%
+% This package doesn't try to activate every primitive, since it would require
+% and extensive list of primitives for each version of \luatex, so it seems
+% simpler to leave that burden on package writers.
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsection{Preliminaries}
+%
+% Reload protection, especially for \plaintex.
+%
+% \begin{macrocode}
+ \csname lltxb@compat@loaded\endcsname
+\expandafter\let\csname lltxb@compat@loaded\endcsname\endinput
+% \end{macrocode}
+%
+% Catcode defenses.
+%
+% \begin{macrocode}
+\begingroup
+ \catcode123 1 % {
+ \catcode125 2 % }
+ \catcode 35 6 % #
+ \toks0{}%
+ \def\x{}%
+ \def\y#1 #2 {%
+ \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}%
+ \edef\x{\x \catcode#1 #2}}%
+ \y 123 1 % {
+ \y 125 2 % }
+ \y 35 6 % #
+ \y 10 12 % ^^J
+ \y 34 12 % "
+ \y 36 3 % $ $
+ \y 39 12 % '
+ \y 40 12 % (
+ \y 41 12 % )
+ \y 42 12 % *
+ \y 43 12 % +
+ \y 44 12 % ,
+ \y 45 12 % -
+ \y 46 12 % .
+ \y 47 12 % /
+ \y 60 12 % <
+ \y 61 12 % =
+ \y 64 11 % @ (letter)
+ \y 62 12 % >
+ \y 95 12 % _ (other)
+ \y 96 12 % `
+ \edef\y#1{\endgroup\edef#1{\the\toks0\relax}\x}%
+\expandafter\y\csname lltxb@compat@AtEnd\endcsname
+% \end{macrocode}
+%
+% Package declaration.
+%
+% \begin{macrocode}
+\begingroup
+ \expandafter\ifx\csname ProvidesPackage\endcsname\relax
+ \def\x#1[#2]{\immediate\write16{Package: #1 #2}}
+ \else
+ \let\x\ProvidesPackage
+ \fi
+\expandafter\endgroup
+\x{luatexbase-compat}[2010/01/21 v0.1 Compatibility tools for LuaTeX]
+% \end{macrocode}
+%
+% Make sure \luatex is used.
+%
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+ \input ifluatex.sty
+\else
+ \RequirePackage{ifluatex}
+\fi
+\ifluatex\else
+ \begingroup
+ \expandafter\ifx\csname PackageWarningNoLine\endcsname\relax
+ \def\x#1#2{\begingroup\newlinechar10
+ \immediate\write16{Package #1 warning: #2}\endgroup}
+ \else
+ \let\x\PackageWarningNoLine
+ \fi
+ \expandafter\endgroup
+ \x{luatexbase-compat}{LuaTeX is required for this package. Aborting.}
+ \lltxb@compat@AtEnd
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsection{\cs{directlua} abstraction}
+%
+% Define |\luatexbase@directlua| to be either |\directlua0| or
+% |\directlua|, depending on the version of \luatex.
+%
+% \begin{macrocode}
+\begingroup
+\expandafter\ifx\csname newcommand\endcsname\relax
+ \toks0{\long\def\luatexbase@directlua}%
+\else
+ \toks0{\newcommand\luatexbase@directlua}%
+\fi
+\ifnum\luatexversion<36
+ \toks0\expandafter{\the\toks0{\directlua0}}%
+\else
+ \toks0\expandafter{\the\toks0{\directlua}}%
+\fi
+\expandafter\endgroup
+\the\toks0
+% \end{macrocode}
+%
+% \subsection{Version information}
+%
+% Make |\luatexversion| and |\luatexrevision| available from Lua.
+%
+% \begin{macrocode}
+\luatexbase@directlua{%
+ luatexbase = luatexbase or {}
+ luatexbase.luatexversion = \number\luatexversion\space
+ luatexbase.luatexrevision = \number\luatexrevision\space}
+% \end{macrocode}
+%
+% \subsection{Primitives}
+%
+% Try reasonably hard to activate a primitive. First, check if it is
+% already activated an do nothing in this case.
+%
+% \begin{macrocode}
+\begingroup
+\expandafter\ifx\csname newcommand\endcsname\relax
+ \toks0{\def\luatexbase@ensure@primitive#1}
+\else
+ \toks0{\newcommand*\luatexbase@ensure@primitive[1]}
+\fi
+\toks2{}\def\x#1{\toks2\expandafter{\the\toks2 #1}}
+\x{%
+ \ifcsname luatex#1\endcsname \else}
+\ifnum\luatexversion<37\relax
+% \end{macrocode}
+%
+% |tex.enableprimitives()| not available. If the unprefixed primitive is
+% undefined, issue an error.
+%
+% \begin{macrocode}
+ \x{%
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname #1\endcsname\relax}
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname PackageError\endcsname\relax
+ \x{%
+ \errmessage{%
+ Package luatexbase-compat error: failed to enable `#1'.}}
+ \else
+ \x{%
+ \PackageError{luatexbase-compat}{%
+ Package luatexbase-compat error: failed to enable `#1'.}{}}
+ \fi
+ \x{%
+ \else}
+% \end{macrocode}
+%
+% Use the unprefixed primitive to define the prefixed version.
+%
+% \begin{macrocode}
+ \x{%
+ \expandafter\let\csname luatex#1\expandafter\endcsname
+ \csname#1\endcsname
+ \fi}
+\else
+% \end{macrocode}
+%
+% |tex.enableprimitives()| available, use it.
+%
+% \begin{macrocode}
+ \x{%
+ \luatexbase@directlua{tex.enableprimitives('luatex', '#1')}}
+\fi
+\x{%
+ \fi}
+\toks0\expandafter{\the\toks0\expandafter{\the\toks2}}
+\expandafter\endgroup
+\the\toks0
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \begin{macrocode}
+\lltxb@compat@AtEnd
+%</texpackage>
+% \end{macrocode}
+%
+% \section{Test files}
+%
+% Test fils for Plain and LaTeX
+%
+% \begin{macrocode}
+%<testplain>\input luatexbase-compat.sty
+%<testlatex>\RequirePackage{luatexbase-compat}
+%<*testplain,testlatex>
+\catcode64 11
+\luatexbase@directlua{local answer = 42}
+\luatexbase@ensure@primitive{primitive}
+\luatexprimitive\relax
+\luatexbase@directlua{assert(type(luatexbase.luatexversion) == 'number')}
+\luatexbase@directlua{assert(type(luatexbase.luatexrevision) == 'number')}
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput
diff --git a/luatexbase-loader.dtx b/luatexbase-loader.dtx
index 695efe6..0a3945f 100644
--- a/luatexbase-loader.dtx
+++ b/luatexbase-loader.dtx
@@ -67,6 +67,9 @@ See source file '\inFileName' for details.
\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
@@ -122,10 +125,45 @@ See source file '\inFileName' for details.
% \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|.
+%
+% 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. 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}
@@ -190,7 +228,7 @@ See source file '\inFileName' for details.
\let\x\ProvidesPackage
\fi
\expandafter\endgroup
-\x{luatexbase-loader}[2010/03/26 v0.1 Lua module loader for LuaTeX (mpg)]
+\x{luatexbase-loader}[2010/03/26 v0.1 Lua module loader for LuaTeX]
% \end{macrocode}
%
% Make sure \luatex is used.
@@ -219,10 +257,23 @@ See source file '\inFileName' for details.
%
% \subsubsection{Main content}
%
-% Load the supporting Lua module.
+% 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}
-\directlua{%
+\luatexbase@directlua{%
local file = "luatexbase.loader.lua"
local path = assert(kpse.find_file(file, 'tex'),
"File '"..file.."' no found")
@@ -241,42 +292,130 @@ See source file '\inFileName' for details.
%
% \begin{macrocode}
%<*luamodule>
-module('luatextra', package.seeall)
+module('luatexbase', package.seeall)
+% \end{macrocode}
+%
+% Emulate (approximatively) kpse's lua format search.
+%
+% |lua_search_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.} except for the addition of the
+% empty string at the beginning (since this is what kpse does: first try
+% without adding a suffix).
+%
+% There is a problem with using the |tex| search format: kpse will try to
+% add suffixes from the |TEX_SUFFIXES| constant, which leads to problems
+% when a file \meta{name}|.tex| exists. We prevent that by checking the
+% extension of the file found.
+%
+% \begin{macrocode}
+local lua_search_suffixes = {
+ "", ".luc", ".luctex", ".texluc", ".lua", ".luatex", ".texlua",
+ }
+local lua_valid_suffixes = {
+ luc = true,
+ lua = true,
+ luctex = true,
+ texluc = true,
+ luatex = true,
+ texlua = true,
+}
+local function find_file_lua_emul(name)
+ for _, suf in ipairs(lua_search_suffixes) do
+ local name = name..suf
+ local f = kpse.find_file(name, 'texmfscripts')
+ or kpse.find_file(name, 'tex')
+ if suf == "" and f then
+ local ext = string.match(f,"^.+%.([^/\\]-)$")
+ if lua_valid_suffixes[suf] then
+ return f
+ end
+ elseif 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 = kpse.find_file(mod, 'lua')
+ local file = find_module_file(mod)
if not file then
- return "\n\t[luatextra.loader] Search failed"
+ 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[luatextra.loader] Loading error:\n\t"..error
+ 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}
-table.insert(package.loaders, load_module)
+package.loaders[2] = load_module
%</luamodule>
% \end{macrocode}
%
% \section{Test files}
%
-% 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
+% A dummy lua file for tests.
%
% \begin{macrocode}
-%<testplain>\input luatexbase-loader.sty
-%<testlatex>\RequirePackage{luatexbase-loader}
-%<*testplain,testlatex>
+%<*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
diff --git a/luamcallbacks.dtx b/luatexbase-mcb.dtx
index c2d94f9..11c2a44 100644
--- a/luamcallbacks.dtx
+++ b/luatexbase-mcb.dtx
@@ -1,18 +1,20 @@
% \iffalse meta-comment
%
-% Copyright (C) 2009 by Elie Roux <elie.roux@telecom-bretagne.eu>
+% 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 luamcallbacks.dtx
+% This work consists of the main source file luatexbase-mcb.dtx
% and the derived files
-% luamcallbacks.sty, luamcallbacks.tex, luamcallbacks.lua
-% test-luamcallbacks.tex, luamcallbacks.pdf.
+% luatexbase-mcb.sty, mcb.lua, luatexbase-mcb.pdf,
+% test-mcb-plain.tex test-mcb-latex.tex
%
% Unpacking:
-% tex luamcallbacks.dtx
+% tex luatexbase-mcb.dtx
% Documentation:
-% pdflatex luamcallbacks.dtx
+% pdflatex luatexbase-mcb.dtx
%
%<*ignore>
\begingroup
@@ -43,8 +45,14 @@ See source file '\inFileName' for details.
\let\MetaPrefix\DoubleperCent
\generate{%
+ \usedir{tex/luatex/luatexbase}%
+ \file{luatexbase-mcb.sty}{\from{luatexbase-mcb.dtx}{texpackage}}%
+}
+
+\generate{%
\usedir{doc/luatex/luatexbase}%
- \file{test-luamcallbacks.tex}{\from{luamcallbacks.dtx}{test}}%
+ \file{test-mcb-plain.tex}{\from{luatexbase-mcb.dtx}{testplain}}%
+ \file{test-mcb-latex.tex}{\from{luatexbase-mcb.dtx}{testlatex}}%
}
\def\MetaPrefix{-- }
@@ -58,7 +66,7 @@ See source file '\inFileName' for details.
\generate{%
\usedir{tex/luatex/luatexbase}%
- \file{luamcallbacks.lua}{\from{luamcallbacks.dtx}{lua}}%
+ \file{mcb.lua}{\from{luatexbase-mcb.dtx}{lua}}%
}
\obeyspaces
@@ -67,7 +75,7 @@ See source file '\inFileName' for details.
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
-\Msg{* luamcallbacks.lua}
+\Msg{* luatexbase-mcb.sty mcb.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
@@ -82,7 +90,7 @@ See source file '\inFileName' for details.
\documentclass{ltxdoc}
\input{lltxb-dtxstyle}
\begin{document}
- \DocInput{luamcallbacks.dtx}%
+ \DocInput{luatexbase-mcb.dtx}%
\end{document}
%</driver>
% \fi
@@ -105,11 +113,11 @@ See source file '\inFileName' for details.
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
-% \GetFileInfo{luamcallbacks.drv}
-%
-% \title{The \textsf{luamcallbacks} package}
+% \title{The \textsf{luatexbase-mcb} package}
% \date{2009/09/18 v0.93}
-% \author{Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \\ \email{mpg@elzevir.fr} \and
+% \'Elie Roux \\ \email{elie.roux@telecom-bretagne.eu}}
%
% \maketitle
%
@@ -123,6 +131,8 @@ See source file '\inFileName' for details.
% has been previously loaded. (This is a temporary limitation.)
% \end{abstract}
%
+% \tableofcontents
+%
% \section{Documentation}
%
% Lua\TeX\ provides an extremely interesting feature, named callbacks. It
@@ -150,11 +160,7 @@ See source file '\inFileName' for details.
% This package also privides a way to create and call new callbacks, in
% addition to the default Lua\TeX\ callbacks.
%
-% This package contains only a \texttt{.lua} file, that can be called by
-% another lua script. For example, this script is called in
-% \textsf{luatextra}.
-%
-%\subsubsection*{Limitations}
+% \subsubsection*{Limitations}
%
% This package only works for callbacks where it's safe to add multiple
% functions without changing the functions' signatures. There are callbacks,
@@ -171,57 +177,171 @@ See source file '\inFileName' for details.
% \texttt{open\_read\_file}. There is though a solution for several packages
% to use these callbacks, see the implementation of \texttt{luatextra}.
%
-% \StopEventually{
-% }
+% \section{Implementation}
%
-% \section{Package code}
+% \subsection{\tex package}
%
-% \iffalse
-%<*lua>
-% \fi
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
%
-% The package contains \texttt{luamcallbacks.lua} with the new functions,
-% and an example of the use of luamcallbacks.
+% \subsubsection{Preliminaries}
%
-% First the \texttt{luamcallbacks} module is registered as a Lua\TeX\
-% module, with some informations.
+% Reload protection, especially for \plaintex.
%
% \begin{macrocode}
-
-luamcallbacks = { }
-
-luamcallbacks.module = {
+ \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/09/11 v0.93 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.93,
date = "2009/09/18",
- description = "Module to register several functions in a callback.",
- author = "Hans Hagen & Elie Roux",
- copyright = "Hans Hagen & Elie Roux",
+ 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",
-}
-
-luatextra.provides_module(luamcallbacks.module)
-
+})
% \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}
-
-luamcallbacks.callbacklist = luamcallbacks.callbacklist or { }
-
+local callbacklist = callbacklist or { }
% \end{macrocode}
%
% A table with the default functions of the created callbacks. See
-% \texttt{luamcallbacks.create} for further informations.
+% \texttt{create} for further informations.
%
% \begin{macrocode}
-
-luamcallbacks.lua_callbacks_defaults = { }
-
-local format = string.format
-
+local lua_callbacks_defaults = { }
% \end{macrocode}
%
% There are 4 types of callback:
@@ -236,117 +356,92 @@ local format = string.format
% \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}
-
-luamcallbacks.callbacktypes = luamcallbacks.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,
+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.
+% appeared, so we enable it. Test the version using the compat package for,
+% well, compatibility.
%
% \begin{macrocode}
-
-if tex.luatexversion > 42 then
- luamcallbacks.callbacktypes["process_output_buffer"] = data
+if luatexbase.luatexversion > 42 then
+ callbacktypes["process_output_buffer"] = data
end
-
% \end{macrocode}
%
% As we overwrite \texttt{callback.register}, we save it as
-% \texttt{luamcallbacks.internalregister}. After that we declare some
-% functions to write the errors or the logs.
+% \texttt{internalregister}.
%
% \begin{macrocode}
-
-luamcallbacks.internalregister = luamcallbacks.internalregister or callback.register
-
-local callbacktypes = luamcallbacks.callbacktypes
-
-luamcallbacks.log = luamcallbacks.log or function(...)
- luatextra.module_log('luamcallbacks', format(...))
-end
-
-luamcallbacks.info = luamcallbacks.info or function(...)
- luatextra.module_info('luamcallbacks', format(...))
-end
-
-luamcallbacks.warning = luamcallbacks.warning or function(...)
- luatextra.module_warning('luamcallbacks', format(...))
-end
-
-luamcallbacks.error = luamcallbacks.error or function(...)
- luatextra.module_error('luamcallbacks', format(...))
-end
-
+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}
-
-function luamcallbacks.str_to_type(str)
+local function str_to_type(str)
if str == 'list' then
return list
elseif str == 'data' then
@@ -359,94 +454,97 @@ function luamcallbacks.str_to_type(str)
return nil
end
end
-
% \end{macrocode}
%
-% \begin{macro}{luamcallbacks.create}
-%
-% 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.
+% 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}
-
-function luamcallbacks.create(name, ctype, default)
- if not name then
- luamcallbacks.error(format("unable to call callback, no proper name passed", name))
- return nil
- end
- if not ctype or not default then
- luamcallbacks.error(format("unable to create callback '%s', callbacktype or default function not specified", name))
- return nil
- end
- if callbacktypes[name] then
- luamcallbacks.error(format("unable to create callback '%s', callback already exists", name))
- return nil
- end
- local temp = luamcallbacks.str_to_type(ctype)
- if not temp then
- luamcallbacks.error(format("unable to create callback '%s', type '%s' undefined", name, ctype))
- return nil
+-- 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
- ctype = temp
- luamcallbacks.lua_callbacks_defaults[name] = default
- callbacktypes[name] = ctype
end
-
% \end{macrocode}
%
-% \end{macro}
+% The handler for callbacks taking datas and returning modified ones.
%
-% \begin{macro}{luamcallbacks.call}
+% \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 calls a callback. It can only call a callback created by
-% the \texttt{create} function.
+% 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}
-
-function luamcallbacks.call(name, ...)
- if not name then
- luamcallbacks.error(format("unable to call callback, no proper name passed", name))
- return nil
- end
- if not luamcallbacks.lua_callbacks_defaults[name] then
- luamcallbacks.error(format("unable to call lua callback '%s', unknown callback", name))
- return nil
- end
- local l = luamcallbacks.callbacklist[name]
- local f
- if not l then
- f = luamcallbacks.lua_callbacks_defaults[name]
- else
- if callbacktypes[name] == list then
- f = luamcallbacks.listhandler(name)
- elseif callbacktypes[name] == data then
- f = luamcallbacks.datahandler(name)
- elseif callbacktypes[name] == simple then
- f = luamcallbacks.simplehandler(name)
- elseif callbacktypes[name] == first then
- f = luamcallbacks.firsthandler(name)
+local function firsthandler (name)
+ return function(...)
+ local l = callbacklist[name]
+ if l then
+ local f = l[1].func
+ return f(...)
else
- luamcallbacks.error("unknown callback type")
+ return nil, false
end
end
- return f(...)
end
-
% \end{macrocode}
%
-% \end{macro}
+% 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}
%
-% \begin{macro}{luamcallbacks.add}
+% \subsubsection{Public functions}
%
-% The main function. The signature is \texttt{luamcallbacks.add (name,
+% 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
@@ -454,7 +552,7 @@ end
% priority the function will have.
%
% The functions for a callbacks are added in a list (in
-% \texttt{luamcallbacks.callbacklist\\.callbackname}). If they have no
+% \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
@@ -463,50 +561,45 @@ end
% 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 themself. Most of the time, the priority is not needed.
+% to their function themselves. Most of the time, the priority is not needed.
%
% \begin{macrocode}
-
-function luamcallbacks.add (name,func,description,priority)
+function add_to_callback (name,func,description,priority)
if type(func) ~= "function" then
- luamcallbacks.error("unable to add function, no proper function passed")
+ err("unable to add function, no proper function passed")
return
end
if not name or name == "" then
- luamcallbacks.error("unable to add function, no proper callback name passed")
+ err("unable to add function, no proper callback name passed")
return
elseif not callbacktypes[name] then
- luamcallbacks.error(
- format("unable to add function, '%s' is not a valid callback",
- name))
+ err("unable to add function, '%s' is not a valid callback", name)
return
end
if not description or description == "" then
- luamcallbacks.error(
- format("unable to add function to '%s', no proper description passed",
- name))
+ err("unable to add function to '%s', no proper description passed",
+ name)
return
end
- if luamcallbacks.get_priority(name, description) ~= 0 then
- luamcallbacks.warning(
- format("function '%s' already registered in callback '%s'",
- description, name))
+ if priority_in_callback(name, description) ~= 0 then
+ warning("function '%s' already registered in callback '%s'",
+ description, name)
end
- local l = luamcallbacks.callbacklist[name]
+ local l = callbacklist[name]
if not l then
l = {}
- luamcallbacks.callbacklist[name] = l
- if not luamcallbacks.lua_callbacks_defaults[name] then
+ callbacklist[name] = l
+ if not lua_callbacks_defaults[name] then
if callbacktypes[name] == list then
- luamcallbacks.internalregister(name, luamcallbacks.listhandler(name))
+ internalregister(name, listhandler(name))
elseif callbacktypes[name] == data then
- luamcallbacks.internalregister(name, luamcallbacks.datahandler(name))
+ internalregister(name, datahandler(name))
elseif callbacktypes[name] == simple then
- luamcallbacks.internalregister(name, luamcallbacks.simplehandler(name))
+ internalregister(name, simplehandler(name))
elseif callbacktypes[name] == first then
- luamcallbacks.internalregister(name, luamcallbacks.firsthandler(name))
+ internalregister(name, firsthandler(name))
else
- luamcallbacks.error("unknown callback type")
+ err("unknown callback type")
end
end
end
@@ -521,320 +614,224 @@ function luamcallbacks.add (name,func,description,priority)
priority = 1
end
if callbacktypes[name] == first and (priority ~= 1 or #l ~= 0) then
- luamcallbacks.warning(format("several callbacks registered in callback '%s', only the first function will be active.", name))
+ warning("several callbacks registered in callback '%s', "
+ .."only the first function will be active.", name)
end
table.insert(l,priority,f)
- luamcallbacks.log(
- format("inserting function '%s' at position %s in callback list for '%s'",
- description,priority,name))
-end
-
-% \end{macrocode}
-%
-% \end{macro}
-%
-% \begin{macro}{luamcallbacks.get priority}
-%
-% 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 luamcallbacks.get_priority (name, description)
- if not name or name == "" or not callbacktypes[name] or not description then
- return 0
- end
- local l = luamcallbacks.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
+ log("inserting function '%s' at position %s in callback list for '%s'",
+ description, priority, name)
end
-
% \end{macrocode}
%
-% \end{macro}
-%
-% \begin{macro}{luamcallbacks.remove}
-%
% The function that removes a function from a callback. The signature is
-% \texttt{mcallbacks.remove (name, description)} with \texttt{name} being
+% \texttt{remove (name, description)} with \texttt{name} being
% the name of callbacks, and description the description passed to
-% \texttt{mcallbacks.add}.
+% \texttt{add}.
%
% \begin{macrocode}
-
-function luamcallbacks.remove (name, description)
+function remove_from_callback (name, description)
if not name or name == "" then
- luamcallbacks.error("unable to remove function, no proper callback name passed")
+ err("unable to remove function, no proper callback name passed")
return
elseif not callbacktypes[name] then
- luamcallbacks.error(
- format("unable to remove function, '%s' is not a valid callback",
- name))
+ err("unable to remove function, '%s' is not a valid callback", name)
return
end
if not description or description == "" then
- luamcallbacks.error(
- format("unable to remove function from '%s', no proper description passed",
- name))
+ err(
+ "unable to remove function from '%s', no proper description passed",
+ name)
return
end
- local l = luamcallbacks.callbacklist[name]
+ local l = callbacklist[name]
if not l then
- luamcallbacks.error(format("no callback list for '%s'",name))
+ 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)
- luamcallbacks.log(
- format("removing function '%s' from '%s'",description,name))
+ log("removing function '%s' from '%s'",description,name)
if not next(l) then
- luamcallbacks.callbacklist[name] = nil
- if not luamcallbacks.lua_callbacks_defaults[name] then
- luamcallbacks.internalregister(name, nil)
+ callbacklist[name] = nil
+ if not lua_callbacks_defaults[name] then
+ internalregister(name, nil)
end
end
return
end
end
- luamcallbacks.warning(
- format("unable to remove function '%s' from '%s'",description,name))
+ warning("unable to remove function '%s' from '%s'",description,name)
end
-
% \end{macrocode}
%
-% \end{macro}
-%
-% \begin{macro}{luamcallbacks.reset}
-%
% This function removes all the functions registered in a callback.
%
% \begin{macrocode}
-
-function luamcallbacks.reset (name)
+function reset_callback (name)
if not name or name == "" then
- luamcallbacks.error("unable to reset, no proper callback name passed")
+ err("unable to reset, no proper callback name passed")
return
elseif not callbacktypes[name] then
- luamcallbacks.error(
- format("reset error, '%s' is not a valid callback",
- name))
+ err("reset error, '%s' is not a valid callback", name)
return
end
- if not luamcallbacks.lua_callbacks_defaults[name] then
- luamcallbacks.internalregister(name, nil)
+ if not lua_callbacks_defaults[name] then
+ internalregister(name, nil)
end
- local l = luamcallbacks.callbacklist[name]
+ local l = callbacklist[name]
if l then
- luamcallbacks.log(format("resetting callback list '%s'",name))
- luamcallbacks.callbacklist[name] = nil
+ log("resetting callback list '%s'",name)
+ callbacklist[name] = nil
end
end
-
% \end{macrocode}
%
-% \end{macro}
-%
-% 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.
+% 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.
%
-% \begin{macro}{luamcallbacks.listhandler}
+% 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 luamcallbacks.listhandler (name)
- return function(head,...)
- local l = luamcallbacks.callbacklist[name]
- if l then
- local done = true
- for _, f in ipairs(l) do
- -- the returned value can be 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
- luamcallbacks.error(format(
- "function \"%s\" returned false in callback '%s'",
- f.description, name))
- end
- end
- return head, done
- else
- return head, false
- end
+function create_callback(name, ctype, default)
+ if not name then
+ err("unable to call callback, no proper name passed", name)
+ return nil
end
-end
-
-% \end{macrocode}
-%
-% \end{macro}
-%
-% The handler for callbacks taking datas and returning modified ones.
-%
-% \begin{macro}{luamcallbacks.datahandler}
-%
-% \begin{macrocode}
-
-function luamcallbacks.datahandler (name)
- return function(data,...)
- local l = luamcallbacks.callbacklist[name]
- if l then
- for _, f in ipairs(l) do
- data = f.func(data,...)
- end
- end
- return data
+ 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}
%
-% \end{macro}
-%
-% 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{macro}{luamcallbacks.firsthandler}
+% This function calls a callback. It can only call a callback created by
+% the \texttt{create} function.
%
% \begin{macrocode}
-
-function luamcallbacks.firsthandler (name)
- return function(...)
- local l = luamcallbacks.callbacklist[name]
- if l then
- local f = l[1].func
- return f(...)
+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
- return nil, false
+ err("unknown callback type")
end
end
+ return f(...)
end
-
% \end{macrocode}
%
-% \end{macro}
-%
-% Handler for simple functions that don't return anything.
-%
-% \begin{macro}{luamcallbacks.simplehandler}
+% 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 luamcallbacks.simplehandler (name)
- return function(...)
- local l = luamcallbacks.callbacklist[name]
- if l then
- for _, f in ipairs(l) do
- f.func(...)
- end
+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}
%
-% \end{macro}
-%
-% Finally we add some functions to the \texttt{callback} module, and we
+% Finally we
% overwrite \texttt{callback.register} so that it outputs an error.
%
% \begin{macrocode}
-
-callback.add = luamcallbacks.add
-callback.remove = luamcallbacks.remove
-callback.reset = luamcallbacks.reset
-callback.create = luamcallbacks.create
-callback.call = luamcallbacks.call
-callback.get_priority = luamcallbacks.get_priority
-
-callback.register = function (...)
-luamcallbacks.error("function callback.register has been deleted by luamcallbacks, please use callback.add instead.")
+callback.register = function ()
+err("function callback.register has been deleted by luamcallbacks, "
+.."please use callback.add instead.")
end
-
% \end{macrocode}
%
-% \iffalse
-%</lua>
-% \fi
-%
-% \iffalse
-%<*test>
-% \fi
-%
-% \section{Test file}
-%
-% The test file is made to run in plainTeX, but is trivial to adapt for
-% LaTeX. First we input the package, and we typeset a small sentence to
-% get a non-empty document.
-%
-% \begin{macrocode}
-\input luatexbase-loader.sty
-\input luatexbase-modutils.sty
-\directlua{require "luamcallbacks"}
-This is just a test file.
-% \end{macrocode}
-%
-% Then we declare three functions that we will use.
-%
-% \begin{macrocode}
-\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
-% \end{macrocode}
-%
-% Then we add the three functions to the hpack\_filter callback
+% That's all folks!
%
% \begin{macrocode}
-callback.add("hpack_filter",one,"my example function one",1)
-callback.add("hpack_filter",two,"my example function two",2)
-callback.add("hpack_filter",three,"my example function three",1)
+%</lua>
% \end{macrocode}
%
-% We remove the function three from the callback.
+% \section{Test files}
%
-% \begin{macrocode}
-callback.remove("hpack_filter","my example function three")
-% \end{macrocode}
-%
-% And we remove a non-declared function to the callback, which will
-% generate an error.
+% 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")
}
-
-\bye
+%</testplain,testlatex>
+%<testplain>\bye
+%<testlatex>\stop
% \end{macrocode}
-% \iffalse
-%</test>
-% \fi
+%
% \Finale
\endinput
diff --git a/luatexbase-modutils.dtx b/luatexbase-modutils.dtx
index bd84dc7..4a08c4c 100644
--- a/luatexbase-modutils.dtx
+++ b/luatexbase-modutils.dtx
@@ -66,7 +66,7 @@ See source file '\inFileName' for details.
\generate{%
\usedir{tex/luatex/luatexbase}%
- \file{luatexbase.modutils.lua}{\from{luatexbase-modutils.dtx}{luamodule}}%
+ \file{modutils.lua}{\from{luatexbase-modutils.dtx}{luamodule}}%
\usedir{doc/luatex/luatexbase}%
\file{test-modutils.lua}{\from{luatexbase-modutils.dtx}{testdummy}}%
}
@@ -77,7 +77,7 @@ See source file '\inFileName' for details.
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
-\Msg{* luatexbase-modutils.sty luatexbase.modutils.lua}
+\Msg{* luatexbase-modutils.sty modutils.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
@@ -126,6 +126,8 @@ See source file '\inFileName' for details.
% \begin{abstract}
% \end{abstract}
%
+% \tableofcontents
+%
% \section{Documentation}
%
% Lua has some embedded module management, with the functions \texttt{module}
@@ -135,8 +137,8 @@ See source file '\inFileName' for details.
% \texttt{\string\luatexUseModule} and \texttt{\string\luatexRequireModule}
% that act like them, but for lua files. The functions \texttt{module} and
% \texttt{require} should not be used, in profit of the lua functions
-% \texttt{luatextra.provides\_module} and \texttt{luatextra.use\_module} or
-% \texttt{luatextra.require\_module}.
+% \texttt{luatexbase.provides\_module} and \texttt{luatexbase.use\_module} or
+% \texttt{luatexbase.require\_module}.
%
% \section{Implementation}
%
@@ -202,7 +204,7 @@ See source file '\inFileName' for details.
\let\x\ProvidesPackage
\fi
\expandafter\endgroup
-\x{luatexbase-modutils}[2010/03/26 v0.1 Module utilities for LuaTeX (mpg)]
+\x{luatexbase-modutils}[2010/03/26 v0.1 Module utilities for LuaTeX]
% \end{macrocode}
%
% Make sure \luatex is used.
@@ -229,7 +231,8 @@ See source file '\inFileName' for details.
\fi
% \end{macrocode}
%
-% Load the package loader.
+% Load \pk{luatexbase-loader} (hence \pk{luatexbase-compat}) and require
+% supporting Lua module.
%
% \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
@@ -238,37 +241,22 @@ See source file '\inFileName' for details.
\else
\RequirePackage{luatexbase-loader}
\fi
+\luatexbase@directlua{require('luatexbase.modutils')}
% \end{macrocode}
%
-% \subsubsection{Main code}
-%
-% The \texttt{\string\luatexModuleError} macro is called by the lua function
-% \texttt{luatextra.module\_error}. It is necessary because we can't call
-% directly \texttt{\string\errmessage} in lua.
-%
-% \begin{macrocode}
-
-\def\luatexModuleError#1#2{%
- \errorcontextlines=0\relax
- \immediate\write16{}%
- \errmessage{Module #1 error: #2^^J^^J%
-See the module #1 documentation for explanation.^^J ...^^J}%
-}
-
-% \end{macrocode}
+% \subsubsection{User macros}
%
% Then we define
% \texttt{\string\luatexUseModule} that simply calls
-% \texttt{luatextra.use\_module}.
+% \texttt{luatexbase.use\_module}.
% If the package is loaded with Plain, we define
% \texttt{\string\luaRequireModule} with two mandatory arguments.
%
% \begin{macrocode}
-\def\luatexUseModule#1{\directlua{luatextra.use_module([[#1]])}}
-
+\def\luatexUseModule#1{\luatexbase@directlua{luatexbase.use_module([[#1]])}}
\expandafter\ifx\csname ProvidesPackage\endcsname\relax
- \def\luatexRequireModule#1#2{\directlua{%
- luatextra.require_module([[#1]], [[#2]])}}
+ \def\luatexRequireModule#1#2{\luatexbase@directlua{%
+ luatexbase.require_module([[#1]], [[#2]])}}
\else
% \end{macrocode}
%
@@ -278,12 +266,12 @@ See the module #1 documentation for explanation.^^J ...^^J}%
% date).
%
% \begin{macrocode}
- \newcommand\luatexRequireModule[2][0]{\directlua{luatextra.require_module([[#2]], [[#1]])}}
+ \newcommand\luatexRequireModule[2][0]{%
+ \luatexbase@directlua{luatexbase.require_module([[#2]], [[#1]])}}
\fi
% \end{macrocode}
%
% \begin{macrocode}
-\directlua{dofile(assert(kpse.find_file('luatexbase.modutils.lua', 'tex')))}
% \end{macrocode}
%
% \begin{macrocode}
@@ -295,37 +283,13 @@ See the module #1 documentation for explanation.^^J ...^^J}%
%
% \begin{macrocode}
%<*luamodule>
+module("luatexbase", package.seeall)
% \end{macrocode}
%
% Initialisation borrowed from luatextra
%
% \begin{macrocode}
-module("luatextra", package.seeall)
-
-local format = string.format
-
-luatextra.modules = luatextra.modules or {}
-% \end{macrocode}
-%
-% Here we define the warning and error functions specific to
-% \texttt{luatextra}.
-%
-% \begin{macrocode}
-
-luatextra.internal_warning_spaces = " "
-
-function luatextra.internal_warning(msg)
- if not msg then return end
- texio.write_nl(format("\nLuaTeXtra Warning: %s\n\n", msg))
-end
-
-luatextra.internal_error_spaces = " "
-
-function luatextra.internal_error(msg)
- if not msg then return end
- tex.sprint(format("\\immediate\\write16{}\\errmessage{LuaTeXtra error: %s^^J^^J}", msg))
-end
-
+local modules = modules or {}
% \end{macrocode}
%
% \subsubsection{Error, warning and info function for modules}
@@ -337,153 +301,115 @@ end
% to be used by lua module writers.
%
% \begin{macrocode}
-
-function luatextra.module_error(package, msg, helpmsg)
- if not package or not msg then
- return
- end
- if helpmsg then
- tex.sprint(format("\\errhelp{%s}", helpmsg))
- end
- tex.sprint(format("\\luatexModuleError{%s}{%s}", package, msg))
+local function module_error_int(mod, ...)
+ error('Module '..mod..' error: '..string.format(...), 3)
end
-
-function luatextra.module_warning(modulename, msg)
- if not modulename or not msg then
- return
- end
- texio.write_nl(format("\nModule %s Warning: %s\n\n", modulename, msg))
+function module_error(mod, ...)
+ module_error_int(mod, ...)
end
-
-function luatextra.module_log(modulename, msg)
- if not modulename or not msg then
- return
- end
- texio.write_nl('log', format("%s: %s", modulename, msg))
+function module_warning(mod, ...)
+ texio.write_nl("Module "..mod.." warning: "..string.format(...))
end
-
-function luatextra.module_term(modulename, msg)
- if not modulename or not msg then
- return
- end
- texio.write_nl('term', format("%s: %s", modulename, msg))
+function module_info(mod, ...)
+ texio.write_nl(mod..": "..string.format(...))
end
-
-function luatextra.module_info(modulename, msg)
- if not modulename or not msg then
- return
- end
- texio.write_nl(format("%s: %s\n", modulename, msg))
+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}
%
-% \subsubsection{module loading and providing functions}
-%
-% A small patch, for the \texttt{module} function to work in this file. I
-% can't understand why it doens't otherwise.
+% For our own convenience, local functions for warning and errors in this
+% module.
%
% \begin{macrocode}
-
-luatextra.module = module
-
+local function err(...) module_error_int('luatexbase.modutils', ...) end
+local function warn(...) module_warning('luatexbase.modutils', ...) end
% \end{macrocode}
%
-% \begin{macro}{luatextra.use module}
+% \subsubsection{module loading and providing functions}
%
% This macro is the one used to simply load a lua module file. It does not
% reload it if it's already loaded, and prints the filename in the terminal
% and the log. A lua module must call the macro
-% \texttt{luatextra.provides\_module}.
+% \texttt{provides\_module}.
%
% \begin{macrocode}
-function luatextra.use_module(name)
- if not name or luatextra.modules[name] then
+function use_module(name)
+ if not name or modules[name] then
return
end
require(name)
- if not luatextra.modules[name] then
- luatextra.internal_warning(format("You have requested module `%s',\n%s but the file %s does not provide it.", name, luatextra.internal_warning_spaces))
- end
- if not package.loaded[name] then
- luatextra.module(name, package.seeall)
+ if not modules[name] then
+ warn("You have requested module `%s', "
+ .."but no file seems to provide it.", name)
end
end
% \end{macrocode}
%
-% \end{macro}
-%
% Some internal functions to convert a date into a number, and to determine
% if a string is a date. It is useful for
-% \texttt{luatextra.require\_package} to understand if a user asks a
+% \texttt{require\_package} to understand if a user asks a
% version with a date or a version number.
%
% \begin{macrocode}
-
-function luatextra.datetonumber(date)
+local function datetonumber(date)
numbers = string.gsub(date, "(%d+)/(%d+)/(%d+)", "%1%2%3")
return tonumber(numbers)
end
-
-function luatextra.isdate(date)
+local function isdate(date)
for _, _ in string.gmatch(date, "%d+/%d+/%d+") do
return true
end
return false
end
-
local date, number = 1, 2
-
-function luatextra.versiontonumber(version)
- if luatextra.isdate(version) then
- return {type = date, version = luatextra.datetonumber(version), orig = version}
+local function versiontonumber(version)
+ if isdate(version) then
+ return {type = date, version = datetonumber(version), orig = version}
else
return {type = number, version = tonumber(version), orig = version}
end
end
-
-luatextra.requiredversions = {}
-
+local requiredversions = {}
% \end{macrocode}
%
-% \begin{macro}{luatextra.require module}
-%
-% This function is like the \texttt{luatextra.use\_module} function, but
+% This function is like the \texttt{use\_module} function, but
% can accept a second argument that checks for the version of the module.
% The version can be a number or a date (format yyyy/mm/dd).
%
% \begin{macrocode}
-
-function luatextra.require_module(name, version)
+function require_module(name, version)
if not name then
return
end
if not version then
- return luatextra.use_module(name)
+ return use_module(name)
end
- luaversion = luatextra.versiontonumber(version)
- if luatextra.modules[name] then
+ luaversion = versiontonumber(version)
+ if modules[name] then
if luaversion.type == date then
- if luatextra.datetonumber(luatextra.modules[name].date) < luaversion.version then
- luatextra.internal_error(format("found module `%s' loaded in version %s, but version %s was required", name, luatextra.modules[name].date, version))
+ 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 luatextra.modules[name].version < luaversion.version then
- luatextra.internal_error(format("found module `%s' loaded in version %.02f, but version %s was required", name, luatextra.modules[name].version, version))
+ 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
- luatextra.requiredversions[name] = luaversion
- luatextra.use_module(name)
+ requiredversions[name] = luaversion
+ use_module(name)
end
end
-
% \end{macrocode}
%
-% \end{macro}
-%
-% \begin{macro}{luatextra.provides module}
-%
% This macro is the one that must be called in the module files. It takes a
% table as argument. You can put any information you want in this table,
% but the mandatory ones are \texttt{name} (a string), \texttt{version} (a
@@ -495,32 +421,37 @@ end
% does for informations about packages.
%
% \begin{macrocode}
-
-function luatextra.provides_module(mod)
+function provides_module(mod)
if not mod then
- luatextra.internal_error('cannot provide nil module')
+ err('cannot provide nil module')
return
end
- if not mod.version or not mod.name or not mod.date or not mod.description then
- luatextra.internal_error('invalid module registered, fields name, version, date and description are mandatory')
+ 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 = luatextra.requiredversions[mod.name]
+ requiredversion = requiredversions[mod.name]
if requiredversion then
- if requiredversion.type == date and requiredversion.version > luatextra.datetonumber(mod.date) then
- luatextra.internal_error(format("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
- luatextra.internal_error(format("loading module %s in version %.02f, but version %s was required", mod.name, mod.version, requiredversion.orig))
+ 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
- luatextra.modules[mod.name] = module
- texio.write_nl('log', format("Lua module: %s %s v%.02f %s\n", mod.name, mod.date, mod.version, mod.description))
+ 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}
%
-% \end{macro}
-%
% \begin{macrocode}
%</luamodule>
% \end{macrocode}
@@ -531,7 +462,7 @@ end
%
% \begin{macrocode}
%<*testdummy>
-luatextra.provides_module {
+luatexbase.provides_module {
name = 'test-modutils',
date = '2000/01/01',
version = 1,
diff --git a/luatexbase-regs.dtx b/luatexbase-regs.dtx
index 89c2313..5b0c648 100644
--- a/luatexbase-regs.dtx
+++ b/luatexbase-regs.dtx
@@ -117,6 +117,8 @@ See source file '\inFileName' for details.
% \luatex.
% \end{abstract}
%
+% \tableofcontents
+%
% \section{Documentation}
%
% Since the \plaintex and \latex formats are both frozen, they fail to take
@@ -147,8 +149,6 @@ See source file '\inFileName' for details.
% degraded performance due to implementation details, but with \luatex the
% performance is uniform, so we just do it.
%
-% \clearpage
-%
% \section{Implementation}
%
% \begin{macrocode}
@@ -211,7 +211,7 @@ See source file '\inFileName' for details.
\let\x\ProvidesPackage
\fi
\expandafter\endgroup
-\x{luatexbase-regs}[2010/01/21 v0.1 Registers allocation for LuaTeX (mpg)]
+\x{luatexbase-regs}[2010/01/21 v0.1 Registers allocation for LuaTeX]
% \end{macrocode}
%
% Make sure \luatex is used.
@@ -238,7 +238,7 @@ See source file '\inFileName' for details.
\fi
% \end{macrocode}
%
-% \subsection{Main content}
+% \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
@@ -272,6 +272,8 @@ See source file '\inFileName' for details.
\else
% \end{macrocode}
%
+% \subsection{Adapt range}
+%
% First, increase the upper bound for all kinds of registers. Copy code to
% avoid defining a macro.
%
@@ -286,6 +288,8 @@ See source file '\inFileName' for details.
\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
@@ -394,6 +398,8 @@ See source file '\inFileName' for details.
\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