diff options
Diffstat (limited to 'doc/context/sources/general/manuals/texit')
8 files changed, 886 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/texit/texit-conditions.tex b/doc/context/sources/general/manuals/texit/texit-conditions.tex new file mode 100644 index 000000000..83fb0a7bc --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-conditions.tex @@ -0,0 +1,108 @@ +\environment texit-style + +\startcomponent texit-conditions + +\startchapter[title={Conditions}] + +In case you wonder why we have modes in \CONTEXT, here is an example that might +convince you. The \TEX\ language has conditionals and they are in fact quite +efficient, take for instance: + +\startTEX +\ifnum\scratchcounter>10 + \ifdim\scratchdimen>10pt + one + \else + two + \fi +\else + three +\fi +\stopTEX + +When the first test fails, \TEX\ will do a fast scan over the following tokens +and expand the \type {three} branch. In order to do such a fast scan, the nested +condition needs to be properly balanced: the \type {\else} is optional but the +nested \type {\fi} definitely isn't. Now imagine that you use a few pseudo +booleans, like: + +\startTEX +\newif\ifalpha \alphatrue +\newif\ifbeta \betatrue +\stopTEX + +And you need it in: + +\startTEX +\ifalpha + \ifbeta + YES + \else + NOP + \fi +\else + NOP +\fi +\stopTEX + +This happens occasionally in real applications and one can either repeat the +\type {NOP} or wrap it in a macro in order to save tokens. However, way more +natural would be something like this: + +\startTEX +\ifalphaorbeta + YES +\else + NOP +\fi +\stopTEX + +This basically would introduce a new kind concept: an expandable macro flagged as +\type {\if} kind of token. I actually experimented with that in \LUATEX\ but +rejected it eventually. Instead \type {\ifcondition} was introduced. This is +basically equivalent to \type {\iffalse} when \TEX\ is in fast \type {\if*} +skipping mode, but when a real test happens the next argument is expanded. That +macro is expected to end up as something equivalent to \type {\iftrue} or \type +{\iffalse} so that other the nexct branch or the \type {\else} is entered. Here +is an example: + +\startTEX +\ifcondition\alphaorbeta + YES +\else + NOP +\fi +\stopTEX + +There are several ways to define \type {\alphaorbeta} now and we show a few here. +It's up to you to figure out which ons is the most efficient. + +\startTEX +\def\alphaorbeta{\ifcase0\ifalpha \else\ifbeta \else1\fi\fi\relax} +\def\alphaorbeta{\ifcase \ifalpha0\else\ifbeta0\else1\fi\fi\relax} +\def\alphaorbeta{\ifnum1=\ifalpha1\else\ifbeta1\else0\fi\fi\relax} +\def\alphaorbeta{\ifnum 0\ifalpha1\fi \ifbeta1\fi >1\relax} +\stopTEX + +Now, do we expect users to come up with such constructs? Of course not. Even in +\CONTEXT\ we don't really need them, although there are a few places where they +can be used. In \CONTEXT\ you would just do this: + +\startTEX +\enablemode[alpha] +\enablemode[beta] + +\doifelsemode {alpha,beta} { + YES +} { + NOP +} +\stopTEX + +Of course such a verbose macro is less efficient but even if you use this test +10.000 times in a run it will not take more than 0.06 seconds on a decent 2013 +laptop. + +\stopchapter + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit-contents.tex b/doc/context/sources/general/manuals/texit/texit-contents.tex new file mode 100644 index 000000000..f22db1c38 --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-contents.tex @@ -0,0 +1,9 @@ +\environment texit-style + +\startcomponent texit-contents + +\starttitle[title={Contents}] + \placelist[chapter] +\stoptitle + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit-introduction.tex b/doc/context/sources/general/manuals/texit/texit-introduction.tex new file mode 100644 index 000000000..cfe87c25a --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-introduction.tex @@ -0,0 +1,24 @@ +\environment texit-style + +\startcomponent texit-introduction + +\startchapter[title={Introduction}] + +I needed a place to collect examples of \TEX\ coding and this is it. The examples +presented here are an unorganized bunch. Some originate in questions asked on the +mailing list. Others are byproducts of tests made when playing with some (new) +functionality. When you plan to use \TEX\ for a long time, it doesn't hurt to see +a bit of \TEX\ coding but when possible I will also show the \CONTEXT\ way. + +I hope that this document is useful. You can of course always try to challenge me +for more examples. Hopefully I will not forget about this document and extend it +occasionaly. + +\startlines +Hans Hagen +Hasselt NL +\stoplines + +\stopchapter + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit-leaders.tex b/doc/context/sources/general/manuals/texit/texit-leaders.tex new file mode 100644 index 000000000..ed224da5c --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-leaders.tex @@ -0,0 +1,247 @@ +\environment texit-style + +\startcomponent texit-leaders + +\startchapter[title={Leaders}] + +The following example comes from a question on the \CONTEXT\ list. It +exhibits a few low level tricks. For the purpose of this example we +use \type {\ruledhbox} instead of \type {\hbox}. We start with a simple +command that puts something at the end of a line: + +\startbuffer +\starttexdefinition MyFill #1 + \removeunwantedspaces + \hfill + \ruledhbox{#1} +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +We use this in: + +\startbuffer[sample] +\startitemize[packed,joinedup][rightmargin=3em] + \startitem + \samplefile{ward}\MyFill{DW} + \stopitem +\stopitemize +\stopbuffer + +\typebuffer[sample][option=TEX] + +and get: + +\getbuffer[sample] + +But, the requirement was that we move the number towards the right margin, so +instead we need something: + +\startbuffer +\starttexdefinition MyFill #1 + \removeunwantedspaces + \hfill + \rlap{\ruledhbox to \rightskip{\hss#1}} +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +This already looks more like it: + +\getbuffer[sample] + +But also part of the requirements was that there should be dots between the end +of the last sentence and the number. In low level \TEX\ speak that means using +leaders: repeated boxed content where the repitition is driven by a glue +specification. Let's naively use leaders now: + +\startbuffer +\starttexdefinition MyFill #1 + \leaders + \ruledhbox to 1em{\hss.\hss} + \hfill + \ruledhbox{#1} +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +Let's see what we get: + +\getbuffer[sample] + +Again we need to move the number to the right. This time we need a different +solution because we need to fill the space in between. When \TEX\ ends a +paragraph it adds \type {\parfillskip} so we will now manipulate that parameter. + +\startbuffer +\starttexdefinition MyFill #1 + \parfillskip-1\rightskip plus 1fil\relax + \leaders + \ruledhbox to 1em{\hss.\hss} + \hfill + \ruledhbox{#1} +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +Does it look better? + +\getbuffer[sample] + +Indeed it does, but watch this: + +\startbuffer[sample] +\startitemize[packed,joinedup][rightmargin=8.5em] + \startitem + \samplefile{ward}\MyFill{DW}\par + \samplefile{ward}\par + \samplefile{ward}\MyFill{DW} + \stopitem +\stopitemize +\stopbuffer + +\typebuffer[sample][option=TEX] + +The first \type {\MyFill} will set the \type {\parfillskip} to a value that will +also be used later on. + +\getbuffer[sample] + +The way out is the following + +\startbuffer +\starttexdefinition MyFill #1 + \begingroup + \parfillskip-1\rightskip plus 1fil\relax + \leaders + \ruledhbox to 1em{\hss.\hss} + \hfill + \ruledhbox{#1} + \par + \endgroup +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +This looks more or less okay. The \type {\par} keeps the adaption local but for +it to work well, the \type {\par} must be inside the group. + +\getbuffer[sample] + +Now it's time to go for perfection! First of all, we get rid of any leading +spacing. If we need some we should inject it after a cleanup. We also use a +different leader command. Instead of \type {to} we use a \type {spread} so that +we get half the emwidth and not something slightly less due to the width of the +period. + +\startbuffer +\starttexdefinition MyFill #1 + \removeunwantedspaces + \begingroup + \parfillskip-1\rightskip plus 1fil\relax + \cleaders + \ruledhbox spread 1em{\hss.\hss} + \hfill + \ruledhbox{#1} + \par + \endgroup +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +So, we end up here: + +\startbuffer[sample] +\startitemize[packed,joinedup][rightmargin=5em] + \startitem + \samplefile{sapolsky}\MyFill{RS}\par + \stopitem +\stopitemize +\stopbuffer + +\getbuffer[sample] + +For which we used this: + +\typebuffer[sample][option=TEX] + +Finally we get rid of the tracing: + +\startbuffer +\starttexdefinition unexpanded MyFill #1 + \begingroup + \parfillskip-1\rightskip plus 1fil\relax + \leaders + \hbox to \emwidth{\hss.\hss} + \hfill + \hbox{#1} + \par + \endgroup +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +Watch a few more details. It brings us to: + +\getbuffer[sample] + +\page + +\startbuffer +\definefiller + [MyFiller] + [offset=.25\emwidth, + method=middle] + +\starttexdefinition unexpanded MyFill #1 + \begingroup + \parfillskip-1\rightskip plus 1fil\relax + \filler[MyFiller]% + \hbox{#1} + \par + \endgroup +\stoptexdefinition +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +\getbuffer[sample] + +When writing these examples I realized that it's rather trivial to add this +option to the already existing filler mechanism. The definition of such a filler +looks like this: + +\startbuffer +\definefiller + [MyFiller] + [offset=.25\emwidth, + rightmargindistance=-\rightskip, + method=middle] +\stopbuffer + +\typebuffer[option=TEX] \getbuffer + +\startbuffer[sample] +\startitemize[packed,joinedup][rightmargin=5em] + \startitem + \samplefile{sapolsky}\fillupto[MyFiller]{RS} + \stopitem +\stopitemize +\stopbuffer + +The sample code now becomes: + +\typebuffer[sample][option=TEX] + +Ans as expected renders as: + +\getbuffer[sample] + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit-lookahead.tex b/doc/context/sources/general/manuals/texit/texit-lookahead.tex new file mode 100644 index 000000000..03eaecabe --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-lookahead.tex @@ -0,0 +1,387 @@ +\environment texit-style + +\startcomponent texit-lookahead + +\startchapter[title={Lookahead}] + +When you look at the \TEX\ source of a macro package, your can often see +constructs like this: + +\startTEX +\def\foo#1% + {We do something with "#1".} +\stopTEX + +or maybe: + +\startTEX +\def\foo#1{% + We do something with "#1".% +} +\stopTEX + +Normally the percentage symbol is used to indicate a comment, but here +are no comments. In these cases, it makes the definition effectively + +\startTEX +\def\foo#1{do something with "#1"!} +\stopTEX + +which is different from when we would not have that percent sign there: + +\startTEX +\def\foo#1 {We do something with "#1"!} +\stopTEX + +That variant is valid \TEX\ code but expects a space as delimiter of the +argument to \type {\foo}. This means that you can say: + +\startTEX +\foo{1} \foo 2 \foo {34} and \foo 56 . +\stopTEX + +while this can trigger an error message (when no space is seen at some point) or +at least give unexpected results. + +\startTEX +\foo{1}\foo 2\foo {34}and\foo 56. +\stopTEX + +A different use of the percent is seen in cases like this: + +\startTEX +\def\foo#1% + {We do something % + with "#1".} +\stopTEX + +This time we want to preserve the space after \type {something} because an +end|-|of|-|line would either or not collapse it with \type {with} depending on +how the endofline character is set up. Normally + +\startTEX +\def\foo#1% + {We do something + with "#1".} +\stopTEX + +will also add a space after something but when \TEX\ is set up to ignore lines +you get a collapse. So the explicit space is a robust way out. Both cases of +using or omitting the comment symbol are easy to spot as they trigger an error +or result in weird typeset results. + +\startbuffer[defs] +\def\fooA#1% + {\ifnum#1>100 + yes\else nop% + \fi} + +\def\fooB#1{\ifnum#1>100 yes\else nop \fi} + +\def\fooC#1% + {\ifnum#1>100% + yes\else nop% + \fi} +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +We test this with: + +\startbuffer[demo] +\fooA{100} \fooB{100} \fooC{100} +\fooA{101} \fooB{101} \fooC{101} +\stopbuffer + +\typebuffer[demo][option=TEX] + +And the result is probably what you expect: + +\startlines +\getbuffer[demo] +\stoplines + +\startbuffer[defs] +\def\fooA#1% + {\ifnum#1>100 + 1\else 0% + \fi} + +\def\fooB#1{\ifnum#1>100 1\else 0\fi} + +\def\fooC#1% + {\ifnum#1>100% + 1\else 0% + \fi} +\stopbuffer + +However, when we have the following macro body: + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +We get this output. Do you see the issue? + +\startlines +\getbuffer[demo] +\stoplines + +A preferred way to catch this is the following as a \type {\relax} ends scanning +for a number: + +\startbuffer[defs] +\def\foo#1% + {\ifnum#1>100\relax + 1\else 0% + \fi} +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +However, watch what happens here: + +\startbuffer[demo] +\edef\result{\foo{123}} +\stopbuffer + +\typebuffer[demo][option=TEX] \getbuffer[demo] + +The \type {\result} macro has the following body: + +\expanded{\setbuffer[result]\meaning\result\endbuffer} + +\typebuffer[result][option=TEX] + +A neat trick out of this is the following: + +\startbuffer[defs] +\def\foo#1% + {\ifnum#1>\numexpr100\relax + 1\else 0% + \fi} +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +\getbuffer[demo] + +Now the body of \type {\result} looks like this: + +\expanded{\setbuffer[result]\meaning\result\endbuffer} + +\typebuffer[result][option=TEX] + +Of course this also works: + +\startTEX +\def\foo#1% + {\ifnum#1>100 % + 1\else 0% + \fi} +\stopTEX + +as a space also delimits scanning the number. But that method can actually introduce +that space in the output. Think of this definition: + +\startbuffer[defs] +\def\foo#1#2% + {\ifnum#1>#2 % + 1\else 0% + \fi} +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +What if \type {#2} has a trailing space? What if it is a verbose number? What if +it is a counter variable? + +\startbuffer[demo] +\scratchcounter=100 + [\foo{101}{100}] [\foo{101}{100 }] [\foo{101}\scratchcounter] +\scratchcounter=101 + [\foo{100}{101}] [\foo{100}{101 }] [\foo{100}\scratchcounter] +\stopbuffer + +\typebuffer[demo][option=TEX] + +\startlines +\getbuffer[demo] +\stoplines + +If you really want to introduce an unpredictable situation, use a coding style like +this: + +\startTEX +\def\foo#1#2#3#4{\if#1=#2#3\else#4\fi} +\stopTEX + +This is not that imaginary as you often see users play safe and do things like this: + +\startTEX +\ifnum\scratchcounterone=\scratchcountertwo% + ... +\else + ... +\fi +\stopTEX + +Here the percent sign is useless as the number scanner already got the number, +just try: + +\startTEX +\scratchcounterone=1 +\scratchcountertwo=1 + +\ifnum\scratchcounterone=\scratchcountertwo + yes +\else + nop +\fi +\stopTEX + +A previous one liner formatted like this really is not better! + +\startTEX +\def\foo#1#2#3#4% + {\ifnum#1=#2% + #3% + \else + #4% + \fi} +\stopTEX + +When you define macros more often than not you don't want unexpected spaces (aka spurious spaces) +which is why in \CONTEXT\ for instance setups ignores lines: + +\startbuffer[defs] +\startsetups foo + here + we ignore + spaces at the end + of a line +\stopsetups +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +so we get: \quotation {\directsetup{foo}} which means that the normally few times +that we {\em do} want spaces we need to be explicit: + +\startbuffer[defs] +\startsetups foo + here\space + we ignore\space + spaces at the end\space + of a line\space +\stopsetups +\stopbuffer + +\typebuffer[defs][option=TEX] \getbuffer[defs] + +Now we're okay: \quotation {\directsetup{foo}}. The same is true for: + +\startTEX +\starttexdefinition foo + here\space + we ignore\space + spaces at the end\space + of a line\space +\stoptexdefinition +\stopTEX + +There are more cases where \TEX\ will look further. Take for example skip (glue) +scanning. A glue specification can have \type {plus} and \type {minus} fields. + +\startbuffer[defs] +\scratchdimenone=10pt +\scratchskipone =10pt plus 10pt minus 10pt +\scratchskiptwo =0pt +\stopbuffer + +\typebuffer[defs][option=TEX] + +Now take the following test: + +\startbuffer[demo] +{1 \scratchskiptwo 10pt plus 10pt \relax\the\scratchskiptwo} +{2 \scratchskiptwo \scratchdimenone plus 10pt \relax\the\scratchskiptwo} +{3 \scratchskiptwo 1\scratchdimenone plus 10pt \relax\the\scratchskiptwo} +{4 \scratchskiptwo \scratchskipone plus 10pt \relax\the\scratchskiptwo} +{5 \scratchskiptwo 1\scratchskipone plus 10pt \relax\the\scratchskiptwo} +\stopbuffer + +\typebuffer[demo][option=TEX] + +\startlines +\inlinebuffer[defs]\getbuffer[demo] +\stoplines + +If you wonder what the second \type {\relax} does, here is a variant: + +\startlines +{1 \scratchskiptwo 10pt plus 10pt \the\scratchskiptwo} +{2 \scratchskiptwo \scratchdimenone plus 10pt \the\scratchskiptwo} +{3 \scratchskiptwo 1\scratchdimenone plus 10pt \the\scratchskiptwo} +{4 \scratchskiptwo \scratchskipone plus 10pt \the\scratchskiptwo} +{5 \scratchskiptwo 1\scratchskipone plus 10pt \the\scratchskiptwo} +\stoplines + +\typebuffer[demo][option=TEX] + +\startlines +\inlinebuffer[defs]\getbuffer[demo] +\stoplines + +In this second variant \TEX\ happily keep looking for a glue specification when +it sees the \type {\the} so it serializes \type {\scratchskiptwo}. But as it sees +\type {0pt} then, it stops scanning the glue spec. What we get typeset is the old +value, not the new one! If you want to prevent this you need to \type {\relax}. + +Another case where \TEX\ keeps scanning is the following: + +\startbuffer[demo] +\vrule width 40pt height 2pt depth 5pt \quad +\vrule width 40pt height 20pt depth 5pt height 10pt \quad +\vrule width 40pt height 10pt height 20pt \quad +\vrule width 40pt height 20pt depth 5pt height 10pt width 80pt +\stopbuffer + +\typebuffer[demo][option=TEX] + +This gives the rules: + +\startlinecorrection \darkgray +\getbuffer[demo] +\stoplinecorrection + +So you can overload dimensions. The space before the \type {quad} is gobbled as +part of the look ahead for more keywords. + +Often rules (just like glue assignments) are wrapped in macro definitions where the +macro writer used \type {\relax} to look ahead. That way you prevent an error message +in cases like: + +\startTEX +\def\foo{\vrule width 40pt height 2pt} + +The \foo depth of this thought is amazing. +\stopTEX + +because \type {of} definitely is not a valid dimension. Even more subtle is: + +\startTEX +\def\foo{\hskip 10pt plus 1fil} + +The \foo fine points of typesetting can actually become a nightmare. +\stopTEX + +As \TEX\ will now see the \type {f} of \type {fine} as further specification and +think that you want \type {1fill}. + +So, the most important lesson of this chapter is that you need to be aware of the way +\TEX\ scans for quantities and specifications. In most cases the users can safely use +a \type {\relax} to prevent a lookahead. And try to avoid adding percent signs all +over the place. + +\stopchapter + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit-style.tex b/doc/context/sources/general/manuals/texit/texit-style.tex new file mode 100644 index 000000000..bee526d7b --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-style.tex @@ -0,0 +1,52 @@ +\startenvironment texit-style + +\setupbodyfont + [dejavu,11pt] + +\setuphead + [chapter] + [style=\bfc, + header=empty, + color=darkgray] + +\setuplist + [chapter] + [alternative=c, + width=1.5em] + +\setuplayout + [width=middle, + height=middle, + topspace=15mm, + backspace=15mm, + header=15mm, + footer=0mm] + +\setupwhitespace + [big] + +\setupheadertexts + [] + +\setupheadertexts + [] + [{\getmarking[chapter]\quad\pagenumber}] + [{\pagenumber\quad\getmarking[chapter]}] + [] + +\setupheader + [style=\bf, + color=darkgray] + +% \setuptype +% [color=darkred] + +% \setuptyping +% [color=darkred] + +\setuppagenumbering + [alternative=doublesided] + +\usemodule[scite] + +\stopenvironment diff --git a/doc/context/sources/general/manuals/texit/texit-titlepage.tex b/doc/context/sources/general/manuals/texit/texit-titlepage.tex new file mode 100644 index 000000000..1b7cabe84 --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit-titlepage.tex @@ -0,0 +1,40 @@ +\environment texit-style + +\startcomponent texit-titlepage + +\startMPpage + +fill Page + withcolor "darkyellow" + withtransparency (1,.75) ; + +draw image ( + for i=1 upto 500 : + draw (((1,-2) ... origin ... (-1,2)) randomized 0.2) + scaled 1cm + rotated (0 randomized 15) + shifted (origin randomized (PaperWidth,PaperHeight)) + withpen pencircle yscaled 5mm xscaled 2mm rotated 45 + withcolor "darkmagenta" + withtransparency (1,.5) + ; + endfor ; +) shifted center Page ; + +clip currentpicture to Page ; + +draw textext.ulft ("\TeX it") ysized 5cm % indeed, no space after \TeX ! + shifted lrcorner Page shifted (-1cm,1cm) + withcolor white ; + +draw textext.llft ("Hans Hagen") ysized 1cm + rotated 90 + shifted urcorner Page shifted (-15mm,-1cm) + withcolor white ; + +\stopMPpage + +\startstandardmakeup[doublesided=no,page=no] +\stopstandardmakeup + +\stopcomponent diff --git a/doc/context/sources/general/manuals/texit/texit.tex b/doc/context/sources/general/manuals/texit/texit.tex new file mode 100644 index 000000000..b8b70c00d --- /dev/null +++ b/doc/context/sources/general/manuals/texit/texit.tex @@ -0,0 +1,19 @@ +\environment texit-style + +\startdocument + +\component texit-titlepage + +\startfrontmatter + \component texit-contents + \component texit-introduction +\stopfrontmatter + +\startbodymatter + \component texit-lookahead + \component texit-conditions + \component texit-leaders + % \component texit-efficiency +\stopbodymatter + +\stopdocument |