diff options
author | Hans Hagen <pragma@wxs.nl> | 2020-05-12 17:07:12 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2020-05-12 17:07:12 +0200 |
commit | d7b2b626996a97ebb9911c972b920f8eace34d4f (patch) | |
tree | 8088503542c84a8e141712bfabe3e6556154ce77 /doc | |
parent | 924914d6830838e5b8191c6996c66fbfe50cd70d (diff) | |
download | context-d7b2b626996a97ebb9911c972b920f8eace34d4f.tar.gz |
2020-05-12 16:20:00
Diffstat (limited to 'doc')
-rw-r--r-- | doc/context/documents/general/manuals/evenmore.pdf | bin | 1538298 -> 1509228 bytes | |||
-rw-r--r-- | doc/context/documents/general/manuals/luametatex.pdf | bin | 1221745 -> 1224967 bytes | |||
-rw-r--r-- | doc/context/documents/general/manuals/units-mkiv.pdf | bin | 164604 -> 113203 bytes | |||
-rw-r--r-- | doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex | 365 | ||||
-rw-r--r-- | doc/context/sources/general/manuals/evenmore/evenmore.tex | 1 | ||||
-rw-r--r-- | doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex | 16 | ||||
-rw-r--r-- | doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex | 1 | ||||
-rw-r--r-- | doc/context/sources/general/manuals/luametatex/luametatex-tex.tex | 4 | ||||
-rw-r--r-- | doc/context/sources/general/manuals/units/units-mkiv.tex | 36 |
9 files changed, 420 insertions, 3 deletions
diff --git a/doc/context/documents/general/manuals/evenmore.pdf b/doc/context/documents/general/manuals/evenmore.pdf Binary files differindex 5c4072192..6e5b1105e 100644 --- a/doc/context/documents/general/manuals/evenmore.pdf +++ b/doc/context/documents/general/manuals/evenmore.pdf diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf Binary files differindex fbf2a3842..04be79255 100644 --- a/doc/context/documents/general/manuals/luametatex.pdf +++ b/doc/context/documents/general/manuals/luametatex.pdf diff --git a/doc/context/documents/general/manuals/units-mkiv.pdf b/doc/context/documents/general/manuals/units-mkiv.pdf Binary files differindex 5631be78e..d40991211 100644 --- a/doc/context/documents/general/manuals/units-mkiv.pdf +++ b/doc/context/documents/general/manuals/units-mkiv.pdf diff --git a/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex b/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex new file mode 100644 index 000000000..9b8e10a56 --- /dev/null +++ b/doc/context/sources/general/manuals/evenmore/evenmore-numbers.tex @@ -0,0 +1,365 @@ +% language=us + +\startcomponent evenmore-numbers + +\environment evenmore-style + +\startchapter[title={Numbers}] + +% \startsection[title={Introduction}] + +A few decades of programming in the \TEX\ language can make one wish for certain +features. It will therefore be no surprise that in \LUATEX\ (and even more in +\LUAMETATEX) we have some additional functionality. However, I have to admit that +some of these are not used that much in \CONTEXT\ \MKIV\ and \LMTX. The reason is +that some wishes date from \MKII\ times and because we now have \LUA\ we actually +don't need that many new fancy features. Also, it makes no sense to rewrite +mechanisms that are already working well. However, in order to fully exploit the +possibilities that \LUA\ gives, there are some additions that relate to the way +this language can communicate with \TEX. Of course there's also the issue of a +potentially enhanced performance, but there is not much to gain in that +department. + +A side effect of adding features, of which some are just there to complete the +picture, or, as mentioned, because they were supposed to make sense, is that I +make examples. Here I show the result of one of these experiments. I have no clue +how useful this is, but I've learned not to underestimate users in their demands +and creativity. + +Internally, \TEX\ does all in 32 bit integers. When you say: + +\starttyping +\scratchcounter 123 +\scratchdimen 123pt +\stoptyping + +the \type {123} gets assigned to a count register and the \type {123pt} is +assigned to a dimen register but actually that is then also an integer: the +internal unit of a dimen is a scaled point (sp) and only when its value is shown +to the user, a real number can show up, followed by the \type {pt} unit. The +precision is limited, so you can expect about four decimal positions precision +here. There is no concept of a floating point number in \TEX, and the only case +where a float gets used is in the final calculations of glue and even that only +comes into play in the backend. + +So, although I don't really have an application for it in \CONTEXT\ (otherwise +I'd already added a float data type to the engine), it sounded like a good idea +to see if we could emulate float support. In the following examples the numbers +are managed in \LUA\ and therefore they are global. I could make a local variant +but why complicate matters. These macros start with \type {\lua} to make clear +that they are not managed by \TEX. + +\startbuffer +\luacardinal bar 123 +\luainteger bar -456 +\luafloat bar 123.456E-3 +\stopbuffer + +\typebuffer \getbuffer + +We define \type {bar} three times. Each type gets its own hash, so from the +perspective of \LUA\ its nature is kept: integer or double. + +\startbuffer +\the\luacardinal bar \quad +\the\luainteger bar \quad +\the\luafloat bar +\stopbuffer + +\typebuffer \getbuffer + +Instead of decimal values, you can also use hexadecimal values (watch the \type +{p} for exponents): + +\startbuffer +\luacardinal bar 0x123 +\luainteger bar -0x456 +\luafloat bar 0x123.456p-3 +\stopbuffer + +\typebuffer \getbuffer + +So, now we get: + +\startbuffer +\the\luacardinal bar \quad +\the\luainteger bar \quad +\the\luafloat bar +\stopbuffer + +\getbuffer + +From these examples you see two kind of usage: setting a value, and using it. It +is that property that makes them special. Because the macros are implemented +using \LUA\ calls it means that at the \LUA\ end we know what usage is expected. +And it is that dualistic property that I wanted to explore but that in the end +only makes sense it a very few cases, but sometimes those few are important. We +could of course two macros, a setter and a getter, but using one kind of its in. + +The setters accept an optional equal sign, as in: + +\startbuffer +\luainteger gnu= 123456 \luafloat gnu= 123.456e12 +\luainteger gnu = 123456 \luafloat gnu = 123.456e12 +\luainteger gnu =123456 \luafloat gnu =123.456e12 +\stopbuffer + +\typebuffer + +Although \LUA\ is involved in picking up the value, storing it someplace, and +retrieving it on demand, performance is pretty good. You probably won't notice +the overhead anyway. + +The values that \type{\the} returns are serialized numbers. However, sometimes +you want what \TEX\ sees as a numeric token, For that we have these variants + +\startbuffer +\luadimen test 100pt +\scratchdimen = .25 \luadimen test +\the\scratchdimen +\stopbuffer + +\typebuffer + +Which produces the expected value: {\tttf \inlinebuffer}, something that depends +on the fact that the dimension is not a serialized. Talking of serialization, +there are several ways that \LUA\ can do that so let's give some examples. We +start with some definitions. Beware, floats and cardinals are stored +independently! + +\startbuffer +\luacardinal x = -123 +\luacardinal y = 456 + +\luafloat x = 123.123 +\luafloat y = -456.456 +\stopbuffer + +\typebuffer \getbuffer + +We have a macro \type {\luaexpression} (not to be confused with \type {\luaexpr}) that +takes an optional keyword: + +\startbuffer +- : \luaexpression {n.x + 2*n.y} +f : \luaexpression float {n.x + 2*n.y} +i : \luaexpression integer {n.x + 2*n.y} +c : \luaexpression cardinal {n.x + 2*n.y} +b : \luaexpression boolean {n.x + 2*n.y} +l : \luaexpression lua {n.x + 2*n.y} +\stopbuffer + +\typebuffer + +The serialization can be different for these cases: + +\startlines +\tt \getbuffer +\stoplines + +The \type {numbers} namespace resolves to a float, integer or cardinal (in that +order) and calculations take place as in \LUA. If you only use integers then +normally \LUA\ will also serialize them as such. + +Here is another teaser. Say that we set the \type {scratchdimen} register to +a value: + +\startbuffer +\scratchdimen 123.456pt +\stopbuffer + +\typebuffer \getbuffer + +We now introduce the \type {\nodimen} macro, that can be used this way: + +\startbuffer +[\the\scratchdimen] [\the\nodimen\scratchdimen] +\stopbuffer + +\typebuffer \getbuffer + +which is not that spectacular. Nor is this: + +\startbuffer +\nodimen\scratchdimen = 654.321pt +\stopbuffer + +\typebuffer \getbuffer + +But how about this: + +\starttabulate[|T|T|] +\NC \type {\the\nodimen bp \scratchdimen} \NC \the\nodimen bp \scratchdimen \NC \NR +\NC \type {\the\nodimen cc \scratchdimen} \NC \the\nodimen cc \scratchdimen \NC \NR +\NC \type {\the\nodimen cm \scratchdimen} \NC \the\nodimen cm \scratchdimen \NC \NR +\NC \type {\the\nodimen dd \scratchdimen} \NC \the\nodimen dd \scratchdimen \NC \NR +\NC \type {\the\nodimen in \scratchdimen} \NC \the\nodimen in \scratchdimen \NC \NR +\NC \type {\the\nodimen mm \scratchdimen} \NC \the\nodimen mm \scratchdimen \NC \NR +\NC \type {\the\nodimen nc \scratchdimen} \NC \the\nodimen nc \scratchdimen \NC \NR +\NC \type {\the\nodimen nd \scratchdimen} \NC \the\nodimen nd \scratchdimen \NC \NR +\NC \type {\the\nodimen pt \scratchdimen} \NC \the\nodimen pt \scratchdimen \NC \NR +\NC \type {\the\nodimen sp \scratchdimen} \NC \the\nodimen sp \scratchdimen \NC \NR +\stoptabulate + +So here we have a curious mix of setter and getter. The setting part is not that +interesting but we just provide it as convenience (and demo). Of course we can +have 10 specific macros instead. Keep in mind that this is a low level macro, so +it doesn't use the normal \CONTEXT\ user interface. + +A bit more complex are one or two dimensional arrays. Again this is an example +implementation where users can come up with more ideas. + +\startbuffer +\newarray name integers type integer nx 2 ny 2 +\newarray name booleans type boolean nx 2 ny 2 +\newarray name floats type float nx 2 ny 2 +\newarray name dimensions type dimension nx 4 +\stopbuffer + +\typebuffer \getbuffer + +Here we define three two|-|dimensional assays and one one|-|dimensional +array. The type determines the initialization as well as the scanner and +serializer. Values can be set as follows: + +\startbuffer +\arrayvalue integers 1 2 4 \arrayvalue integers 2 1 8 +\arrayvalue booleans 1 2 true \arrayvalue booleans 2 1 true +\arrayvalue floats 1 2 12.34 \arrayvalue floats 2 1 34.12 +\arrayvalue dimensions 1 12.34pt \arrayvalue dimensions 3 34.12pt +\stopbuffer + +\typebuffer \getbuffer + +If you want to check an array on the console, you can say: + +\starttyping +\showarray integers +\stoptyping + +We now access some values. Apart from the float these are (sort of) native data +types. + +\startbuffer +[\the\arrayvalue integers 1 2] +[\the\arrayvalue booleans 1 2] +[\the\arrayvalue floats 1 2] +[\the\arrayvalue dimensions 1 ]\crlf +[\the\arrayvalue integers 2 1] +[\the\arrayvalue booleans 2 1] +[\the\arrayvalue floats 2 1] +[\the\arrayvalue dimensions 3] +\stopbuffer + +\typebuffer + +This produces: + +\getbuffer + +You can of course use these values in many ways: + +\startbuffer +\dostepwiserecurse{1}{4}{1}{ + [\the\arrayvalue dimensions #1 : + \luaexpression dimen {math.sind(30) * a.dimensions[#1]}] +} +\stopbuffer + +\typebuffer + +This gives: + +\getbuffer + +In addition to the already seen integer and dimension variables fed back into +\TEX, we also have booleans. These are just integers with the value zero or one. +In order to make their use easier there is a new \type {\ifboolean} primitive +that takes such a bit: + +\startbuffer +slot 1 is \ifboolean\arrayequals dimensions 1 0pt zero \else not zero \fi +slot 2 is \ifboolean\arrayequals dimensions 2 0pt zero \else not zero \fi +\stopbuffer + +\typebuffer + +We get: + +\startlines +\getbuffer +\stoplines + +A variant is a comparison macro. Of course we can use the dimen comparison +conditional instead: + +\startbuffer +slot 1: \ifcase\arraycompare dimensions 1 3pt lt \or eq \else gt \fi zero +slot 2: \ifcase\arraycompare dimensions 2 3pt lt \or eq \else gt \fi zero +slot 3: \ifcase\arraycompare dimensions 3 3pt lt \or eq \else gt \fi zero +slot 4: \ifcase\arraycompare dimensions 4 3pt lt \or eq \else gt \fi zero + +slot 1: \ifcmpdim\arrayvalue dimensions 1 3pt lt \or eq \else gt \fi zero +slot 2: \ifcmpdim\arrayvalue dimensions 2 3pt lt \or eq \else gt \fi zero +slot 3: \ifcmpdim\arrayvalue dimensions 3 3pt lt \or eq \else gt \fi zero +slot 4: \ifcmpdim\arrayvalue dimensions 4 3pt lt \or eq \else gt \fi zero +\stopbuffer + +\typebuffer + +We get: + +\startlines +\getbuffer +\stoplines + +Anyway, the question is: do we need this kind of trickery, and if so, what more +is needed? But beware: we do have \LUA\ anyway, so there is no need for a complex +user interface at the \TEX\ end just for the sake of it looking more \TEX. The +above shows a bit what is possible. + +It is too soon to discuss the low level interface because it still evolves. After +some initial experiments, I decided to follow a slightly different route, and +often the third implementation starts to look what I like more. + +% \newarray name whatever type integer nx 100 ny 100 +% +% \testfeatureonce{1}{ +% \dorecurse {100} { +% \dorecurse {100} { +% \scratchcounter \arrayvalue whatever ##1 ####1 \relax +% } +% } +% } \elapsedtime + +% \startluacode +% local whatever = { foo = true, bar = true } +% +% interfaces.implement { +% name = "MyMatch", +% public = true, +% value = true, +% actions = function(b) +% -- we gobble spaces +% return +% tokens.functionvalues.boolean, +% whatever[tokens.scanners.word(true)] or false +% end, +% } +% \stopluacode +% +% [\ifboolean\MyMatch foo YES\else NOP\fi] +% [\ifboolean\MyMatch rab YES\else NOP\fi] +% [\ifboolean\MyMatch bar YES\else NOP\fi] +% [\ifboolean\MyMatch oof YES\else NOP\fi] +% +% \def\Matched#1{\ifboolean\MyMatch #1 } +% +% [\ifcondition\Matched{oof}YES\else NOP\fi] +% [\ifcondition\Matched{foo}YES\else NOP\fi] + +% \stopsection + +\stopchapter + +\stopcomponent diff --git a/doc/context/sources/general/manuals/evenmore/evenmore.tex b/doc/context/sources/general/manuals/evenmore/evenmore.tex index 293753a79..e6d046e7f 100644 --- a/doc/context/sources/general/manuals/evenmore/evenmore.tex +++ b/doc/context/sources/general/manuals/evenmore/evenmore.tex @@ -20,6 +20,7 @@ \component evenmore-macros \component evenmore-libraries \component evenmore-whattex + \component evenmore-numbers \stopbodymatter \stopdocument diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex index 3e710fe8c..d199239b1 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-enhancements.tex @@ -1091,6 +1091,18 @@ or more than zero. \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}}] \topicindex {conditions+tokens} @@ -1113,8 +1125,8 @@ 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). diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex b/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex index 825de3e12..dea7b08b3 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-primitives.tex @@ -296,6 +296,7 @@ new primitives, a summary is given below. \NC \type {iffrozen} \NC command \NC \NC \NR \NC \type {iftok} \NC \NC \NC \NR \NC \type {ifcstok} \NC \NC \NC \NR +\NC \type {ifboolean} \NC \NC \NC \NR \NC \type {internalcodesmode} \NC integer \NC \NC \NR %NC \type {ifprimitive} \NC command \NC check if the given command is a primitive \NC \NR \NC \type {immediateassigned} \NC command \NC (todo) expand the following assignment now\NC \NR diff --git a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex index 56fffeafa..40e6b5a84 100644 --- a/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex +++ b/doc/context/sources/general/manuals/luametatex/luametatex-tex.tex @@ -2115,7 +2115,9 @@ expanded definition (\prm {edef}'d). In the case of the braced variant one can o course use the \prm {detokenize} and \prm {unexpanded} primitives since there we do expand. -The \type {scan_word} scanner can be used to implement for instance a number scanner: +The \type {scan_word} scanner can be used to implement for instance a number +scanner. An optional boolean argument can signal that a trailing space or \type +{\relax} should be gobbled: \starttyping function token.scan_number(base) diff --git a/doc/context/sources/general/manuals/units/units-mkiv.tex b/doc/context/sources/general/manuals/units/units-mkiv.tex index ba4f12787..db9306e6c 100644 --- a/doc/context/sources/general/manuals/units/units-mkiv.tex +++ b/doc/context/sources/general/manuals/units/units-mkiv.tex @@ -508,6 +508,40 @@ Which gives: \stopsection +\startsection[title={Goodies}] + +Here are some goodies: + +\startbuffer +\type{1 } : \unit {30^2 meter per second} +\type{2a} : \unit {30 ± 10 meter per second} +\type{2b} : \unit {30 – 10 meter per second} +\type{3a} : \unit {30^2 ± 10^2 meter per second} +\type{3b} : \unit {30^2 – 10^2 meter per second} +\type{4 } : \unit {30 (10) meter per second} +\type{5a} : \unit {30 (± 10) meter per second} +\type{5b} : \unit {30^2 (± 10^2) meter per second} +\type{6a} : \unit {(30 ± 10) meter per second} +\type{6b} : \unit {(30^2 ± 10^2) meter per second} +\type{6c} : \unit {(30^2 – 10^2) meter per second} +\type{7a} : \unit {(30 ± 10)^2 meter per second} +\type{7b} : \unit {(30 – 10)^2 meter per second} +\type{7c} : \unit {(30^2 – 10^3)^5 meter per second} +\stopbuffer + +Instead of \type {±} one can use \type {pm} and \type {to} can be used instead of +\type {–}. + +\typebuffer + +Their rendering explains their intention: + +\startlines +\getbuffer +\stoplines + +\stopsection + \startsection[title={Built in keywords}] A given sequence of keywords is translated in an list of internal @@ -541,6 +575,8 @@ These are also special: \showunits[packaged] +\stopsection + \startsection[title={Colofon}] \starttabulate[|B|p|] |