Difference between revisions of "Modes"

From Wiki
Jump to navigation Jump to search
(Lots of changes. Just replacing with the new version)
Line 1: Line 1:
 
< [[The ConTeXt Way]] | [[Inside ConTeXt]] | [[Project structure]] >
 
< [[The ConTeXt Way]] | [[Inside ConTeXt]] | [[Project structure]] >
  
{{note | I am replacing this article with a detailed article that I am writing for TugBoat. For the time being I am leaving the original article at the end. Fell free to make any changes or to merge the examples of the original article. --[[User:Adityam|Aditya]]}}
+
Very often, you want to generate multiple versions of the same document:
 
+
one version for printing and one for viewing on the screen, one version for
Many-a-times, you want to to generate multiple versions of the same document.
+
students and one version for the instructor, and so on. You can do this in a
One version for printing and one for viewing on the screen; one version for
+
simple but naive way: create different files set up for the different versions and
students and one version for the instructor; and so on. You can do this a
 
naive way. Create different files with setup for the different versions and
 
 
<code>\input</code> the common material, or create some new conditional flags using
 
<code>\input</code> the common material, or create some new conditional flags using
 
<code>\newif</code> and set them appropriately for conditional processing. Or you
 
<code>\newif</code> and set them appropriately for conditional processing. Or you
could use '''modes'''&mdash;the ConTeXt way of doing conditional processing.
+
could use <em>modes</em>&mdash;the ConTeXt way of doing conditional processing.
 
 
  
 
= Introduction =
 
= Introduction =
  
A mode is similar to a conditional flag, but with a few advantages. New modes
+
A mode is similar to a conditional flag, but with a few advantages: new modes
 
need not be explicitly defined (no need for something like <code>\newif</code>),
 
need not be explicitly defined (no need for something like <code>\newif</code>),
multiple modes can be simultaneously enabled or disabled, the status of multiple
+
multiple modes can be simultaneously enabled or disabled, and the status of multiple
 
modes can be checked easily. Moreover, modes can be set from a command line
 
modes can be checked easily. Moreover, modes can be set from a command line
switch. So, multiple versions of a document can be generated without changing
+
switch. As a result, multiple versions of a document can be generated without changing
 
the source file.
 
the source file.
  
Line 24: Line 21:
 
spaces. Names starting with <code>*</code> are reserved for system modes.  
 
spaces. Names starting with <code>*</code> are reserved for system modes.  
  
 +
In this article I explain how to activate a mode and how to check if a mode is
 +
active or not.
  
 
= Setting modes =
 
= Setting modes =
Line 29: Line 28:
 
ConTeXt has three commands for setting modes:
 
ConTeXt has three commands for setting modes:
  
* <code><cmd>enablemode</cmd> [...]</code>
+
* <code><cmd>enablemode </cmd>[...]</code>
 
* <code><cmd>disablemode</cmd>[...]</code>
 
* <code><cmd>disablemode</cmd>[...]</code>
 
* <code><cmd>preventmode</cmd>[...]</code>
 
* <code><cmd>preventmode</cmd>[...]</code>
  
The names are self explanatory. <cmd>enablemode</cmd> activates a mode,
+
The names are self-descriptive. <cmd>enablemode</cmd> activates a mode,
 
<cmd>disablemode</cmd> deactivates a mode, and <cmd>preventmode</cmd> permanently
 
<cmd>disablemode</cmd> deactivates a mode, and <cmd>preventmode</cmd> permanently
 
deactivates a mode. All three commands take a list of modes as an argument. For
 
deactivates a mode. All three commands take a list of modes as an argument. For
example,  you can  activate <tt>screen</tt> and <tt>solution</tt> modes by
+
example,  you can  activate modes named <code>screen</code> and <code>solution</code> with
 
<texcode>
 
<texcode>
\enablemode[screen,solution]
+
    \enablemode[screen,solution]
 
</texcode>
 
</texcode>
  
 
Modes can also be activated by a command line switch <code>--modes</code> to
 
Modes can also be activated by a command line switch <code>--modes</code> to
<code>texexec</code> and <code>context</code>. For example, to activate <tt>screen</tt> and
+
<code>texexec</code> or <code>context</code>. For example, another way to activate the <code>screen</code> and
<tt>solution</tt> modes, you can run ConTeXt using
+
<code>solution</code> modes, to run ConTeXt using one of:
  
  texexec --mode=screen,solution ...
+
    texexec --mode=screen,solution ...
 +
    context --mode=screen,solution ...
  
or
 
  
  context --mode=screen,solution ...
 
  
To get different pdf output for different modes, you can add <code>--result</code> switch
+
= Conditional processing based on modes =
  
  context --mode=screen,solution --result=solution.pdf ...
+
You may want to process or ignore a chunk of code if a particular mode is enabled
 
+
or disabled. Such a chunk of code is specified using <code>\startmode</code> and
= Conditional processing based on modes =
+
<code>\startnotmode</code> environments. Their usable is best explained by an example.
  
 
Suppose you want to change the paper size of a document depending on whether it
 
Suppose you want to change the paper size of a document depending on whether it
is for print or screen. This can be done in multiple ways. You could either set
+
is for print or screen. This can be done in multiple ways. You could set
a default paper size for print and change it for screen:
+
the default paper size for print and change it in screen mode:
 
<texcode>
 
<texcode>
\setuppapersize[letter][letter]
+
  \setuppapersize[letter][letter]
 
+
  \startmode[screen]
\startmode[screen]
+
    \setuppapersize[S6][S6]
  \setuppapersize[S6][S6]
+
  \stopmode
\stopmode
 
 
</texcode>
 
</texcode>
 
(S6 is one of the screen-optimized paper sizes in ConTeXt; the paper size has a
 
(S6 is one of the screen-optimized paper sizes in ConTeXt; the paper size has a
4:3 aspect ratio and a width equal to the width of A4 paper.) Alternatively, you
+
4:3 aspect ratio and a width equal to the width of A4 paper.)
could set a default paper size for screen and change it if the screen mode is
+
 
 +
Alternatively, you
 +
could set a default paper size for the screen and change it if screen mode is
 
not enabled:
 
not enabled:
 
<texcode>
 
<texcode>
\setuppapersize[S6][S6]
+
  \setuppapersize[S6][S6]
 
+
  \startnotmode[screen]
\startnotmode[screen]
+
    \setuppapersize[letter][letter]
  \setuppapersize[letter][letter]
+
  \stopnotmode
\stopnotmode
 
 
</texcode>
 
</texcode>
  
<cmd>startmode</cmd> and <cmd>startnotmode</cmd> can check for multiple modes. The
+
<code>\startmode</code> and <code>\startnotmode</code> can check for multiple modes,
arguments to <cmd>startmode</cmd> and <cmd>startnotmode</cmd> can be a list of modes.
+
by giving a list of modes as their arguments. <code>\startmode</code>
<cmd>startmode</cmd> processes its contents (everything until the next
+
processes its contents (everything until the next
<cmd>stopmode</cmd> which means that <cmd>startmode</cmd> cannot be nested)
+
<code>\stopmode</code>, thus <code>\startmode</code> cannot be
if any of the modes are enabled, otherwise (i.e., when all the modes are
+
nested.) if any of the modes are enabled, otherwise (i.e., when all
disabled) <cmd>startmode</cmd> ignores it contents. <cmd>startnotmode</cmd> is the
+
the modes are disabled) <code>\startmode</code> ignores its
opposite. It processes its contents (everything until the next
+
contents. The opposite is <code>\startnotmode</code>: it processes its
<cmd>stopnotmode</cmd> if any of the modes are disabled, otherwise (i.e., when all
+
contents (everything until the next <code>\stopnotmode</code>) if any of the
the mods are enabled) <cmd>startnotmode</cmd> ignores its contents.
+
modes are disabled, otherwise&mdash;when all the modes are enabled&mdash;the contents are ignored.
  
<cmd>startmode</cmd> and <cmd>startnotmode</cmd> are <em>or</em> environments. They
+
<code>\startmode</code> and <code>\startnotmode</code> are "<em>or</em>" environments. They
 
process their contents if any of the modes satisfy the required condition. Their
 
process their contents if any of the modes satisfy the required condition. Their
<em>and</em> counterparts are <cmd>startallmodes</cmd> and <cmd>startnotallmodes</cmd>,
+
"<em>and</em>" counterparts are also available: <code>\startallmodes</code> and <code>\startnotallmodes</code>
which process their contents only if all the modes satisfy the required
+
process their contents only if all the given modes satisfy the required
condition. For example, suppose you want to enable interaction (hyperlinks) etc.
+
condition. For example, suppose you want to enable interaction (e.g., hyperlinks)
only when both <tt>screen</tt> and <tt>solution</tt> modes are enabled. Then you can
+
only when both <code>screen</code> and <code>solution</code> modes are enabled. Then you can
 
use:
 
use:
 
<texcode>
 
<texcode>
\startallmodes[screen,solution]
+
  \startallmodes[screen,solution]
  \setupinteraction[state=start]
+
    \setupinteraction[state=start]
\stopallmodes
+
  \stopallmodes
 
</texcode>
 
</texcode>
  
Line 105: Line 103:
 
<texcode>
 
<texcode>
 
\startmode[mode1, mode2, ...]
 
\startmode[mode1, mode2, ...]
   % Process if one of the modes is enabled
+
   % Processed if any of the modes is enabled
 
\stopmode
 
\stopmode
  
 
\startnotmode[mode1, mode2, ...]
 
\startnotmode[mode1, mode2, ...]
   % Process if one of the modes is disabled
+
   % Processed if any of the modes is disabled
 
\stopnotmode
 
\stopnotmode
  
 
\startallmodes[mode1, mode2, ...]
 
\startallmodes[mode1, mode2, ...]
   % Process if all modes are enabled
+
   % Processed if all the modes are enabled
 
\stopallmodes
 
\stopallmodes
  
 
\startnotallmodes[mode1, mode2, ...]
 
\startnotallmodes[mode1, mode2, ...]
   % Process if all the modes are disabled
+
   % Processed if all the modes are disabled
 
\stopnotallmodes
 
\stopnotallmodes
 
</texcode>
 
</texcode>
  
These environments have a <code>\doif</code> alternative that are useful for short
+
These environments have <code>\doif...</code> alternatives that are useful for short
setups and can also be nested.
+
setups.  Also, they can be nested.
  
 
<texcode>
 
<texcode>
Line 130: Line 128:
 
\doifnotallmodes {modes} {content}
 
\doifnotallmodes {modes} {content}
 
</texcode>
 
</texcode>
\noindentation
+
The logic for determining when the content is processed is exactly the same as
The logic for determining when the content is processes is exactly the same as
+
for the <code>start</code>-<code>stop</code> commands.
for the <code>start</code>-<code>stop</code> alternatives.
 
  
These <code>\doif</code> commands have a variant that can process something else if
+
These <code>\doif</code> commands each have a variant to process alternative code if
 
the conditions are not satisfied (like the <code>\else</code> branch of <code>\if</code>).
 
the conditions are not satisfied (like the <code>\else</code> branch of <code>\if</code>).
 
<texcode>
 
<texcode>
\doifmodeelse       {modes} {content} {alternative}
+
\doifmodeelse       {modes} {content} {alt}
\doifnotmodeelse     {modes} {content} {alternative}
+
\doifnotmodeelse   {modes} {content} {alt}
\doifallmodeselse   {modes} {content} {alternative}
+
\doifallmodeselse   {modes} {content} {alt}
\doifnotallmodeselse {modes} {content} {alternative}
+
\doifnotallmodeselse{modes} {content} {alt}
 
</texcode>
 
</texcode>
  
 
= System modes =
 
= System modes =
  
In addition to user-defined modes, ConTeXt provides some system modes. These
+
Besides allowing user-definable modes, ConTeXt provides some system
modes start with a <code>*</code>. Here I will only explain the more commonly used
+
modes. These modes start with a <code>*</code> character. Here I will explain
system modes. You can see the ConTeXt [http://pragma-ade.com/general/manuals/mmodes.pdf modes manual]
+
only the more commonly used system modes; see the ConTeXt [http://pragma-ade.com/general/manuals/mmodes.pdf modes manual]
for a complete list of system modes.
+
for a complete list.
  
 
Perhaps the most useful system modes are <code>*mkii</code> and <code>*mkiv</code> which
 
Perhaps the most useful system modes are <code>*mkii</code> and <code>*mkiv</code> which
determine whether MkII or MkIV is being used. These modes are handy when you
+
determine whether MKII or MKIV is being used. These modes are handy when you
want different setups for MkII and MkIV.
+
want different setups for MKII and MKIV.
  
 
Other modes are useful for very specific situations. Some of these are described
 
Other modes are useful for very specific situations. Some of these are described
 
below.
 
below.
  
A document multiple times to get the cross referencing, table of contents, etc.\
+
A document must be run multiple times to get the cross referencing,
right. However, sometimes you need to do some external processing (like graphic
+
table of contents, etc.
conversion) that only needs to be done only once. In such cases, the
+
right. However, sometimes you need to do some external processing (e.g., graphic
<code>*first</code> mode is handy, which checks for the first run of the document.  
+
conversion) that only needs to be done once. In such cases, the
 +
<code>*first</code> mode is handy&mdash;it is active only on the first run of the
 +
document.
  
 
You can use the project-product-component structure for managing large projects
 
You can use the project-product-component structure for managing large projects
 
like a book series. See [[Project structure]]
 
like a book series. See [[Project structure]]
for details. Both product and components can be compiled separately.
+
for details of this approach. A product or its components may be compiled
Sometimes you want to process a component differently depending on whether it is
+
separately, and you may want to do something different when a product is
being compiled directly, or if the complete product is being compiled. This can
+
compiled or when a component is compiled. To do so, you need to check for
be checked using the modes <code>*project</code>, <code>*product</code>, <code>*component</code>,
+
modes <code>*project</code>, <code>*product</code>, <code>*component</code>, and
and <code>*environment</code>. For example, the <code>*product</code> mode is set whenever a
+
<code>*environment</code>; these modes are set when the corresponding structure file
product file is read (more specifically, whenever a <code>\startproduct</code> is
+
is processed. For example, the <code>*product</code> mode is set whenever a
encountered). Similarly, a mode <code>*text</code> is enabled whenever a
+
product file is read; more specifically, when <code>\startproduct</code> is
<code>\starttext</code> is encountered.  
+
encountered. Similarly, a mode <code>*text</code> is enabled when
 +
<code>\starttext</code> is encountered, and likewise for the others.
  
A large document is also broken down into different section blocks like
+
A large document is typically broken down into different section blocks:
 
frontmatter, bodymatter, appendices, and backmatter. Internally, these section
 
frontmatter, bodymatter, appendices, and backmatter. Internally, these section
blocks are refered as <code>frontpart</code>, <code>backpart</code>, <code>appendix</code>, and
+
blocks are referred to as <code>frontpart</code>, <code>bodypart</code>, <code>appendix</code>, and
<code>backmatter</code>. Each section block sets a system mode with the same name. So,
+
<code>backpart</code>. Each section block sets a system mode with the same name. So,
if you want macros that work differently for different section blocks, you can
+
if you want macros that work differently in different section blocks, you can
check for <code>*fronpart</code>, <code>*backpart</code>, <code>*appendix</code>, and
+
check for modes <code>*frontpart</code>, <code>*bodypart</code>, and so on.
<code>*backmatter</code> modes.  
 
  
ConTeXt provides support for multiple language. Language are recognized by
+
ConTeXt provides support for multiple languages. Languages are recognized by
their IETF language tags, like <code>en-us</code> for US English, <code>en-gb</code>
+
their IETF language tags, like <code>en-us</code> for US
 +
English, <code>en-gb</code>
 
for British English, <code>nl</code> for Dutch, <code>de</code> for German, etc. A document
 
for British English, <code>nl</code> for Dutch, <code>de</code> for German, etc. A document
has a main language set using <code>\mainlanguage[...]</code> that is sued for
+
has a main language, set with the command <code>\mainlanguage[...]</code>,
 +
that is used for
 
translated labels like <em>chapter</em> and <em>figure</em>. You can also switch the
 
translated labels like <em>chapter</em> and <em>figure</em>. You can also switch the
 
current language using <code>\language[...]</code> to change the hyphenation rules.
 
current language using <code>\language[...]</code> to change the hyphenation rules.
Whenever a language is chosen, its id is set as mode. The mode for the main
+
Whenever a language is chosen, its identifier is set as a mode. The mode for the main
language starts with two <code>*</code>. For example, when the main language is US
+
language starts with two <code>*</code>. For example, when the main language
 +
is US
 
English and the current language is Dutch, the modes <code>**en-us</code> and
 
English and the current language is Dutch, the modes <code>**en-us</code> and
 
<code>*nl</code> are set (notice the extra <code>*</code> in <code>**en-us</code>).  
 
<code>*nl</code> are set (notice the extra <code>*</code> in <code>**en-us</code>).  
  
Other system modes are: <code>*figure</code> which is set when a graphic is found,
+
Other system modes: <code>*figure</code> is set when a graphic is found,
<code>*interaction</code> which is set when interaction is enabled, <code>*grid</code> which
+
<code>*interaction</code> is set when interaction is enabled, <code>*grid</code>
is set when grid typesetting is enabled, and <code>*pdf</code> and <code>*dvi</code> which
+
is set when grid typesetting is enabled, and <code>*pdf</code> and <code>*dvi</code>  
are set depending on the whether we are generating pdf or dvi output. Others
+
are set when the output is PDF or DVI. Others
are too esoteric to desribe here. If you are interested, see the  
+
are too esoteric to describe here. If you are interested, see the  
[http://pragma-ade.com/general/manuals/mmodes.pdf modes manual].
+
modes manual mentioned earlier.
  
= Earlier Article =  
+
= Specific Examples =
Often you'd like to publish different versions of a document, say a presentation and a handout or a student's and a teacher's version.
 
  
ConTeXt supports such filtering with its '''modes''':
+
== Different fonts ==
  
<texcode>
+
Suppose you want to generate two versions of a document, one with times font and one with palatino. One way to do this is as follows:
ConTeXt is a great TeX macro package.
 
\startmode[handout] % The following text will only appear in the handout
 
It’s based on Plain TeX like the better known LaTeX.
 
\stopmode
 
</texcode>
 
  
<texcode>
 
\startnotmode[print]
 
Here's a link to my homepage: \url[...]
 
\stopnotmode
 
</texcode>
 
 
<texcode>
 
\doifmode{answers}{The answer to the homework is 42.}
 
</texcode>
 
 
<texcode>
 
\doifmodeelse{draft}{Draft Version}{Final Version}
 
</texcode>
 
 
<tt>...mode</tt> and <tt>...notmode</tt> let you filter your content sufficient in most cases.
 
You can also give several modes like <tt>\startmode[handout,print]</tt>.
 
 
Modes are also a convenient way to comment out sections (typical: "obsolete" mode).
 
 
You can typeset the different modes like:
 
 
<pre>
 
texexec myfile --mode=handout --result=handout.pdf
 
</pre>
 
 
You don't need the <tt>--result</tt>, but otherwise you'd get the same filename for both modes.
 
 
Modes are extremely powerful when applied to text. However, they can be applied to configuration problems as well. A user wanted to generate different versions of the same file with different fonts:
 
 
<texcode>
 
<texcode>
 
\startmode[palatino]
 
\startmode[palatino]
  \usetypescript[adobekb][8r]
 
 
   \usetypescript[palatino][8r]
 
   \usetypescript[palatino][8r]
 
   \setupbodyfont[palatino,12pt]
 
   \setupbodyfont[palatino,12pt]
Line 247: Line 214:
  
 
\startmode[times]
 
\startmode[times]
  \usetypescript[adobekb][8r]
 
 
   \usetypescript[postscript][8r]
 
   \usetypescript[postscript][8r]
 
   \setupbodyfont[postscript,12pt]
 
   \setupbodyfont[postscript,12pt]
Line 254: Line 220:
 
\starttext
 
\starttext
 
\input knuth
 
\input knuth
\showfontstrip
 
 
\stoptext
 
\stoptext
 
</texcode>
 
</texcode>
 +
and run with one of the following:
  
And run with one of the following:
+
texexec --mode=palatino filename
<pre>
+
texexec --mode=times    filename
texexec --pdf --mode=palatino filename
 
texexec --pdf --mode=times    filename
 
</pre>
 
  
If you want to enable some mode(s) without changing the command line (e.g. because you use some TeX GUI), you can use
+
== Running external commands once ==
<cmd>enablemode</cmd><tt>[mymode]</tt> in your source. Put this before you load your environment! You can even enable several modes at once like <tt>[a4,print]</tt>.
 
 
 
== First-run-mode: Doing things only once ==
 
 
 
When you need to call external programs to process some of your data and return you some results, you probaly want to do that only once (instead of three times, if ConTeXt needs three runs). Here's how you can do it:
 
  
 +
Suppose you want to run some external program, say to generate a figure. Unfortunately, the program only generates postscript figure. So you want to convert it to pdf. This can be done as follows:
 
<texcode>
 
<texcode>
\doifmode{*first}{%
+
\startmode[*first]
   % external program which creates a file figure1.ps
+
   % external program which creates a file fig-1.ps
 
   \executesystemcommand{some_external_program ...}
 
   \executesystemcommand{some_external_program ...}
 
   % convert PS into PDF
 
   % convert PS into PDF
   \executesystemcommand{texmfstart pstopdf figure1.ps}
+
   \executesystemcommand{texmfstart pstopdf fig-1.ps}
}
+
\stopmode
  
 
% include the resulting PDF
 
% include the resulting PDF
\externalfigure[figure1]
+
\externalfigure[fig-1]
 
</texcode>
 
</texcode>
  
 +
= Summary =
 +
 +
In summary, modes provide generalized conditional processing. A rich set of
 +
built-in modes is available.
  
 
[[Category:ConTeXt programming]]
 
[[Category:ConTeXt programming]]

Revision as of 07:56, 12 May 2010

< The ConTeXt Way | Inside ConTeXt | Project structure >

Very often, you want to generate multiple versions of the same document: one version for printing and one for viewing on the screen, one version for students and one version for the instructor, and so on. You can do this in a simple but naive way: create different files set up for the different versions and \input the common material, or create some new conditional flags using \newif and set them appropriately for conditional processing. Or you could use modes—the ConTeXt way of doing conditional processing.

Introduction

A mode is similar to a conditional flag, but with a few advantages: new modes need not be explicitly defined (no need for something like \newif), multiple modes can be simultaneously enabled or disabled, and the status of multiple modes can be checked easily. Moreover, modes can be set from a command line switch. As a result, multiple versions of a document can be generated without changing the source file.

The name or identifier of a mode can be any combination of letters, digits, or spaces. Names starting with * are reserved for system modes.

In this article I explain how to activate a mode and how to check if a mode is active or not.

Setting modes

ConTeXt has three commands for setting modes:

The names are self-descriptive. \enablemode activates a mode, \disablemode deactivates a mode, and \preventmode permanently deactivates a mode. All three commands take a list of modes as an argument. For example, you can activate modes named screen and solution with

    \enablemode[screen,solution]

Modes can also be activated by a command line switch --modes to texexec or context. For example, another way to activate the screen and solution modes, to run ConTeXt using one of:

   texexec --mode=screen,solution ...
   context --mode=screen,solution ...


Conditional processing based on modes

You may want to process or ignore a chunk of code if a particular mode is enabled or disabled. Such a chunk of code is specified using \startmode and \startnotmode environments. Their usable is best explained by an example.

Suppose you want to change the paper size of a document depending on whether it is for print or screen. This can be done in multiple ways. You could set the default paper size for print and change it in screen mode:

  \setuppapersize[letter][letter]
  \startmode[screen]
    \setuppapersize[S6][S6]
  \stopmode

(S6 is one of the screen-optimized paper sizes in ConTeXt; the paper size has a 4:3 aspect ratio and a width equal to the width of A4 paper.)

Alternatively, you could set a default paper size for the screen and change it if screen mode is not enabled:

  \setuppapersize[S6][S6]
  \startnotmode[screen]
    \setuppapersize[letter][letter]
  \stopnotmode

\startmode and \startnotmode can check for multiple modes, by giving a list of modes as their arguments. \startmode processes its contents (everything until the next \stopmode, thus \startmode cannot be nested.) if any of the modes are enabled, otherwise (i.e., when all the modes are disabled) \startmode ignores its contents. The opposite is \startnotmode: it processes its contents (everything until the next \stopnotmode) if any of the modes are disabled, otherwise—when all the modes are enabled—the contents are ignored.

\startmode and \startnotmode are "or" environments. They process their contents if any of the modes satisfy the required condition. Their "and" counterparts are also available: \startallmodes and \startnotallmodes process their contents only if all the given modes satisfy the required condition. For example, suppose you want to enable interaction (e.g., hyperlinks) only when both screen and solution modes are enabled. Then you can use:

  \startallmodes[screen,solution]
    \setupinteraction[state=start]
  \stopallmodes

To summarize, the four start-stop environments for checking modes are:

\startmode[mode1, mode2, ...]
  % Processed if any of the modes is enabled
\stopmode

\startnotmode[mode1, mode2, ...]
  % Processed if any of the modes is disabled
\stopnotmode

\startallmodes[mode1, mode2, ...]
  % Processed if all the modes are enabled
\stopallmodes

\startnotallmodes[mode1, mode2, ...]
  % Processed if all the modes are disabled
\stopnotallmodes

These environments have \doif... alternatives that are useful for short setups. Also, they can be nested.

\doifmode        {modes} {content}
\doifnotmode     {modes} {content}
\doifallmodes    {modes} {content}
\doifnotallmodes {modes} {content}

The logic for determining when the content is processed is exactly the same as for the start-stop commands.

These \doif commands each have a variant to process alternative code if the conditions are not satisfied (like the \else branch of \if).

\doifmodeelse       {modes} {content} {alt}
\doifnotmodeelse    {modes} {content} {alt}
\doifallmodeselse   {modes} {content} {alt}
\doifnotallmodeselse{modes} {content} {alt}

System modes

Besides allowing user-definable modes, ConTeXt provides some system modes. These modes start with a * character. Here I will explain only the more commonly used system modes; see the ConTeXt modes manual for a complete list.

Perhaps the most useful system modes are *mkii and *mkiv which determine whether MKII or MKIV is being used. These modes are handy when you want different setups for MKII and MKIV.

Other modes are useful for very specific situations. Some of these are described below.

A document must be run multiple times to get the cross referencing, table of contents, etc. right. However, sometimes you need to do some external processing (e.g., graphic conversion) that only needs to be done once. In such cases, the *first mode is handy—it is active only on the first run of the document.

You can use the project-product-component structure for managing large projects like a book series. See Project structure for details of this approach. A product or its components may be compiled separately, and you may want to do something different when a product is compiled or when a component is compiled. To do so, you need to check for modes *project, *product, *component, and *environment; these modes are set when the corresponding structure file is processed. For example, the *product mode is set whenever a product file is read; more specifically, when \startproduct is encountered. Similarly, a mode *text is enabled when \starttext is encountered, and likewise for the others.

A large document is typically broken down into different section blocks: frontmatter, bodymatter, appendices, and backmatter. Internally, these section blocks are referred to as frontpart, bodypart, appendix, and backpart. Each section block sets a system mode with the same name. So, if you want macros that work differently in different section blocks, you can check for modes *frontpart, *bodypart, and so on.

ConTeXt provides support for multiple languages. Languages are recognized by their IETF language tags, like en-us for US English, en-gb for British English, nl for Dutch, de for German, etc. A document has a main language, set with the command \mainlanguage[...], that is used for translated labels like chapter and figure. You can also switch the current language using \language[...] to change the hyphenation rules. Whenever a language is chosen, its identifier is set as a mode. The mode for the main language starts with two *. For example, when the main language is US English and the current language is Dutch, the modes **en-us and *nl are set (notice the extra * in **en-us).

Other system modes: *figure is set when a graphic is found, *interaction is set when interaction is enabled, *grid is set when grid typesetting is enabled, and *pdf and *dvi are set when the output is PDF or DVI. Others are too esoteric to describe here. If you are interested, see the modes manual mentioned earlier.

Specific Examples

Different fonts

Suppose you want to generate two versions of a document, one with times font and one with palatino. One way to do this is as follows:

\startmode[palatino]
   \usetypescript[palatino][8r]
   \setupbodyfont[palatino,12pt]
\stopmode

\startmode[times]
   \usetypescript[postscript][8r]
   \setupbodyfont[postscript,12pt]
\stopmode

\starttext
\input knuth
\stoptext

and run with one of the following:

texexec --mode=palatino filename texexec --mode=times filename

Running external commands once

Suppose you want to run some external program, say to generate a figure. Unfortunately, the program only generates postscript figure. So you want to convert it to pdf. This can be done as follows:

\startmode[*first]
   % external program which creates a file fig-1.ps
   \executesystemcommand{some_external_program ...}
   % convert PS into PDF
   \executesystemcommand{texmfstart pstopdf fig-1.ps}
\stopmode

% include the resulting PDF
\externalfigure[fig-1]

Summary

In summary, modes provide generalized conditional processing. A rich set of built-in modes is available.