ConTeXt and Lua programming/Module writing/Module namespaces
Contents
Naming Conventions
To avoid clashes with existing and future commands, any module should adhere to the following rules:
- Namespace identifiers (their ID) should have more than two characters,
- different from anything listed in Modules,
- only 7 bit ASCII, lowercase, without underscores (hyphens are allowed) – CTAN conventions.
Generating a Namespace for Your Module
See also Wolfgang’s talk from context meeting 2024!
ConTeXt provides the user command \installnamespace that generates a namespace for macros and variables and enables simple setups for advanced techniques (defining instances, parameter setup & handling).
Suppose you have a module called My Module (preferably in a file t-mymodule.tex) and want to reserve the namespace MyMod:
\installnamespace{MyMod} % defines \????MyMod, only accessible after … \unprotect % … up to \protect
Module factory
Depending on your needs, you can then use one or several of the “factory” macros that define the usual \define…
(instances), \setup…
etc. commands and parameter handling for you:
- \installframedcommandhandler (complete with inheritance from \setupframed)
- \installcommandhandler (complete with nearly everything below, without
framed
) - \installsimplecommandhandler (without
define
, but includingsetup
, style and color) - \installbasiccommandhandler (without
define
,setup
, style and color) - \installdefinehandler (
define
only) - \installsetuphandler (
setup
only) - \installparameterhandler (processing parameters)
- \installbasicparameterhandler
- \installrootparameterhandler
- \installparametersethandler (setting parameters)
- \installstyleandcolorhandler (style and color)
\installcommandhandler\????MyMod
creates
\defineMyMod[…][…][…=…‚]
= create a newMyMod
instance\currentMyMod
and\currentMyModparent
contain the names of the instance (or the parent of a copy)\everypresetMyMod
and\everydefineMyMod
can be used to apply additional settings
\setupMyMod[…][…=…,]
= change settings, first parameter can be the name of an instance\setupcurrentMyMod[…=…,]
to change a value within a command/environment\everysetupMyMod
and\everysetupMyModroot
can be used to apply additional settings
\MyModparameter{…}
to access single parameters\namedMyModparameter{…}
to access single parameters of a named instance\detokenizedMyModparameter{…}
,\directMyModparameter{…}
,\letfromMyModparameter\…{…}
\rootMyModparameter{…}
and\detokenizedrootMyModparameter{…}
only from \installrootparameterhandler
\useMyModstyleandcolor{…}{…}
,\useMyModstyleparameter{…}
,\useMyModcolorparameter{…}
to use with style and color keys of the internally used macros (from \installstyleandcolorhandler)\setMyModparameter{…}{…}
,\setexpandedMyModparameter{…}{…}
,\letMyModparameter\…{…}
,\resetMyModparameter{…}
to work with parameters (from \installparametersethandler)- finally
\startMyMod[…=…,] … \stopMyMod
and\MyMod[…=…,]
Through \setupMyMod you can now set the variables that you want to use in your module — it is already a mature command that conforms to the overall ConTeXt style and can take a parameter list, a list of key-value pairs or both as arguments.
Any parameter defined that way can now be retrieved via \MyModparameter{…}
.
\usemodule[MyMod] % setting a parameter within the namespace \setupMyMod[ yamp=Yet another module parameter, ] % command sequence that does something with the parameter \def\blueparameter{\color[blue]{\MyModparameter{yamp}}} % deploying the new user command \starttext \blueparameter \stoptext
or within the module:
\getparameters[\????MyMod][width=10dk]
- \getparameters is for setting parameters in a namespace.
Framed commands
If you want a new \framed command which takes its values from \setupMyMod
, use \installframedcommandhandler or single \installinheritedframed.
To avoid clashes with other MyMod settings, the namespace and command name should be different from the default one.
\installinheritedframed \????MyModFrame {MyModFrame}
… then you get additionally:
\currentMyModFrame
\MyModFrameparameter{…}
and\MyModFrameparameterhash{…}
\inheritedMyModFrameframed{…}
(like\framed
with custom settings)\inheritedMyModFrameframedbox{…} …
Local values
In some cases you want to accept values as assignments which are local to the command or environment. This can be done with the predefined \getdummyparameters.
The values can be retrieved with \dummyparameter{...}
\def\MyModText[#1]{#2}% {\begingroup \getdummyparameters[blabla=,#1]% \dummyparameter{blabla}: #2% \endgroup
Background information
Internally the namespaces are represented as ordinary command sequences with a prefix of 4 question marks.
Outside of the \unprotect … \protect
section, this is represented as something like \2DD>
which can’t be used in normal documents and ensures that no user can modify the values.
The internal representation of \getparameters[\????MyMod][width=10dk]
would be \def\2DD>width{10dk}
.