summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-03-06 21:58:15 +0000
committerKarl Berry <karl@freefriends.org>2021-03-06 21:58:15 +0000
commit974640d66e61e81cb197ad96fdff7b08343e4c5a (patch)
tree2e1f75f32f312b7f24ba82b4590ae230bcd6f399 /Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
parentb4fa72e61230aca75f7f6fbf988821f71edfb6b2 (diff)
context
git-svn-id: svn://tug.org/texlive/trunk@58167 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex')
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex1025
1 files changed, 753 insertions, 272 deletions
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
index f295b34643a..947b2320a13 100644
--- a/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex
@@ -19,7 +19,7 @@ and there will be no \type {luametatex} variants. This is because we consider
\LUAMETATEX\ to be \LUATEX 2\high{+}.
Contrary to the \LUATEX\ engine \LUAMETATEX\ enables all its primitives. You can
-clone (a selection of) primitives with a different prefix, like:
+clone (a selection of) primitives with a different prefix, like this:
\starttyping
\directlua { tex.enableprimitives('normal',tex.extraprimitives()) }
@@ -27,38 +27,26 @@ clone (a selection of) primitives with a different prefix, like:
The \type {extraprimitives} function returns the whole list or a subset,
specified by one or more keywords \type {core}, \type {tex}, \type {etex} or
-\type {luatex}. \footnote {At some point this function might be changed to return
-the whole list always}.
+\type {luatex}. When you clone all primitives you can also do this:
+
+\starttyping
+\directlua { tex.enableprimitives('normal',true) }
+\stoptyping
But be aware that the curly braces may not have the proper \prm {catcode}
assigned to them at this early time (giving a \quote {Missing number} error), so
it may be needed to put these assignments before the above line:
\starttyping
-\catcode `\{=1
-\catcode `\}=2
+\catcode `\{ = 1
+\catcode `\} = 2
\stoptyping
More fine|-|grained primitives control is possible and you can look up the
details in \in {section} [luaprimitives]. There are only three kinds of
primitives: \type {tex}, \type {etex} and \type {luatex} but a future version
-might drop this and no longer make that distinction as it no longer serves
-a purpose.
-
-\stopsubsection
-
-\startsubsection[title={Experiments}]
-
-There are a few extensions to the engine regarding the macro machinery. Some are
-already well tested but others are (still) experimental. Although they are likely
-to stay, their exact behaviour might evolve. Because \LUAMETATEX\ is also used
-for experiments, this is not a problem. We can always decide to also add some of
-what is discussed here to \LUATEX, but it will happen with a delay.
-
-There are all kinds of small improvements that might find their way into stock
-\LUATEX: a few more helpers, some cleanup of code, etc. We'll see. In any case,
-if you play with these before they are declared stable, unexpected side effects
-are what you have to accept.
+might drop this and no longer make that distinction as it no longer serves a
+purpose apart from the fact that it reveals some history.
\stopsubsection
@@ -83,9 +71,9 @@ There are three primitives to test the version of \LUATEX\ (and \LUAMETATEX):
\BC explanation \NC \NR
\TB
\NC \lpr {luatexbanner} \NC \VersionHack{\luatexbanner}
- \NC the banner reported on the command line \NC \NR
+ \NC the banner reported on the console \NC \NR
\NC \lpr {luatexversion} \NC \the\luatexversion
- \NC a combination of major and minor number \NC \NR
+ \NC major and minor number combined \NC \NR
\NC \lpr {luatexrevision} \NC \the\luatexrevision
\NC the revision number \NC \NR
\LL
@@ -123,17 +111,6 @@ The \LUAMETATEX\ version number starts at~2 in order to prevent a clash with
\LUATEX, and the version commands are the same. This is a way to indicate that
these projects are related.
-\startsubsubsection[title={\lpr {formatname}}]
-
-\topicindex{format}
-
-The \lpr {formatname} syntax is identical to \prm {jobname}. In \INITEX, the
-expansion is empty. Otherwise, the expansion is the value that \prm {jobname} had
-during the \INITEX\ run that dumped the currently loaded format. You can use this
-token list to provide your own version info.
-
-\stopsubsubsection
-
\stopsubsection
\stopsection
@@ -178,7 +155,9 @@ the time comes to print a character $c>=1{,}114{,}112$, \LUATEX\ will actually
print the single byte corresponding to $c$ minus 1{,}114{,}112.
Contrary to other \TEX\ engines, the output to the terminal is as|-|is so there
-is no escaping with \type {^^}. We operate in a \UTF\ universe.
+is no escaping with \type {^^}. We operate in a \UTF\ universe. Because we
+operate in a \CCODE\ universum, zero characters are special but because we also
+live in a \UNICODE\ galaxy that is no real problem.
\stopsubsection
@@ -229,6 +208,34 @@ Fonts are loaded via \LUA\ and a minimal amount of information is kept at the
about what a character (or glyph) number represents (a \UNICODE\ or index) as it
only is interested in dimensions.
+In \TEX\ the number of registers is 256 and \ETEX\ bumped that to 32K. One reason
+for a fixed number is that these registers are fast ways to store data and
+therefore are part of the main lookup table (used for data and pointers to data
+as well as save and restore housekeeping). In \LUATEX\ the number was bumped to
+64K but one can argue that less would also do. In order to keep the default
+memory footprint reasonable, in \LUAMETATEX\ the number of languages, fonts and
+marks is limited. The size of some tables can be limited by configuration
+settings, so they can start out small and grow till configured maximum which is
+smaller than the absolute maximum. The following table shows all kind of defaults
+as reported by \typ {status.getconstants()}.
+
+\startluacode
+ context.starttabulate { "|T|r|" }
+ for k, v in table.sortedhash(status.getconstants()) do
+ context.NC() context(k) context.NC() context(v) context.NC() context.NR()
+ end
+ context.stoptabulate()
+\stopluacode
+
+Because we have additional ways to store integers, dimensions and glue, we might
+actually decide to decrease the maximum of the registers: if 64K is not enough,
+and you work around it, then likely 32K might do as well. Also, we have \LUA\ to
+store massive amounts of data. One can argue that saving some 1.5MB memory (when
+we go halfway) is not worth the effort in a time when you have to close a browser
+in order to free the gigabytes it consumes, but there is no reason not to be lean
+and mean: a more conservative approach to start with creates headroom for going
+wild later.
+
\stopsubsection
\stopsection
@@ -274,6 +281,12 @@ language related information, the expansion factor, etc. Now that we have access
to these nodes from \LUA\ it makes sense to be able to carry more information
with a node and this is where attributes kick in.
+It is important to keep in mind that there are situations where nodes get created
+in the current context. For instance, when \TEX\ builds a paragraph or page or
+constructs math formulas, it does add nodes and giving these the current
+attributes makes no sense and can even give weird side effects. In these cases,
+the attributes are inherited from neighbouring nodes.
+
\stopsubsection
\startsubsection[title={Attribute registers}]
@@ -320,6 +333,7 @@ experimental.
\topicindex {attributes}
\topicindex {boxes}
+\topicindex {vcentering}
Nodes typically receive the list of attributes that is in effect when they are
created. This moment can be quite asynchronous. For example: in paragraph
@@ -343,7 +357,7 @@ already boxed material will have no effect. Keep in mind that this
incompatibility is mostly due to the fact that separate specials and literals are
a more unnatural approach to colors than attributes.
-It is possible to fine-tune the list of attributes that are applied to a \type
+It is possible to fine|-|tune the list of attributes that are applied to a \type
{hbox}, \type {vbox} or \type {vtop} by the use of the keyword \type {attr}. The
\type {attr} keyword(s) should come before a \type {to} or \type {spread}, if
that is also specified. An example is:
@@ -392,6 +406,19 @@ indexing the node (here we do that with \type {[a]}). Running this snippet gives
Because some values are not set we need to apply the \type {tostring} function
here so that we get the word \type {nil}.
+A special kind of box is \prm {vcenter}. This one also can have attributes. When
+one or more are set these plus the currently set attributes are bound to the
+resulting box. In regular \TEX\ these centered boxes are only permitted in math
+mode, but in \LUAMETATEX\ there is no error message and the box the height and
+depth are equally divided. Of course in text mode there is no math axis related
+offset applied.
+
+It is possible to change or add to the attributes assigned to a box:
+
+\starttyping
+\boxattr 0 123 456
+\stoptyping
+
\stopsubsection
\stopsection
@@ -467,20 +494,22 @@ will result in
Note that the expansion of \prm {directlua} is a sequence of characters, not of
tokens, contrary to all \TEX\ commands. So formally speaking its expansion is
-null, but it places material on a pseudo-file to be immediately read by \TEX, as
-\ETEX's \prm {scantokens}. For a description of print functions look at \in
-{section} [sec:luaprint].
+null, but it collects material in a new level on the input stack to be
+immediately read by \TEX\ after the \LUA\ call as finished. It is a bit like
+\ETEX's \prm {scantokens}, which now uses the same mechanism. For a description
+of print functions look at \in {section} [sec:luaprint].
Because the \syntax {<general text>} is a chunk, the normal \LUA\ error handling
is triggered if there is a problem in the included code. The \LUA\ error messages
-should be clear enough, but the contextual information is still pretty bad.
-Often, you will only see the line number of the right brace at the end of the
-code.
+should be clear enough, but the contextual information is often suboptimal
+because it can come from deep down, and \TEX\ has no knowledge about what you do
+in \LUA. Often, you will only see the line number of the right brace at the end
+of the code.
While on the subject of errors: some of the things you can do inside \LUA\ code
can break up \LUAMETATEX\ pretty bad. If you are not careful while working with
-the node list interface, you may even end up with assertion errors from within
-the \TEX\ portion of the executable.
+the node list interface, you may even end up with errors or even crashes from
+within the \TEX\ portion of the executable.
\stopsubsection
@@ -557,6 +586,8 @@ tokens and assume that the function is available when that token expands. On the
other hand, as we have tested this functionality in relative complex situations
normal usage should not give problems.
+{\em It makes sense to delegate the implementation of the primitives to \LUA.}
+
\stopsubsection
\startsubsection[title={\lpr {luabytecode} and \lpr {luabytecodecall}}]
@@ -586,6 +617,8 @@ The variable \type {s} in the code is the number of the byte code register that
can be used for diagnostic purposes. The advantage of bytecode registers over
function calls is that they are stored in the format (but without upvalues).
+{\em It makes sense to delegate the implementation of the primitives to \LUA.}
+
\stopsubsection
\stopsection
@@ -608,14 +641,14 @@ contents is stored and retrieved from the format file.
\startsubsection[title={\lpr {catcodetable}}]
-\startsyntax
-\catcodetable <15-bit number>
-\stopsyntax
-
The primitive \lpr {catcodetable} switches to a different catcode table. Such a
table has to be previously created using one of the two primitives below, or it
has to be zero. Table zero is initialized by \INITEX.
+\startsyntax
+\catcodetable <15-bit number>
+\stopsyntax
+
\stopsubsection
\startsubsection[title={\lpr {initcatcodetable}}]
@@ -655,11 +688,9 @@ initial values are:
\lpr {savecatcodetable} copies the current set of catcodes to a new table with
the requested number. The definitions in this new table are all treated as if
-they were made in the outermost level.
-
-The new table is allocated globally: it will not go away after the current group
-has ended. If the supplied number is the currently active table, an error is
-raised.
+they were made in the outermost level. Again, the new table is allocated globally:
+it will not go away after the current group has ended. If the supplied number is
+the currently active table, an error is raised.
\stopsubsection
@@ -667,7 +698,7 @@ raised.
\startsection[title={Tokens, commands and strings}]
-\startsubsection[title={\lpr {scantextokens}}]
+\startsubsection[title={\lpr {scantextokens} and \lpr {tokenized}}]
\topicindex {tokens+scanning}
@@ -677,8 +708,7 @@ differences are:
\startitemize
\startitem
- The last (and usually only) line does not have a \prm {endlinechar}
- appended.
+ The last (and usually only) line does not have a \prm {endlinechar} appended.
\stopitem
\startitem
\lpr {scantextokens} never raises an EOF error, and it does not execute
@@ -691,6 +721,18 @@ differences are:
\stopitem
\stopitemize
+The implementation in \LUAMETATEX\ is different in the sense that it uses the same
+methods as printing from \LUA\ to \TEX\ does. Therefore, in addition to the two
+commands we also have this expandable command:
+
+\startsyntax
+\tokenized {...}
+\tokenized catcodetable <number> {...}
+\stopsyntax
+
+The \ETEX\ command \type {\tracingscantokens} has been dropped in the process as
+that was interwoven with the old code.
+
\stopsubsection
\startsubsection[title={\lpr {toksapp}, \lpr {tokspre}, \lpr {etoksapp}, \lpr {etokspre},
@@ -750,7 +792,7 @@ that it saves a few tokens and can make code a bit more readable.
This primitive complements the \ETEX\ mark primitives and clears a mark class
completely, resetting all three connected mark texts to empty. It is an
-immediate command.
+immediate command (no synchronization node is used).
\startsyntax
\clearmarks <16-bit number>
@@ -792,103 +834,135 @@ but faster (only measurable with millions of calls) and probably more convenient
\stopsubsection
-\startsubsection[title={\lpr {expanded}, \lpr {immediateassignment} and \lpr {immediateassigned}}]
-
-\topicindex {expansion}
-
-The \lpr {expanded} primitive takes a token list and expands its content which can
-come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
-You can compare it with what happens inside the body of an \prm {edef}. But this
-kind of expansion still doesn't expand some primitive operations.
-
-\startbuffer
-\newcount\NumberOfCalls
-
-\def\TestMe{\advance\NumberOfCalls1 }
-
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-
-\meaning\Tested
-\stopbuffer
-
-\typebuffer
-
-The result is a macro that has the not expanded code in its body:
-
-\getbuffer
-
-Instead we can define \tex {TestMe} in a way that expands the assignment
-immediately. You need of course to be aware of preventing look ahead interference
-by using a space or \tex {relax} (often an expression works better as it doesn't
-leave an \tex {relax}).
-
-\startbuffer
-\def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+\startsubsection[title={\lpr {defcsname}, \lpr {edefcsname}, \lpr {edefcsname} and \lpr {xdefcsname}}]
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
-\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+Although we can implement these primitives easily using macros it makes sense,
+given the popularity of \prm {csname} to have these as primitives. It also saves
+some \prm {expandafter} usage and it looks a bit better in the source.
-\meaning\Tested
-\stopbuffer
-
-\typebuffer
-
-This time the counter gets updates and we don't see interference in the
-resulting \tex {Tested} macro:
-
-\getbuffer
-
-Here is a somewhat silly example of expanded comparison:
-
-\startbuffer
-\def\expandeddoifelse#1#2#3#4%
- {\immediateassignment\edef\tempa{#1}%
- \immediateassignment\edef\tempb{#2}%
- \ifx\tempa\tempb
- \immediateassignment\def\next{#3}%
- \else
- \immediateassignment\def\next{#4}%
- \fi
- \next}
-
-\edef\Tested
- {(\expandeddoifelse{abc}{def}{yes}{nop}/%
- \expandeddoifelse{abc}{abc}{yes}{nop})}
-
-\meaning\Tested
-\stopbuffer
+\starttyping
+\def\gdefcsname foo\endcsname{oof}
+\stoptyping
-\typebuffer
+\stopsubsection
-It gives:
+\startsubsection[title={\lpr {expanded}}]
-\getbuffer
+\topicindex {expansion}
-A variant is:
+The \lpr {expanded} primitive takes a token list and expands its content which
+can come in handy: it avoids a tricky mix of \prm {expandafter} and \prm
+{noexpand}. You can compare it with what happens inside the body of an \prm
+{edef}. The \tex {immediateassignment} and \tex {immediateassigned} commands are
+gone because we have the more powerful local control commands. They are a tad
+slower but this mechanism isn't used that much anyway. Inside an \prm {edef} you
+can use the \type {\immediate} prefix anyway, so if you really want these
+primitives back you can say:
\starttyping
-\def\expandeddoifelse#1#2#3#4%
- {\immediateassigned{
- \edef\tempa{#1}%
- \edef\tempb{#2}%
- }%
- \ifx\tempa\tempb
- \immediateassignment\def\next{#3}%
- \else
- \immediateassignment\def\next{#4}%
- \fi
- \next}
+\let\immediateassignment\immediate
+\let\immediateassigned \localcontrolled
\stoptyping
-The possible error messages are the same as using assignments in preambles of
-alignments and after the \prm {accent} command. The supported assignments are the
-so called prefixed commands (except box assignments).
-
\stopsubsection
+% \startsubsection[title={\lpr {expanded}, \lpr {immediateassignment} and \lpr {immediateassigned}}]
+%
+% \topicindex {expansion}
+%
+% The \lpr {expanded} primitive takes a token list and expands its content which can
+% come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
+% You can compare it with what happens inside the body of an \prm {edef}. But this
+% kind of expansion still doesn't expand some primitive operations.
+%
+% \startbuffer
+% \newcount\NumberOfCalls
+%
+% \def\TestMe{\advance\NumberOfCalls1 }
+%
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% The result is a macro that has the not expanded code in its body:
+%
+% \getbuffer
+%
+% Instead we can define \tex {TestMe} in a way that expands the assignment
+% immediately. You need of course to be aware of preventing look ahead interference
+% by using a space or \tex {relax} (often an expression works better as it doesn't
+% leave an \tex {relax}).
+%
+% \startbuffer
+% \def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+%
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+% \edef\Tested{\TestMe foo:\the\NumberOfCalls}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% This time the counter gets updates and we don't see interference in the
+% resulting \tex {Tested} macro:
+%
+% \getbuffer
+%
+% Here is a somewhat silly example of expanded comparison:
+%
+% \startbuffer
+% \def\expandeddoifelse#1#2#3#4%
+% {\immediateassignment\edef\tempa{#1}%
+% \immediateassignment\edef\tempb{#2}%
+% \ifx\tempa\tempb
+% \immediateassignment\def\next{#3}%
+% \else
+% \immediateassignment\def\next{#4}%
+% \fi
+% \next}
+%
+% \edef\Tested
+% {(\expandeddoifelse{abc}{def}{yes}{nop}/%
+% \expandeddoifelse{abc}{abc}{yes}{nop})}
+%
+% \meaning\Tested
+% \stopbuffer
+%
+% \typebuffer
+%
+% It gives:
+%
+% \getbuffer
+%
+% A variant is:
+%
+% \starttyping
+% \def\expandeddoifelse#1#2#3#4%
+% {\immediateassigned{
+% \edef\tempa{#1}%
+% \edef\tempb{#2}%
+% }%
+% \ifx\tempa\tempb
+% \immediateassignment\def\next{#3}%
+% \else
+% \immediateassignment\def\next{#4}%
+% \fi
+% \next}
+% \stoptyping
+%
+% The possible error messages are the same as using assignments in preambles of
+% alignments and after the \prm {accent} command. The supported assignments are the
+% so called prefixed commands (except box assignments).
+%
+% \stopsubsection
+
\startsubsection[title={\lpr {ignorepars}}]
This primitive is like \prm {ignorespaces} but also skips paragraph ending
@@ -1034,6 +1108,55 @@ or more than zero.
\typebuffer \blank {\tt \getbuffer} \blank
+The last checked values are available in \lpr {lastchknum} and \lpr {lastchkdim}.
+These don't obey grouping.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifmathstyle} and \lpr {ifmathparameter}}]
+
+These two are variants on \prm {ifcase} where the first one operates with values
+in ranging from zero (display style) to seven (cramped script script style) and
+the second one can have three values: a parameter is zero, has a value or is
+unset. The \type {\ifmathparameter} primitive takes a proper parameter name and a
+valid style identifier (a primitive identifier or number). The \type
+{\ifmathstyle} primitive is equivalent to \type {\ifcase \mathstyle}.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifempty}}]
+
+This primitive tests for the following token (control sequence) having no
+content. Assuming that \type {\empty} is indeed empty, the following two are
+equivalent:
+
+\starttyping
+\ifempty\whatever
+\ifx\whatever\empty
+\stoptyping
+
+There is no real performance gain here, it's more one of these extensions that
+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
+
+\starttyping
+ \ifcase <integer>.F.\else .T.\fi
+\unless\ifcase <integer>.T.\else .F.\fi
+ \ifboolean<integer>.T.\else .F.\fi
+\stoptyping
+
\stopsubsection
\startsubsection[title={\lpr {iftok} and \lpr {ifcstok}}]
@@ -1058,13 +1181,40 @@ provided in \LUAMETATEX:
\typebuffer \startpacked[blank] {\tt\nospacing\getbuffer} \stoppacked
-You can check if a macro is is defined as protected with \type {\ifprotected}
-while frozen macros can be tested with \type {\iffrozen}. A provisional \type
+You can check if a macro is defined as protected with \type {\ifprotected} while
+frozen macros can be tested with \type {\iffrozen}. A provisional \type
{\ifusercmd} tests will check if a command is defined at the user level (and this
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}
@@ -1123,7 +1273,7 @@ we use \type {\unless} to negate the result.
\stopsubsection
-\startsubsection[title={\lpr {orelse}}]
+\startsubsection[title={\lpr {orelse} and \lpr {orunless}}]
Sometimes you have successive tests that, when laid out in the source lead to
deep trees. The \type {\ifcase} test is an exception. Experiments with \type
@@ -1189,6 +1339,12 @@ Of course it is only useful at the right level, so you might end up with cases l
\fi
\stoptyping
+The \lpr {orunless} variant negates the next test, just like \prm {unless}. In
+some cases these commands look at the next token to see if it is an if|-|test so
+a following negation will not work (read: making that work would complicate the
+code and hurt efficiency too). Side note: interesting is that in \CONTEXT\ we
+hardly use this kind of negation.
+
\stopsubsection
\startsubsection[title={\lpr {ifprotected}, \lpr {frozen}, \lpr {iffrozen} and \lpr {ifusercmd}}]
@@ -1219,10 +1375,18 @@ the acceptable range is from 0 to 65535.
\stopsubsection
-\startsubsection[title={\prm {vpack}, \prm {hpack} and \prm {tpack}}]
+\startsubsection[title={\prm {hrule}, \prm {vrule}, \lpr {nohrule} and \lpr {novrule}}]
+
+\topicindex {rules}
+
+Both rule drawing commands take an optional \type {xoffset} and \type {yoffset}
+parameter. The displacement is virtual and not taken into account when the
+dimensions are calculated.
-These three primitives are like \prm {vbox}, \prm {hbox} and \prm {vtop}
-but don't apply the related callbacks.
+Two new primitives were introduced: \lpr {nohrule} and \lpr {novrule}. These can
+be used to reserve space. This is often more efficient than creating an empty box
+with fake dimensions. Of course this assumes that the backend implements them
+being invisible but still taking space.
\stopsubsection
@@ -1236,7 +1400,7 @@ a split of the given size but result has the natural dimensions then.
\stopsubsection
-\startsubsection[title={Images and reused box objects},reference=sec:imagedandforms]
+\startsubsection[title={Images and reused box objects},reference=sec:imagesandforms]
In original \TEX\ image support is dealt with via specials. It's not a native
feature of the engine. All that \TEX\ cares about is dimensions, so in practice
@@ -1252,12 +1416,12 @@ point this approach was abandoned and a more natural trick was used: images (and
box resources) became a special kind of rules, and as rules already have
dimensions, the code could be simplified.
-When direction nodes and localpar nodes also became first class nodes, whatsits
-again became just that: nodes representing whatever you want, but without
-dimensions, and therefore they could again be ignored when dimensions mattered.
-And, because images were disguised as rules, as mentioned, their dimensions
-automatically were taken into account. This seperation between front and backend
-cleaned up the code base already quite a bit.
+When direction nodes and (formerly local) par nodes also became first class
+nodes, whatsits again became just that: nodes representing whatever you want, but
+without dimensions, and therefore they could again be ignored when dimensions
+mattered. And, because images were disguised as rules, as mentioned, their
+dimensions automatically were taken into account. This separation between front
+and backend cleaned up the code base already quite a bit.
In \LUAMETATEX\ we still have the image specific subtypes for rules, but the
engine never looks at subtypes of rules. That was up to the backend. This means
@@ -1313,21 +1477,12 @@ packages.
\startsubsection[title={\lpr {hpack}, \lpr {vpack} and \lpr {tpack}}]
-These three primitives are the equivalents of \type {\hbox}, \type {\vbox} and
-\type {\vtop} but they don't trigger the packaging related callbacks. Of course
+These three primitives are the equivalents of \prm {hbox}, \prm {vbox} and
+\prm {vtop} but they don't trigger the packaging related callbacks. Of course
one never know if content needs a treatment so using them should be done with
-care.
-
-\stopsubsection
-
-\startsubsection[title={\lpr {nohrule} and \lpr {novrule}}]
-
-\topicindex {rules}
-
-Because introducing a new keyword can cause incompatibilities, two new primitives
-were introduced: \lpr {nohrule} and \lpr {novrule}. These can be used to
-reserve space. This is often more efficient than creating an empty box with fake
-dimensions.
+care. Apart from accepting more keywords (and therefore options) the normal
+box behave the same as before. The \prm {vcenter} builder also works in text
+mode.
\stopsubsection
@@ -1390,14 +1545,29 @@ the node number of the nodes.
\stopsubsection
+% \startsubsection[title={\lpr {lastnodetype}, \lpr {lastnodesubtype}, \lpr
+% {currentiftype} and \lpr {internalcodesmode}.}]
+%
+% The \ETEX\ command \type {\lastnodetype} is limited to some nodes. When the
+% parameter \type {\internalcodesmode} is set to a non|-|zero value the normal
+% (internally used) numbers are reported. The same is true for \type
+% {\currentiftype}, as we have more conditionals and also use a different order.
+% The \type {\lastnodesubtype} is a bonus.
+%
+% \stopsubsection
+
\startsubsection[title={\lpr {lastnodetype}, \lpr {lastnodesubtype}, \lpr
-{currentiftype} and \lpr {internalcodesmode}.}]
+{currentiftype}}]
-The \ETEX\ command \type {\lastnodetype} is limited to some nodes. When the
-parameter \type {\internalcodesmode} is set to a non|-|zero value the normal
-(internally used) numbers are reported. The same is true for \type
+The \ETEX\ command \type {\lastnodetype} returns the node codes as used in the
+engine. You can query the numbers at the \LUA\ end if you need the actual values.
+The parameter \type {\internalcodesmode} is no longer provided as compatibility
+switch because \LUATEX\ has more cq. some different nodes and it makes no sense
+to be incompatible with the \LUA\ end of the engine. The same is true for \type
{\currentiftype}, as we have more conditionals and also use a different order.
-The \type {\lastnodesubtype} is a bonus.
+The \type {\lastnodesubtype} is a bonus and again reports the codes used
+internally. During development these might occasionally change, but eventually
+they will be stable.
\stopsubsection
@@ -1417,7 +1587,10 @@ The \type {\lastnodesubtype} is a bonus.
\stoptyping
This allows for embedded spaces, without the need for double quotes. Macro
-expansion takes place inside the argument.
+expansion takes place inside the argument. Keep in mind that as side effect of
+delegating \IO\ to \LUA\ the \prm {openin} primitive is nor provided by the
+engine and has to be implemented by the macro package. This also means that the
+limit on the number of open files is not enforced by the engine.
The \lpr {tracingfonts} primitive that has been inherited from \PDFTEX\ has
been adapted to support variants in reporting the font. The reason for this
@@ -1442,10 +1615,12 @@ extension is that a csname not always makes sense. The zero case is the default.
\topicindex {files+writing}
-You can now open upto 127 files with \prm {openout}. When no file is open writes
-will go to the console and log. The \type {write} related primitives have to be
-implemented as part of a backend! As a consequence a system command is no longer
-possible but one can use \type {os.execute} to do the same.
+Writing to a file in \TEX\ has two forms: delayed and immediate. Delayed writing
+means that the to be written text is anchored in the node list and flushed by the
+backend. As all \IO\ is delegated to \LUA, this also means that it has to deal
+with distinction. In \LUATEX\ the number of open files was already bumped to 127,
+but in \LUAMETATEX\ it depends on the macro package. The special meaning of
+channel 18 was already dropped in \LUATEX\ because we have \type {os.execute}.
\stopsubsection
@@ -1617,106 +1792,143 @@ convenience extra which could also have been implemented using node list parsing
\stopsubsection
-\startsubsection[title={Controlling glue with \lpr {breakafterdirmode}}]
+\startsubsection[title={Normalizing lines}]
-Glue after a dir node is ignored in the linebreak decision but you can bypass that
-by setting \lpr {breakafterdirmode} to~\type {1}. The following table shows the
-difference. Watch your spaces.
+The original \TEX\ machinery was never meant to be opened up. As a consequence a
+constructed line can have different layouts. There can be left- and/or right
+skips and hanging indentation or parshape can result in a shift and adapted
+width. In \LUATEX\ glue got subtypes so we can recognize the left-, right and
+parfill skips, but still there is no hundred percent certainty about the shape.
-\def\ShowSome#1{%
- \BC \type{#1}
- \NC \breakafterdirmode\zerocount\hsize\zeropoint#1
- \NC
- \NC \breakafterdirmode\plusone\hsize\zeropoint#1
- \NC
- \NC \NR
-}
+In \LUAMETATEX\ lines can be normalized. This is optional because we want to
+preserve the original (for comparison) and is controlled by \lpr
+{normalizelinemode}. That variable actually drives some more. An earlier version
+provided a few more granular options (for instance: does a leftskip comes before
+or after a left hanging indentation) but in the end that was dropped. Because
+this normalization only is seen at the \LUA\ end there is no need to go into much
+detail here.
-\starttabulate[|l|Tp(1pt)|w(5em)|Tp(1pt)|w(5em)|]
- \DB
- \BC \type{0}
- \NC
- \BC \type{1}
- \NC
- \NC \NR
- \TB
- \ShowSome{pre {\textdirection 0 xxx} post}
- \ShowSome{pre {\textdirection 0 xxx }post}
- \ShowSome{pre{ \textdirection 0 xxx} post}
- \ShowSome{pre{ \textdirection 0 xxx }post}
- \ShowSome{pre { \textdirection 0 xxx } post}
- \ShowSome{pre {\textdirection 0\relax\space xxx} post}
- \LL
-\stoptabulate
+At this moment a line has this pattern: left parfill, left hang, left skip,
+indentation, content, right hang, right skip, right parfill. Of course the
+indentation and fill skips are not present in every line.
-\stopsubsection
+Control over normalization happens via the mentioned mode variable and here is
+what the engine provides right now. We use a bitmap:
-\startsubsection[title={Controling parshapes with \lpr {shapemode}}]
-
-Another adaptation to the \ALEPH\ directional model is control over shapes driven
-by \prm {hangindent} and \prm {parshape}. This is controlled by a new parameter
-\lpr {shapemode}:
-
-\starttabulate[|c|l|l|]
-\DB value \BC \prm {hangindent} \BC \prm {parshape} \NC \NR
+\starttabulate[|l|l|]
+\DB value \BC reported \NC \NR
\TB
-\BC \type{0} \NC normal \NC normal \NC \NR
-\BC \type{1} \NC mirrored \NC normal \NC \NR
-\BC \type{2} \NC normal \NC mirrored \NC \NR
-\BC \type{3} \NC mirrored \NC mirrored \NC \NR
+\NC \type{0x0001} \NC normalize line as described above \NC \NR
+\NC \type{0x0002} \NC use a skip for parindent instead of a box \NC \NR
+\NC \type{0x0004} \NC swap hangindent in l2r mode \NC \NR
+\NC \type{0x0008} \NC swap parshape in l2r mode \NC \NR
+\NC \type{0x0010} \NC put breaks after dir in l2r mode \NC \NR
+\NC \type{0x0020} \NC remove margin kerns (\PDFTEX\ left-over) \NC \NR
+\NC \type{0x0040} \NC if needed clip width and use correction kern \NC \NR
\LL
\stoptabulate
-The value is reset to zero (like \prm {hangindent} and \prm {parshape})
-after the paragraph is done with. You can use negative values to prevent
-this. In \in {figure} [fig:shapemode] a few examples are given.
-
-\startplacefigure[reference=fig:shapemode,title={The effect of \type {shapemode}.}]
- \startcombination[2*3]
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 0 \textdirection 0
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TLT: hangindent}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 0 \textdirection 0
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TLT: parshape}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 1 \textdirection 1
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TRT: hangindent mode 0}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \pardirection 1 \textdirection 1
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TRT: parshape mode 0}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \shapemode=3
- \pardirection 1 \textdirection 1
- \hangindent 40pt \hangafter -3
- \leftskip10pt \input tufte \par
- \egroup} {TRT: hangindent mode 1 & 3}
- {\ruledvbox \bgroup \setuptolerance[verytolerant]
- \hsize .45\textwidth \switchtobodyfont[6pt]
- \shapemode=3
- \pardirection 1 \textdirection 1
- \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
- \input tufte \par
- \egroup} {TRT: parshape mode 2 & 3}
- \stopcombination
-\stopplacefigure
-
-We have \type {\pardirection}, \type {\textdirection}, \type {\mathdirection} and
-\type {\linedirection} that is like \type {\textdirection} but with some
-additional (inline) glue checking.
+Setting the bit enables the related normalization. More features might be added
+in future releases.
+
+% Swapping shapes
+%
+% Another adaptation to the \ALEPH\ directional model is control over shapes driven
+% by \prm {hangindent} and \prm {parshape}. This is controlled by a new parameter
+% \lpr {shapemode}:
+%
+% \starttabulate[|c|l|l|]
+% \DB value \BC \prm {hangindent} \BC \prm {parshape} \NC \NR
+% \TB
+% \BC \type{0} \NC normal \NC normal \NC \NR
+% \BC \type{1} \NC mirrored \NC normal \NC \NR
+% \BC \type{2} \NC normal \NC mirrored \NC \NR
+% \BC \type{3} \NC mirrored \NC mirrored \NC \NR
+% \LL
+% \stoptabulate
+%
+% The value is reset to zero (like \prm {hangindent} and \prm {parshape})
+% after the paragraph is done with. You can use negative values to prevent
+% this. In \in {figure} [fig:shapemode] a few examples are given.
+%
+% \startplacefigure[reference=fig:shapemode,title={The effect of \type {shapemode}.}]
+% \startcombination[2*3]
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 0 \textdirection 0
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TLT: hangindent}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 0 \textdirection 0
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TLT: parshape}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 1 \textdirection 1
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TRT: hangindent mode 0}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \pardirection 1 \textdirection 1
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TRT: parshape mode 0}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \shapemode=3
+% \pardirection 1 \textdirection 1
+% \hangindent 40pt \hangafter -3
+% \leftskip10pt \input tufte \par
+% \egroup} {TRT: hangindent mode 1 & 3}
+% {\ruledvbox \bgroup \setuptolerance[verytolerant]
+% \hsize .45\textwidth \switchtobodyfont[6pt]
+% \shapemode=3
+% \pardirection 1 \textdirection 1
+% \parshape 4 0pt .8\hsize 10pt .8\hsize 20pt .8\hsize 0pt \hsize
+% \input tufte \par
+% \egroup} {TRT: parshape mode 2 & 3}
+% \stopcombination
+% \stopplacefigure
+%
+% We have \type {\pardirection}, \type {\textdirection}, \type {\mathdirection} and
+% \type {\linedirection} that is like \type {\textdirection} but with some
+% additional (inline) glue checking.
+
+% Controlling glue with \lpr {breakafterdirmode}
+%
+% Glue after a dir node is ignored in the linebreak decision but you can bypass that
+% by setting \lpr {breakafterdirmode} to~\type {1}. The following table shows the
+% difference. Watch your spaces.
+%
+% \def\ShowSome#1{%
+% \BC \type{#1}
+% \NC \breakafterdirmode\zerocount\hsize\zeropoint#1
+% \NC
+% \NC \breakafterdirmode\plusone\hsize\zeropoint#1
+% \NC
+% \NC \NR
+% }
+%
+% \starttabulate[|l|Tp(1pt)|w(5em)|Tp(1pt)|w(5em)|]
+% \DB
+% \BC \type{0}
+% \NC
+% \BC \type{1}
+% \NC
+% \NC \NR
+% \TB
+% \ShowSome{pre {\textdirection 0 xxx} post}
+% \ShowSome{pre {\textdirection 0 xxx }post}
+% \ShowSome{pre{ \textdirection 0 xxx} post}
+% \ShowSome{pre{ \textdirection 0 xxx }post}
+% \ShowSome{pre { \textdirection 0 xxx } post}
+% \ShowSome{pre {\textdirection 0\relax\space xxx} post}
+% \LL
+% \stoptabulate
\stopsubsection
@@ -1751,17 +1963,286 @@ shows that is't okay, they will become official, so we just mention them: \type
{\boxdirection}, \type {\boxattr}, \type {\boxorientation}, \type {\boxxoffset},
\type {\boxyoffset}, \type {\boxxmove}, \type {\boxymove} and \type {\boxtotal}.
+{\em This is still somewhat experimental and will be documented in more detail
+when I've used it more in \CONTEXT\ and the specification is frozen. This might
+take some time (and user input).}
+
\stopsubsection
\stopsection
-\startsection[title=Expressions]
+\startsection[title=Keywords]
+
+Some primitives accept one or more keywords and \LUAMETATEX\ adds some more. In
+order to deal with this efficiently the keyword scanner has been optimized, where
+even the context was taken into account. As a result the scanner was quite a bit
+faster. This kind of optimization was a graduate process the eventually ended up
+in what we have now. In traditional \TEX\ (and also \LUATEX) the order of
+keywords is sometimes mixed and sometimes prescribed. In most cases only one
+occurrence is permitted. So, for instance, this is valid in \LUATEX:
+
+\starttyping
+\hbox attr 123 456 attr 123 456 spread 10cm { }
+\hrule width 10cm depth 3mm
+\hskip 3pt plus 2pt minus 1pt
+\stoptyping
+
+The \type {attr} comes before the \type {spread}, rules can have multiple mixed
+dimension specifiers, and in glue the optional \type {minus} part always comes
+last. The last two commands are famous for look ahead side effects which is why
+macro packages will end them with something not keyword, like \type {\relax},
+when needed.
+
+In \LUAMETATEX\ the following is okay. Watch the few more keywords in box and
+rule specifications.
+
+\starttyping
+\hbox reverse to 10cm attr 123 456 orientation 4 xoffset 10pt spread 10cm { }
+\hrule xoffset 10pt width 10cm depth 3mm
+\hskip 3pt minus 1pt plus 2pt
+\stoptyping
+
+Here the order is not prescribed and, as demonstrated with the box specifier, for
+instance dimensions (specified by \type {to} or \type {spread} can be overloaded
+by later settings. In case you wonder if that breaks compatibility: in some way
+it does but bad or sloppy keyword usage breaks a run anyway. For instance \type
+{minuscule} results in \type {minus} with no dimension being seen. So, in the end
+the user should not noticed it and when a user does, the macro package already
+had an issue that had to be fixed.
+
+\stopsection
+
+\startsection[title=Expressions and \lpr {numericscale}]
The \type {*expr} parsers now accept \type {:} as operator for integer division
(the \type {/} operators does rounding. This can be used for division compatible
with \type {\divide}. I'm still wondering if adding a couple of bit operators
makes sense (for integers).
+The \lpr{numericscale} parser is kind of special (and might evolve). For now it
+converts a following number in a scale value as often used in \TEX, where 1000
+means scaling by~1.0. The trick is in the presence of a digit (or comma): 1.234
+becomes 1234 but 1234 stays 1234 and from this you can deduce that 12.34 becomes
+123400. Internally \TEX\ calculates with integers, but this permits the macro
+package to provide an efficient mix.
+
+\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]