From Wiki
Revision as of 17:51, 13 February 2010 by Adityam (talk | contribs) (→‎System modes: typo)
Jump to navigation Jump to search

< 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. --Aditya

Many-a-times, you want to 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 a naive way. Create different files with setup 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.


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, the status of multiple 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 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.

Setting modes

ConTeXt has three commands for setting modes:

  • \enablemode [...]
  • \disablemode[...]
  • \preventmode[...]

The names are self explanatory. \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 screen and solution modes by


Modes can also be activated by a command line switch --modes to texexec and context. For example, to activate screen and solution modes, you can run ConTeXt using

 texexec --mode=screen,solution ...


 context --mode=screen,solution ...

To get different pdf output for different modes, you can add --result switch

 context --mode=screen,solution --result=solution.pdf ...

Conditional processing based on modes

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 a default paper size for print and change it for screen:



\noindentation (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 screen and change it if the screen mode is not enabled:



\startmode and \startnotmode can check for multiple modes. The arguments to \startmode and \startnotmode can be a list of modes. \startmode processes its contents (everything until the next \stopmode which means that \startmode cannot be nested) if any of the modes are enabled, otherwise (i.e., when all the modes are disabled) \startmode ignores it contents. \startnotmode is the opposite. It processes its contents (everything until the next \stopnotmode if any of the modes are disabled, otherwise (i.e., when all the mods are enabled) \startnotmode ignores its contents.

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


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

\startmode[mode1, mode2, ...]
  % Process if one of the modes is enabled

\startnotmode[mode1, mode2, ...]
  % Process if one of the modes is disabled

\startallmodes[mode1, mode2, ...]
  % Process if all modes are enabled

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

These environments have a \doif alternative that are useful for short setups and can also be nested.

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

\noindentation The logic for determining when the content is processes is exactly the same as for the start-stop alternatives.

These \doif commands have a variant that can process something else if the conditions are not satisfied (like the \else branch of \if).

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

System modes

In addition to user-defined modes, ConTeXt provides some system modes. These modes start with a *. Here I will only explain the more commonly used system modes. You can see the ConTeXt modes manual for a complete list of system modes.

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 multiple times to get the cross referencing, table of contents, etc.\ right. However, sometimes you need to do some external processing (like graphic conversion) that only needs to be done only once. In such cases, the *first mode is handy, which checks for 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. Both product and components can be compiled separately. Sometimes you want to process a component differently depending on whether it is being compiled directly, or if the complete product is being compiled. This can be checked using the modes *project, *product, *component, and *environment. For example, the *product mode is set whenever a product file is read (more specifically, whenever a \startproduct is encountered). Similarly, a mode *text is enabled whenever a \starttext is encountered.

A large document is also broken down into different section blocks like frontmatter, bodymatter, appendices, and backmatter. Internally, these section blocks are refered as frontpart, backpart, appendix, and backmatter. 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 check for *fronpart, *backpart, *appendix, and *backmatter modes.

ConTeXt provides support for multiple language. Language 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 using \mainlanguage[...] that is sued 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 id is set as 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 are: *figure which is set when a graphic is found, *interaction which is set when interaction is enabled, *grid which is set when grid typesetting is enabled, and *pdf and *dvi which are set depending on the whether we are generating pdf or dvi output. Others are too esoteric to desribe here. If you are interested, see the modes manual.

Earlier Article

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:

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.
Here's a link to my homepage: \url[...]
\doifmode{answers}{The answer to the homework is 42.}
\doifmodeelse{draft}{Draft Version}{Final Version}

...mode and ...notmode let you filter your content sufficient in most cases. You can also give several modes like \startmode[handout,print].

Modes are also a convenient way to comment out sections (typical: "obsolete" mode).

You can typeset the different modes like:

texexec myfile --mode=handout --result=handout.pdf

You don't need the --result, 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:



\input knuth

And run with one of the following:

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

If you want to enable some mode(s) without changing the command line (e.g. because you use some TeX GUI), you can use \enablemode[mymode] in your source. Put this before you load your environment! You can even enable several modes at once like [a4,print].

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:

   % external program which creates a file
   \executesystemcommand{some_external_program ...}
   % convert PS into PDF
   \executesystemcommand{texmfstart pstopdf}

% include the resulting PDF