Changes

Jump to navigation Jump to search
15,107 bytes added ,  11:39, 11 March 2019
m
closing tag much needed
< [[The ConTeXt Way]] | [[Inside ConTeXt]] | [[Project structure]] >
Often Very often, you'd like want to publish different generate multiple versions of a the same document:one version for printing and one for viewing on the screen, say one version forstudents and one version for the instructor, and so on. You can do this in a presentation simple but naive way: create different files set up for the different versions and a handout <code>\input</code> the common material, or a student's create some new conditional flags using<code>\newif</code> and a teacher's versionset them appropriately for conditional processing. Or youcould use <em>modes</em>&mdash;the ConTeXt way of doing conditional processing.
= Introduction = A mode is similar to a conditional flag, but with a few advantages: new modesneed not be explicitly defined (no need for something like <code>\newif</code>),multiple modes can be simultaneously enabled or disabled, and the status of multiplemodes can be checked easily. Moreover, modes can be set from a command lineswitch. As a result, multiple versions of a document can be generated without changingthe source file. The name or identifier of a mode can be any combination of letters, digits, orspaces. 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 isactive or not.  = Setting modes = ConTeXt has three commands for setting modes: * <code>{{cmd|enablemode }}[...]</code>* <code>{{cmd|disablemode}}[...]</code>* <code>{{cmd|preventmode}}[...]</code> The names are self-descriptive. {{cmd|enablemode}} activates a mode,{{cmd|disablemode}} deactivates a mode, and {{cmd|preventmode}} permanentlydeactivates a mode. All three commands take a list of modes as an argument. Forexample, you can activate modes named <code>screen</code> and <code>solution</code> with<texcode>\enablemode[screen,solution]</texcode> Modes can also be activated by a command line switch <code>--modes</code> to<code>texexec</code> or <code>context</code>. For example, another way to activate the <code>screen</code> and<code>solution</code> modes, to run ConTeXt supports using one of:  texexec --mode=screen,solution ... context --mode=screen,solution ... == Pre-defining modes == Normally, the overhead for testing modes is negligible, but it can add up if modes are tested multiple times in a document (for example, as part of a macro). In such filtering with its cases, you can '''modes'define''a mode before using them, to speed up the processing. Modes are defined using:
<texcode>
ConTeXt \definemode[...][...]</texcode> The first argument is a great TeX macro packagelist of modes; the second argument may be `yes`, `no`, or `keep`.For example, * <code>\definemode[screen][yes]</code> defines a mode and enables it; * <code>\startmodedefinemode[screen][no]</code> defines a mode and disables it; * <code>\definemode[screen][keep]</code> defines a mode and keeps its previous status. Typically, it is better to use <code>\definemode[...][handoutkeep] % The following text will only appear in </code> so that the handoutmodes may be enabled or disabled from command line as well. It’s = Conditional processing based on PlainTeX like modes = You may want to process or ignore a chunk of code if a particular mode is enabledor disabled. Such a chunk of code is specified using <code>\startmode</code> and<code>\startnotmode</code> environments. Their use is best explained by an example. Suppose you want to change the better known LaTeXpaper size of a document depending on whether itis for print or screen. This can be done in multiple ways.You could setthe default paper size for print and change it in screen mode:<texcode>\setuppapersize[letter][letter]\startmode[screen] \setuppapersize[S6][S6]
\stopmode
</texcode>
(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:
<texcode>
\setuppapersize[S6][S6]\startnotmode[printscreen]Here's a link to my homepage: \urlsetuppapersize[letter][...letter]
\stopnotmode
</texcode>
<code>\startmode</code> (and <code>\startnotmode</code>) checks the value of the mode '''at the time it is executed'''. This is important when you are setting the modes using <code>\enablemode</code> or <code>\disablemode</code>. For example,
<texcode>
\doifmodeenablemode[answersfoo]{The answer to \startmode[foo]...\stopmode</texcode>the homework contents of the mode environment are executed because <code>foo</code> is enabled when <code>\startmode</code> is 42encountered. However, in<texcode>\startmode[foo].}..\stopmode\enablemode[foo]
</texcode>
the contents of the mode environment are not execited because <code>foo</code> is not enabled when <code>\startmode</code> is encountered.
 
== Checking for multiple modes (<code>or</code>/<code>and</code> statements for modes) ==
<code>\startmode</code> and <code>\startnotmode</code> can check for multiple modes,
by giving a list of modes as their arguments. <code>\startmode</code>
processes its contents (everything until the next
<code>\stopmode</code>, thus <code>\startmode</code> cannot be
nested.) if any of the modes are enabled, otherwise (i.e., when all
the modes are disabled) <code>\startmode</code> ignores its
contents. The opposite is <code>\startnotmode</code>: it processes its
contents (everything until the next <code>\stopnotmode</code>) if any of the
modes are disabled, otherwise&mdash;when all the modes are enabled&mdash;the contents are ignored.
 
<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
"<em>and</em>" counterparts are also available: <code>\startallmodes</code> and <code>\startnotallmodes</code>
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 <code>screen</code> and <code>solution</code> modes are enabled. Then you can
use:
<texcode>
\doifmodeelsestartallmodes[draftscreen,solution]{Draft Version}{Final Version} \setupinteraction[state=start]\stopallmodes
</texcode>
To summarize, the four start-stop environments for checking modes are:<tttexcode>\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</texcode> These environments have <code>\doif...mode</ttcode> and alternatives that are useful for shortsetups. Also, they can be nested. <tttexcode>\doifmode {mode1, mode2, ...} {Processed if any mode is enabled}\doifnotmode {mode1, mode2, ...} {Processed if any mode is disabled}\doifallmodes {mode1, mode2, ...notmode} {Processed if all modes are enabled}\doifnotallmodes {mode1, mode2, ...} {Processed if all modes are disabled}</tttexcode> let you filter your The logic for determining when the content sufficient in most casesis processed is exactly the same asfor the <code>start</code>-<code>stop</code> commands.You can also give several modes These <code>\doif</code> commands each have a variant to process alternative code ifthe conditions are not satisfied (like the <code>\else</code> branch of <code>\if</code>).<tttexcode>\startmode[handoutdoifmodeelse {mode1, mode2, ...} {Processed if any mode is enabled} {else this is processed} \doifallmodeselse {mode1, mode2, ...} {Processed if all modes are enabled} {else this is processed} \doifnotallmodeselse {mode1, mode2,print]...} {Processed if all modes are disabled} {else this is processed}</texcode> Note that there is no command <code>\doifnotmodeelse</code> because there is no need for it; <code>\doifmodeelse</code> may be used for the same effect (with the <code>if</code> and <code>else</ttcode>branches switched).
Modes are also a convenient way to comment out sections == Checking multiple modes in parallel (typical: "obsolete" mode<code>case</code> statement for modes).==
You In addition to the above <em>"or"</em> and <em>"and"</em> environment which check modes is sequence, you can typeset the different also check multiple modes likein parallel. The syntax for such a <em>"case"</em> environment is as follows:
<pretexcode>texexec myfile --\startmodeset [mode1, mode2, ...] {Processed if either mode=handout --result=handoutis enabled} [mode3, mode4, ..pdf.] {Processed if either mode is enabled} [default] {Processed if none of the above modes match}\stopmodeset</pretexcode>
The same mode can be referenced multiple times, and '''all''' matching branches are executed. The {{cmd|startmodeset}} ... {{cmd|stopmodeset}} environments can be nested. So, you can use  <texcode>\startmodeset [mode1, mode2] { Processed when either mode1 or mode2 is enabled } [mode3] { \startmodeset [mode1] {Processed when mode1 and mode3 are enabled} [mode2] {Processed when mode2 and mode3 are enabled} [default] {Processed when mode3 is enabled and mode1 and mode2 are disabled} \stopmodeset } [default] { Processed when mode1, mode2, and mode3 are disabled.: }\stopmodeset</texcode> == Checking modes in Lua == In MkIV, the state of any mode is accessible at the Lua end as <code>tex.modes</code> table. Specifically, <texcode>tex.modes["screen"]</texcode> returns <code>true</code> if mode <code>screen</code> is enabled and <code>false</code> otherwise. Thus, specific combinations of modes can be checked using boolean expressions. For example<texcode>if (tex.modes["mode1"] and tex.modes["mode2"]) then ...end</texcode>checks if both <code>mode1</code> and <code>mode2</code> are enabled.  = System modes = Besides allowing user-definable modes, ConTeXt provides some systemmodes. These modes start with a <code>*</code> character. Here only the more commonly used system modes are explained; see the ConTeXt [http://pragma-ade.com/general/manuals/mmodes.pdf modes manual]for a complete list.  {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*mkii'''| Enabled when running [[MkII]] |-| '''*mkiv''' | Enabled when running [[MkIV]]|}   Perhaps the most useful system modes are <code>*mkii</code> and <code>*mkiv</code> whichdetermine whether MKII or MKIV is being used. These modes are handy when youwant different setups for MKII and MKIV. Other modes are useful for very specific situations. Some of these are describedbelow.   {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"| '''*first'''| Enabled during the first compile run|} 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., graphicconversion) 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 thedocument.    {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"| '''*export'''| Enabled when <code>\setupbackend[export=yes]</code> is set|} You donmay want to use different images for XML [Export]. The <code>*export</code> mode is useful in such cases.     {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*project'''| Enabled when inside <code>\startproject</code> ... <code>\stopproject</code>|-|'''*component'''| Enabled when inside <code>\startcomponent</code>...<code>\stopcomponent</code>|-| '''*environment'''| Enabled when inside <code>\startenvironment</code> ... <code>\stopenvironment</code>|-| ''t '*text'''| Enabled when inside <code>\starttext</code> ... <code>\stoptext</code>.|} You can use the project-product-component structure for managing large projectslike a book series. See [[Project structure]]for details of this approach. A product or its components may be compiledseparately, and you may want to do something different when a product iscompiled or when a component is compiled. To do so, you need to check formodes <code>*project</code>, <code>*product</code>, <code>*component</code>, and<code>*environment</code>; these modes are set when the corresponding structure fileis processed. For example, the <code>*product</code> mode is set whenever aproduct file is read; more specifically, when <code>\startproduct</code> isencountered. Similarly, a mode <code>*text</code> is enabled when<code>\starttext</code> is encountered, and likewise for the others.   {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*frontpart''' | Enabled when inside <code>\startfrontmatter</code> ... <ttcode>\stopfrontmatter</code>|-| '''*bodypart'''| Enabled when inside <code>\startbodymatter</code> ... <code>\stopbodymatter</code>|-result| '''*backpart'''| Enabled when inside <code>\startbackmatter</code> ... <code>\stopbackmatter</code>|} A large document is typically broken down into different section blocks:frontmatter, bodymatter, appendices, and backmatter. Internally, these sectionblocks are referred to as <code>frontpart</code>, <code>bodypart</code>, <code>appendix</code>, and<code>backpart</code>. Each section block sets a system mode with the same name. So,if you want macros that work differently in different section blocks, you cancheck for modes <code>*frontpart</code>, <code>*bodypart</ttcode>, but otherwise and so on.   {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*list'''| Enabled inside a list entry|-|'''*marking'''| Enabled inside a marking|-|'''*register'''| Enabled inside a register|-|'''*chapter''', '''*section''', etc.| Enabled inside the corresponding section head.|}  Sometimes you want a macro to behave differently if it is part of a section head, a section number, a list, a marking, or a register. For section heads, youcan check for modes <code>*chapter</code>, <code>*section</code>, <code>*subsection</code>, etc. Similarly, <code>*list</code> is enabled inside a list, <code>*marking</code> is enabled inside a marking, and <code>*register</code> is enabled inside a register.   {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*en-us''', ''d get '*nl''', etc.| Enabled when the current <code>\language</code> is <code>en-us</code>, <code>nl</code>, etc.|-|'''**en-us''', '''**nl''', etc.| Enabled when the <code>\mainlanguage</code> is <code>en-us</code>, <code>nl</code>, etc.|} ConTeXt provides support for multiple languages. Languages are recognized bytheir IETF language tags, like <code>en-us</code> for USEnglish, <code>en-gb</code>for British English, <code>nl</code> for Dutch, <code>de</code> for German, etc. A documenthas a main language, set with the command <code>\mainlanguage[...]</code>,that is used fortranslated labels like <em>chapter</em> and <em>figure</em>. You can also switch thecurrent language using <code>\language[...]</code> to change the same filename hyphenation rules.Whenever a language is chosen, its identifier is set as a mode. The mode for both the mainlanguage starts with two <code>*</code>. For example, when the main languageis USEnglish 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>).    {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*figure'''| Enabled when a graphic is found|-|'''*interaction'''| Enabled when interaction is enabled|-|'''*grid'''| Enabled when grid typesetting is enabled|} {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"|'''*pdf'''| Enabled when the main output is pdf|-|'''*dvi'''| Enabled when the main output is dvi|} Other system modes: <code>*figure</code> is set when a graphic is found,<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> are set when the output is PDF or DVI. Othersare too esoteric to describe here. If you are interested, see the modesmanual 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:
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>
\startmode[palatino]
\usetypescript[adobekb][8r]
\usetypescript[palatino][8r]
\setupbodyfont[palatino,12pt]
\stopmode
\startmode[times]
\usetypescript[adobekb][8r]
\usetypescript[postscript][8r]
\setupbodyfont[postscript,12pt]
\stopmode
\starttext
\input knuth
\showfontstrip
\stoptext
</texcode>
and run with one of the following:
 
context --mode=palatino filename
context --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:
<texcode>
\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]
</texcode>
And run with one of the following:<pre> texexec --pdf --mode=palatino filename texexec --pdf --mode=times filename</pre>{{Getting started navbox}}
If you want to enable some mode(s) without changing the command line (e.g. because you use some TeX GUI), you can use<cmd>enablemode</cmd><tt>[mymode[Category:ConTeXt programming]</tt> in your source. Put this before you load your environment! You can even enable several modes at once like <tt>[a4,print]</tt>.
139

edits

Navigation menu