diff options
Diffstat (limited to 'doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex')
-rw-r--r-- | doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex | 259 |
1 files changed, 251 insertions, 8 deletions
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex index ee30683e8..f4dbfb15d 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex @@ -1110,6 +1110,13 @@ lead to less clutter in tracing. \stopsubsection +\startsubsection[title={\lpr {ifrelax}}] + +This primitive complements \type {\ifdefined}, \type {\ifempty} and \type +{\ifcsname} so that we have all reasonable tests directly available. + +\stopsubsection + \startsubsection[title={\lpr {ifboolean}}] This primitive tests for non|-|zero, so the next variants are similar @@ -1151,6 +1158,33 @@ one might evolve). \stopsubsection +\startsubsection[title={\lpr {ifarguments}, \lpr {ifparameters} and \lpr {ifparameter}}] + +These are part of the extended macro argument parsing features. The \type +{\ifarguments} condition is like an \type {\ifcase} where the number is the +picked up number of arguments. The number reflects the {\em last} count, so +successive macro expansions will adapt the value. The \type {\ifparameters} +counts till the first empty parameter and the \type {\ifparameter} (singular) +takes a parameter reference (like \type {#2}) and again is an \type {\ifcase} +where zero means a bad reference, one a non|-|empty argument and two an empty +one. A typical usage is: + +\starttyping +\def\foo#1#2% + {\ifparameter#1\or one\fi + \ifparameter#2\or two\fi} +\stoptyping + +No expansion of arguments takes place here but you can use a test like this: + +\starttyping +\def\foo#1#2% + {\iftok{#1}{}\else one\fi + \iftok{#2}{}\else two\fi} +\stoptyping + +\stopsubsection + \startsubsection[title={\lpr {ifcondition}}] \topicindex {conditions} @@ -1321,14 +1355,6 @@ dimensions are calculated. \stopsubsection -\topicindex {splitting} - -The \prm {vsplit} primitive has to be followed by a specification of the required -height. As alternative for the \type {to} keyword you can use \type {upto} to get -a split of the given size but result has the natural dimensions then. - -\stopsubsection - \startsubsection[title={\prm {vsplit}}] \topicindex {splitting} @@ -1931,6 +1957,223 @@ makes sense (for integers). \stopsection +\startsection[title=Macro arguments] + +Again this is experimental and (used and) discussed in document that come with the +\CONTEXT\ distribution. When defining a macro you can do this: + +\starttyping +\def\foo(#1)#2{...} +\stoptyping + +Here the first argument between parentheses is mandate. But the magic +prefix \lpr {tolerant} makes that limitation go away: + +\starttyping +\tolerant\def\foo(#1)#2{...} +\stoptyping + +A variant is this: + +\starttyping +\tolerant\def\foo(#1)#*(#2){...} +\stoptyping + +Here we have two optional arguments, possibly be separated by spaces. There are +more parsing options: + +\starttabulate[|T|i2l|] +\FL +\NC + \NC keep the braces \NC \NR +\NC - \NC discard and don't count the argument \NC \NR +\NC / \NC remove leading an trailing spaces and pars \NC \NR +\NC = \NC braces are mandate \NC \NR +\NC _ \NC braces are mandate and kept \NC \NR +\NC ^ \NC keep leading spaces \NC \NR +\ML +\NC 1-9 \NC an argument \NC \NR +\NC 0 \NC discard but count the argument \NC \NR +\ML +\NC * \NC ignore spaces \NC \NR +\NC : \NC pick up scanning here \NC \NR +\NC ; \NC quit scanning \NC \NR +\LL +\stoptabulate + +For the moment we leave it to your fantasy what these options do. Most probably +only make sense when you write a bit more complex macros. Just try to imagine +what this does: + +\starttyping +\permanent\tolerant\global\protected\def\foo(#1)#*#;[#2]#:#3{...} +\stoptyping + +Of course complex combinations can be confusing because after all \TEX\ is +parsing for (multi|-|token) delimiters and will happily gobble the whole file if +you are not careful. You can quit scanning if you want: + +\starttyping +\mymacro 123\ignorearguments +\stoptyping + +which of course only makes sense when used in a nested call where an already +picked up arguments is processed further. A not (yet) discussed feature of the +parser is that it will happily skip tokens that have the (probably seldom used) +ignored characters property. + +When you use tracing or see error messages arguments defined using for instance +\type {#=} will have their usual number in the macro body, so you need to keep +track of the numbers. + +All this is rather easy on the engine and although it might have a little impact +on performance this has been compensated by some more efficiency in the macro +parser and engine in general and of course you can gain back some by using these +features. + +\stopsection + +\startsection[title=Overload protection] + +There is an experimental overload protection mechanism that we will test for a +while before declaring it stable. The reason for that is that we need to adapt +the \CONTEXT\ code base in order to test its usefulness. Protection is achieved +via prefixes. Depending on the value of the \lpr {overloadmode} variable +warnings or errors will be triggered. Examples of usage can be found in some +documents that come with \CONTEXT, so here we just stick to the basics. + +\starttyping +\mutable \def\foo{...} +\immutable\def\foo{...} +\permanent\def\foo{...} +\frozen \def\foo{...} +\aliased \def\foo{...} +\stoptyping + +A \lpr {mutable} macro can always be changed contrary to an \lpr {immutable} one. +For instance a macro that acts as a variable is normally \lpr {mutable}, while a +constant can best be immutable. It makes sense to define a public core macro as +\lpr {permanent}. Primives start out a \lpr {permanent} ones but with a primitive +property instead. + +\startbuffer + \let\relaxone \relax 1: \meaningfull\relaxone +\aliased \let\relaxtwo \relax 2: \meaningfull\relaxtwo +\permanent\let\relaxthree\relax 3: \meaningfull\relaxthree +\stopbuffer + +\typebuffer + +The \lpr {meaningfull} primitive is like \prm {meaning} but report the +properties too. The \lpr {meaningless} companion reports the body of a macro. +Anyway, this typesets: + +\startlines \tttf \getbuffer \stoplines + +So, the \lpr {aliased} prefix copies the properties. Keep in mind that a macro +package can redefine primitives, but \prm {relax} is an unlikely candidate. + +There is an extra prefix \lpr {noaligned} that flags a macro as being valid +for \prm {noalign} compatible usage (which means that the body must contain that +one. The idea is that we then can do this: + +\starttyping +\permanent\protected\noaligned\def\foo{\noalign{...}} % \foo is unexpandable +\stoptyping + +that is: we can have protected macros that don't trigger an error in the parser +where there is a look ahead for \prm {noalign} which is why normally protection +doesn't work well. So: we have macro flagged as permanent (overload protection), +being protected (that is, not expandable by default) and a valid equivalent of +the noalign primitive. Of course we can also apply the \prm {global} and \lpr +{tolerant} prefixes here. The complete repertoire of extra prefixes is: + +\starttabulate +\HL +\NC \type {frozen} \NC a macro that has to be redefined in a managed way \NC \NR +\NC \type {permanent} \NC a macro that had better not be redefined \NC \NR +\NC \type {primitive} \NC a primitive that normally will not be adapted \NC \NR +\NC \type {immutable} \NC a macro or quantity that cannot be changed, it is a constant \NC \NR +\NC \type {mutable} \NC a macro that can be changed no matter how well protected it is \NC \NR +\HL +\NC \type {instance} \NC a macro marked as (for instance) be generated by an interface \NC \NR +\HL +\NC \type {noaligned} \NC the macro becomes acceptable as \type {\noalign} alias \NC \NR +\HL +\NC \type {overloaded} \NC when permitted the flags will be adapted \NC \NR +\NC \type {enforced} \NC all is permitted (but only in zero mode or ini mode) \NC \NR +\NC \type {aliased} \NC the macro gets the same flags as the original \NC \NR +\HL +\stoptabulate + +The not yet discussed \lpr {instance} is just a flag with no special meaning +which can be used as classifier. The \lpr {frozen} also protects against overload +which brings amount of blockers to four. + +To what extent the engine will complain when a property is changed in a way that +violates the flags depends on the parameter \lpr {overloadmode}. When this +parameter is set to zero no checking takes place. More interesting are values +larger than zero. If that is the case, when a control sequence is flagged as +mutable, it is always permitted to change. When it is set to immutable one can +never change it. The other flags determine the kind of checking done. Currently +the following overload values are used: + +\starttabulate[|l|l|c|c|c|c|c|] + \NC \NC \BC immutable \BC permanent \BC primitive \BC frozen \BC instance \NC \NR + \NC 1 \NC warning \NC \star \NC \star \NC \star \NC \NC \NC \NR + \NC 2 \NC error \NC \star \NC \star \NC \star \NC \NC \NC \NR + \NC 3 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \NC \NR + \NC 4 \NC error \NC \star \NC \star \NC \star \NC \star \NC \NC \NR + \NC 5 \NC warning \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR + \NC 6 \NC error \NC \star \NC \star \NC \star \NC \star \NC \star \NC \NR +\stoptabulate + +The even values (except zero) will abort the run. A value of 255 will freeze this +parameter. At level five and above the \lpr {instance} flag is also checked but +no drastic action takes place. We use this to signal to the user that a specific +instance is redefined (of course the definition macros can check for that too). + +The \lpr {overloaded} prefix can be used to overload a frozen macro. The \lpr +{enforced} is more powerful and forces an overload but that prefix is only +effective in ini mode or when it's embedded in the body of a macro or token list +at ini time unless of course at runtime the mode is zero. + +So far for a short explanation. More details can be found in the \CONTEXT\ +documentation where we can discuss it in a more relevant perspective. It must be +noted that this feature only makes sense a controlled situation, that is: user +modules or macros of unpredictable origin will probably suffer from warnings and +errors when de mode is set to non zero. In \CONTEXT\ we're okay unless of course +users redefine instances but there a warning or error is kind of welcome. + +\stopsection + +\startsection[title=Constants] + +It is rather common to store constant values in a register or character +definition. + +\starttyping +\newcount\MyConstantA \MyConstantA 123 +\newdimen\MyConstantB \MyConstantB 123pt +\chardef \MyConstantC \MyConstantC 123 +\stoptyping + +But in \LUAMETATEX\ we also can do this: + +\starttyping +\integerdef\MyConstantC 456 +\dimendef \MyConstantD 456pt +\stoptyping + +These two are stored as efficient as a register but don't occupy a register slot. +They can be set as above, need \prm {the} for serializations and are seen as +valid number or dimension when needed. + +Experiments with constant strings made the engine source more complex than I +wanted so that features was rejected. Of course we can use the prefixes mentioned +in a previous section. + +\stopsection + \startsection[title=Nodes] The \ETEX\ primitive \type {\lastnodetype} is not honest in reporting the |