Changes

Jump to navigation Jump to search
9,005 bytes added ,  23:02, 18 July 2019
Paragraph in a group issue
will cause ConTeXt to break the page.
Ordinarily this works as expected, unless, however, the heading
immediately follows a previous section heading with no text in between.
The rationale behind this is that consecutive headings are conceived of
collectively as one single structural element.
as in the Plain format) and the more familiar {{cmd|dontleavehmode}}
({{src|syst-aux.mkiv}}).
Just use the chosen macro immediately before the <code>\framed</code> macro and
everything should be fine:
\stoptext
</context>
 
=== The “paragraph in a group” problem ===
 
Another common issue with sidefloats is starting a paragraph in a group.
 
<context source="yes" mode="mkiv">
\placefigure[right,none]{}{\externalfigure[cow][width=0.25\textwidth]}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 
{\bf Oeps} \samplefile{lorem}
</context>
As you can see the paragraph starting with “Oeps” just overflows into the picture.
That is a well-known problem and there are posts about it on the mailing
list every once in a while. The sidefigure mechanism uses <code>\parshape</code> to
make the paragraph flow around the figure. The <code>\parshape</code> primitive only
applies to a single paragraph, so ConTeXt communicates the current
<code>\parshape</code> settings to the next paragraph using <code>\everypar</code>. However, when
a new paragraph starts in a group, i.e.
<texcode>
{\bf Oeps} ...
</texcode>
TeX inserts the <code>\everypar</code> tokens inside that group because only the
first letter starts the paragraph. That is to say is effectively looks
like this
<texcode>
% \everypar inserted inside the group
% ~~~v
{\bf \the\everypar Opes} ...
% ~~~~~~~~~~~~~~~~~~~~~^
% Setting of \everypar are discarded again when leaving the group and \parshape is lost.
</texcode>
You have to explicitly start a new paragraph before opening a group.
The easiest way to do this is
<texcode>
\dontleavehmode{\bf Oeps} ...
</texcode>
Now the <code>\everypar</code> tokens are inserted directly after {{cmd|dontleavehmode}}
outside the group and the problem goes away.
= Syntax =
What’s the status of this?
-->
 
== Treacherous Dimensions ==
 
At some places dimension-lookalikes are expected but they do not behave
exactly as in TEX per se because they are evaluated differently.
A very common example is the command {{cmd|setupbodyfont}} that is
possibly called, albeit implicitly, in every production document.
Its argument, the ''font size'', although it may look like an ordinary
dimension expression, will not have the same result if it has zeros
prepended or decimal places are specified.
 
Suppose you want to set the main font to a very large size:
 
<texcode>
\setupbodyfont[42pt]
\starttext foobar \stoptext
</texcode>
 
this works out well as long as you do not mistake the expression
''42pt'' to be a real dimension.
 
In TEX dimensions (which are really just integers) are treated the same
irrespective of leading or trailing zeros used in the variable
assignment.
Thus the following are all equivalent:
 
<texcode>
\newdimen\fortytwo\fortytwo=42pt
\newdimen\fortytoo\fortytoo=042pt
\newdimen\fortytww\fortytww=42.00pt
 
\starttext
\the\fortytwo\ \ifnum\fortytwo=\fortytoo\m{\top}\else\m{\bot}\fi\par
\the\fortytoo\ \ifnum\fortytwo=\fortytww\m{\top}\else\m{\bot}\fi\par
\the\fortytww\ \ifnum\fortytoo=\fortytww\m{\top}\else\m{\bot}\fi\par
\stoptext
</texcode>
 
However, this does not hold for the Context commands
{{cmd|setupbodyfont}} and {{cmd|switchtobodyfont}}.
With the latter macros, only the ''pure-integer'' specification
(<code>42pt</code>) can be used reliably, everything else, even though it
denotates the same TEX dimension, will result in a warning:
 
<pre>
fonts > bodyfont 42.0pt is defined (can better be done global)
</pre>
 
Additionally, if the code in question relies on font switching a lot
(e.&nbsp;g. Lua snippets that calculcate font sizes from floating point
numbers), there will be a ''huge'' perfomance penalty because everytime
a font switch occurs, the font will be reloaded entirely.
The reason for this is that the process of defining a font for the main
text is accompanied by a myriad of secondary definitions for different
relative font sizes ({{cmd|tfx|link=no}}, {{cmd|tfa|link=no}}
[[Font_Switching#Font_sizes|and the likes]]) and shapes &ndash; the
creation of the ''body font environment''.
If the “size” requested by {{cmd|setupbodyfont}} cannot be found in the
internal table, this environment will be rebuilt on the spot.
 
''It is also not possible to catch these cases by predefining the corresponding bodyfont environments''
by placing {{cmd|definebodyfontenvironment}} statements in the preamble.
So if you have, say:
 
<texcode>
\definebodyfontenvironment[42.0pt]
\definebodyfontenvironment[042pt]
\definebodyfontenvironment[042.0pt]
\starttext
\setupbodyfont[42.0pt] foo bar
\setupbodyfont[042pt] foo bar
\setupbodyfont[042.0pt] foo bar
\stoptext
</texcode>
 
the warning and slowdown will occur regardless.
The only real option is to serve {{cmd|setupbodyfont}} and the likes
natural integers only.
 
Alternatively you can always employ raw font definitions, if there
isn’t any need for the environment in the first place:
<texcode>
\starttext
\definedfont[file:iwona-regular.otf at 42.0pt] foo bar
\definedfont[file:iwona-regular.otf at 042pt] foo bar
\definedfont[file:iwona-regular.otf at 042.0pt] foo bar
\stoptext
</texcode>
Here the dimensions are ''real''.
 
For further information see
[http://www.ntg.nl/pipermail/ntg-context/2012/067324.html this] and
[http://www.ntg.nl/pipermail/ntg-context/2012/066940.html this]
thread on the mailing list.
 
 
= Multipass =
 
In some circumstances, portions of code are evaluated two or more
times.
This can be disruptive in contexts where the order of actions is
important.
 
== Trialtypesetting ==
 
Often the size of elements must be calculated prior to determining the
optimal placements.
Probably the most common example are tables:
In order to align cells correctly the dimensions of later parts of the
document must already be determined before anything is typeset.
The stage during which this takes place is called *trial typesetting*.
 
The system mode ''trialtypesetting'' allows fine-grained control over
what code should be executed during what stage.
For instance, the naive definition of a macro that increments and
prints a counter register will behave erratically in tables:
 
<context source="yes" mode="mkiv">
\def \inccount {%
\incrementnumber [somecount]%
\getnumber [somecount]%
}
\definenumber [somecount]
\setnumber [somecount] [42]
 
\starttext
 
before \inccount
 
\startplacetable[location=here]
\bTABLE
\bTR \bTD \inccount \eTD \bTD \inccount \eTD \eTR
\eTABLE
\stopplacetable
 
after \inccount
 
\stoptext
</context>
 
To bypass the extra evaluation, wrap the incrementation part in an
<code>\iftrialtypesetting</code> conditional.
 
<context source="yes" mode="mkiv">
\def \inccount {%
\iftrialtypesetting \else
\incrementnumber [somecount]%
\fi
\getnumber [somecount]%
}
 
\definenumber [somecount]
\setnumber [somecount] [42]
 
\starttext
 
before \inccount
 
\startplacetable[location=here]
\bTABLE
\bTR \bTD \inccount \eTD \bTD \inccount \eTD \eTR
\eTABLE
\stopplacetable
 
after \inccount
 
\stoptext
</context>
 
 
Note that annoying as it may appear, the trial typesetting phase is
essential for certain features to work, so take extra care when
omitting it.
In the example above the number itself must be present as placeholder
during the first pass even though it has not been updated at this
point.
 
<texcode>
\def \inccount {%
\iftrialtypesetting \else
\incrementnumber [somecount]%
\getnumber [somecount]% <= wrong!
\fi
}
</texcode>
 
<context mode="mkiv" source="no">
\def \inccount {%
\iftrialtypesetting \else
\incrementnumber [somecount]%
\getnumber [somecount]%
\fi
}
 
\definenumber [somecount]
\setnumber [somecount] [42]
 
\starttext
 
before \inccount
 
\startplacetable[location=here]
\bTABLE
\bTR \bTD \inccount \eTD \bTD \inccount \eTD \eTR
\eTABLE
\stopplacetable
 
after \inccount
 
\stoptext
</context>
 
 
== Tables ==
 
In addition to trial typesetting Context also knows a ''table'' state:
 
<context mode="mkiv" source="yes">
\def \tablecheck {\ifintable In table. \else Outside table. \fi}
 
\starttext
\tablecheck
\startplacetable[location=here]
\bTABLE
\bTR \bTD \tablecheck \eTD \bTD \tablecheck \eTD \eTR
\eTABLE
\stopplacetable
\tablecheck %% decrement
\stoptext
</context>
 
== Metapost ==
 
As with TeX, Metapost sometimes requires multiple passes,
especially when processing text.
In below snippet, the Metapost tracer reveals that the code is actually
evaluated twice:
 
<texcode>
\enabletrackers[metapost.showlog]
\starttext
\startMPcode
show "This gets printed twice.";
label (btex Some label text etex, (0,0));
\stopMPcode
\stoptext
</texcode>
 
NB removing the <code>label</code> statement will result in the second
pass being omitted.
 
In [[Metafun]], the default Metapost format in Context, the booleans
<code>mfun_first_run</code> and <code>mfun_trial_run</code> allow
detecting the individual stages:
 
<texcode>
\enabletrackers[metapost.showlog]
\starttext
\startMPcode
if mfun_trial_run :
show "This gets printed during the trial pass.";
else :
show "This gets printed during the final pass.";
fi;
label (btex Some label text etex, (0,0));
\stopMPcode
\stoptext
</texcode>
28

edits

Navigation menu