System Macros/Branches and Decisions
< Prev: Definitions & Assignments | Top: System Macros | Next: Loops and Recursion >
Contents
- 1 Introduction
- 2 \doifnextcharelse
- 3 \doifundefined, \doifdefined, etc.
- 4 \doif, \doifnot, \doifelse
- 5 \doifempty, \doifnotempty, \doifemptyelse
- 6 \doifinset, \doifnotinset, \doifnotinsetelse
- 7 \doifcommon, \doifnotcommon, \doifcommonelse
- 8 \doifsamestringelse,\doifsamestring,\doifnotsamestring
- 9 \doifinstringelse,\doifincsnameelse
- 10 \doifnumberelse
- 11 \doifassignmentelse
- 12 \doiftext, \doiftextelse
Introduction
This page describes the conditional expressions available in ConTeXt.
See also: \doif...
\doifnextcharelse
When Pragma ADE started using TeX in the late eighties, their first experiences with programming concerned a simple shell around LaTeX. The commands probably used most at Pragma ADE are the itemizing ones. One of those initial shell commands took care of an optional argument, that enabled the specification of the item symbol to be used. Without understanding anything they were able to locate a LaTeX macro that could be used to inspect the next character.
It is that macro that the ancester of the next one presented here. It executes one of two actions, dependant of the next character. Disturbing spaces and line endings, which are normally interpreted as spaces too, are skipped.
\doifnextcharelse {char} {then ...} {else ...}
\doifundefined, \doifdefined, etc.
The standard way of testing if a macro is defined is comparing its meaning with another undefined one, aptly named \undefined
. To guarantee correct working of this set of macros, \undefined
may never be defined by a user!
\doifundefined {string} {...} \doifdefined {string} {...} \doifundefinedelse {string} {then ...} {else ...} \doifdefinedelse {string} {then ...} {else ...} \doifalldefinedelse {commalist} {then ...} {else ...}
\doif, \doifnot, \doifelse
Programming in TeX differs from programming in procedural languages like Modula. This means that one --- well, let me speek for myself --- tries to do the things in the well known way. Therefore the next set of \ifthenelse
commands were between the first ones we needed. A few years later, the opposite became true: when programming in Modula, I sometimes miss handy things like grouping, runtime redefinition, expansion etc. While Modula taught me to structure, TeX taught me to think recursive.
\doif {string1} {string2} {...} \doifnot {string1} {string2} {...} \doifelse {string1} {string2} {then ...}{else ...}
These macros test string equality of the (expanded) first two arguments.
\doifempty, \doifnotempty, \doifemptyelse
We complete our set of conditionals with:
\doifempty {string} {...} \doifnotempty {string} {...} \doifemptyelse {string} {then ...} {else ...}
This time, the string is not expanded. Remember to expand it yourself where needed.
\doifinset, \doifnotinset, \doifnotinsetelse
We can check if a string is present in a comma separated set of strings. Depending on the result, some action is taken.
\doifinset {string} {string,...} {...} \doifnotinset {string} {string,...} {...} \doifinsetelse {string} {string,...} {then ...} {else ...}
The second argument is the comma separated set of strings. If the first string expands 'empty', it is considered to be not in the set. The comma separated set is not expanded.
\doifcommon, \doifnotcommon, \doifcommonelse
Probably the most time consuming tests are those that test for overlap in sets of strings.
\doifcommon {string,...} {string,...} {...} \doifnotcommon {string,...} {string,...} {...} \doifcommonelse {string,...} {string,...} {then ...} {else ...}
\doifsamestringelse,\doifsamestring,\doifnotsamestring
The next comparison macro converts the arguments into
expanded strings. This command can be used to compare for
instance \jobname
with a name stored in a macro.
\doifinstringelse,\doifincsnameelse
We can check for the presence of a substring in a given sequence of characters.
\doifinstringelse {substring} {string} {then ...} {else ...}
The next alternative proved to be upto twice as fast on tasks like checking reserved words in pretty verbatim typesetting. This is mainly due to the fact that passing (expanded) strings is much slower that passing a macro.
\doifincsnameelse {substring} {\string} {then ...} {else ...}
Where \doifinstringelse
does as much expansion as possible, the latter alternative does minimal (one level) expansion.
\doifnumberelse
The next macro executes a command depending of the outcome of a test on numerals.It checks only the first character of string.
\doifnumberelse {string} {then ...} {else ...}
The macro accepts 123
, abc
, {}
, \anumber
and \the\count...
.
The definition of this macro is extremly ugly, or extremely beautiful, depending on how you feel about TeX macro expansion. It is the first of only a few that will actually appear in this series of articles, I promise.
\long\def\doifnumberelse#1% {\ifcase0\ifcase1#1\or\or\or\or\or\or\or\or\or\else1\fi\space \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi}
\doifassignmentelse
A lot of ConTeXt commands take optional arguments, for instance:
\dothisorthat[alfa,beta] \dothisorthat[first=foo,second=bar] \dothisorthat[alfa,beta][first=foo,second=bar]
Although a combined solution is possible, we prefer a seperation. The next command takes care of propper handling of such multi-faced commands.
\doifassignmentelse {...} {then ...} {else ...}
\doiftext, \doiftextelse
See https://www.mail-archive.com/ntg-context@ntg.nl/msg73506.html for details.
\define\CustomHeader{% \cap{\ss{\| % \doiftextelse{\getmarking[chapter]}% {\getmarking[chapter]}% {Contents}% }} }
\setupheadertexts[\CustomHeader{}][][][\CustomHeader{}]
< Prev: Definitions & Assignments | Top: System Macros | Next: Loops & Recursion >