Changes

Jump to navigation Jump to search
5,210 bytes added ,  11:39, 11 March 2019
m
closing tag much needed
< [[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]]}} Many-a-timesVery often, you want to to generate multiple versions of the same document.:One one version for printing and one for viewing on the screen; , one version forstudents and one version for the instructor; , and so on. You can do this in asimple but naive way. Create : create different files with setup set up for the different versions and
<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
could 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 : new modes
need not be explicitly defined (no need for something like <code>\newif</code>),
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. SoAs a result, multiple versions of a document can be generated without changing
the source file.
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 =
ConTeXt has three commands for setting modes:
* <code>\{{cmd|enablemode }}[...]</code>* <code>\{{cmd|disablemode}}[...]</code>* <code>\{{cmd|preventmode}}[...]</code>
The names are self explanatory-descriptive. <code>\{{cmd|enablemode</code> }} activates a mode,<code>\{{cmd|disablemode</code> }} deactivates a mode, and <code>\{{cmd|preventmode</code> }} permanently
deactivates a mode. All three commands take a list of modes as an argument. For
example, you can activate modes named <code>screen</code> and <code>solution</code> modes bywith
<texcode>
\enablemode[screen,solution]
Modes can also be activated by a command line switch <code>--modes</code> to
<code>texexec</code> and or <code>context</code>. For example, another way to activate the <code>screen</code> and<code>solution</code> modes, you can to run ConTeXt usingone of:
texexec --mode=screen,solution ...
context --mode=screen,solution ...
 
== Pre-defining modes ==
orNormally, 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 cases, you can ''define'' a mode before using them, to speed up the processing. Modes are defined using:
context --mode=screen,solution <texcode>\definemode[...][...]</texcode> The first argument is a list of modes; the second argument may be `yes`, `no`, or `keep`.For example,
To get different pdf output for different modes, you can add * <code>--result\definemode[screen][yes]</code> switchdefines a mode and enables it; * <code>\definemode[screen][no]</code> defines a mode and disables it; * <code>\definemode[screen][keep]</code> defines a mode and keeps its previous status.
context --mode=screenTypically,solution --result=solutionit is better to use <code>\definemode[.pdf ..][keep]</code> so that the modes may be enabled or disabled from command line as well.
= 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 <code>\startmode</code> and
<code>\startnotmode</code> environments. Their use 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 either seta the default paper size for print and change it for in screenmode:
<texcode>
\setuppapersize[letter][letter]
 
\startmode[screen]
\setuppapersize[S6][S6]
\stopmode
</texcode>
\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, youcould set a default paper size for the screen and change it if the screen mode is
not enabled:
<texcode>
\setuppapersize[S6][S6]
 
\startnotmode[screen]
\setuppapersize[letter][letter]
</texcode>
<code>\startmode</code> (and <code>\startnotmode</code> can check for multiple ) checks the value of the mode '''at the time it is executed'''. This is important when you are setting the modes. Thearguments to using <code>\startmodeenablemode</code> and or <code>\startnotmodedisablemode</code> can be a list of modes.For example,<codetexcode>\enablemode[foo]\startmode[foo]...\stopmode</codetexcode> processes its the contents (everything until of the nextmode environment are executed because <code>\stopmodefoo</code> which means that is enabled when <code>\startmode</code> cannot be nested)if any of the modes are enabled, otherwise (i.eis encountered.However, when all the modes areindisabled) <codetexcode>\startmode</code> ignores it contents[foo]... <code>\stopmode\startnotmodeenablemode[foo]</codetexcode> is theopposite. It processes its contents (everything until of the nextmode environment are not execited because <code>\stopnotmodefoo</code> if any of the modes are disabled, otherwise (i.e., is not enabled when allthe mods are enabled) <code>\startnotmodestartmode</code> ignores its contentsis 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 benested.) if any of the modes are enabled, otherwise (i.e., when allthe modes are disabled) <code>\startmode</code> ignores itscontents. The opposite is <code>\startnotmode</code>: it processes itscontents (everything until the next <code>\stopnotmode</code>) if any of themodes 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>,which process their contents only if all the given modes satisfy the requiredcondition. For example, suppose you want to enable interaction (e.g., hyperlinks) etc.
only when both <code>screen</code> and <code>solution</code> modes are enabled. Then you can
use:
<texcode>
\startmode[mode1, mode2, ...]
% Process Processed if one any of the modes is enabled
\stopmode
\startnotmode[mode1, mode2, ...]
% Process Processed if one any of the modes is disabled
\stopnotmode
\startallmodes[mode1, mode2, ...]
% Process Processed if all the modes are enabled
\stopallmodes
\startnotallmodes[mode1, mode2, ...]
% Process Processed if all the modes are disabled
\stopnotallmodes
</texcode>
These environments have a <code>\doif...</code> alternative alternatives that are useful for shortsetups and . Also, they can also be nested.
<texcode>
\doifmode {modesmode1, mode2, ...} {contentProcessed if any mode is enabled}\doifnotmode {modesmode1, mode2, ...} {contentProcessed if any mode is disabled}\doifallmodes {modesmode1, mode2, ...} {contentProcessed if all modes are enabled}\doifnotallmodes {modesmode1, mode2, ...} {contentProcessed if all modes are disabled}
</texcode>
\noindentation The logic for determining when the content is processes processed is exactly the same asfor the <code>start</code>-<code>stop</code> alternativescommands.
These <code>\doif</code> commands each have a variant that can to process something else alternative code if
the conditions are not satisfied (like the <code>\else</code> branch of <code>\if</code>).
<texcode>
\doifmodeelse {modesmode1, mode2, ...} {contentProcessed if any mode is enabled} {alternative}\doifnotmodeelse {modes} {content} {alternativeelse this is processed}\doifallmodeselse {modesmode1, mode2, ...} {contentProcessed if all modes are enabled} {alternativeelse this is processed}\doifnotallmodeselse {modesmode1, mode2, ...} {contentProcessed if all modes are disabled} {alternativeelse 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</code> branches switched).
 
== Checking multiple modes in parallel (<code>case</code> statement for modes) ==
 
In addition to the above <em>"or"</em> and <em>"and"</em> environment which check modes is sequence, you can also check multiple modes in parallel. The syntax for such a <em>"case"</em> environment is as follows:
 
<texcode>
\startmodeset
[mode1, mode2, ...] {Processed if either mode is enabled}
[mode3, mode4, ...] {Processed if either mode is enabled}
[default] {Processed if none of the above modes match}
\stopmodeset
</texcode>
 
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 =
In addition to Besides allowing user-defined definable modes, ConTeXt provides some system modes. Thesemodes start with a <code>*</code>character. Here I will only explain the more commonly usedsystem modes. You can are explained; see the ConTeXt [http://pragma-ade.com/general/manuals/mmodes.pdf modes manual]for a complete list of system modes.  {|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> which
determine whether MkII MKII or MkIV MKIV is being used. These modes are handy when youwant different setups for MkII MKII and MkIVMKIV.
Other modes are useful for very specific situations. Some of these are described
below.
  {|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 (like e.g., graphicconversion) that only needs to be done only once. In such cases, the<code>*first</code> mode is handy, which checks for &mdash;it is active only on the first run of the document.     {|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"| '''*export'''| Enabled when <code>\setupbackend[export=yes]</code> is set|} You may 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>|-| '''*text'''| Enabled when inside <code>\starttext</code> ... <code>\stoptext</code>.|}
You can use the project-product-component structure for managing large projects
like a book series. See [[Project structure]]
for detailsof this approach. Both A product and or its components can may be compiled separately. Sometimes , and you may want to process do something different when a component differently depending on whether it product isbeing compiled directly, or if the complete product when a component is being compiled. This canTo do so, you need to check forbe checked using the modes <code>*project</code>, <code>*product</code>, <code>*component</code>,andand <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, whenever a when <code>\startproduct</code> isencountered). Similarly, a mode <code>*text</code> is enabled whenever awhen<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> ... <code>\stopfrontmatter</code>|-| '''*bodypart'''| Enabled when inside <code>\startbodymatter</code> ... <code>\stopbodymatter</code>|-| '''*backpart'''| Enabled when inside <code>\startbackmatter</code> ... <code>\stopbackmatter</code>|}
A large document is also typically broken down into different section blocks like:
frontmatter, bodymatter, appendices, and backmatter. Internally, these section
blocks are refered referred to as <code>frontpart</code>, <code>backpartbodypart</code>, <code>appendix</code>, and<code>backmatterbackpart</code>. Each section block sets a system mode with the same name. So,if you want macros that work differently for in different section blocks, you cancheck for modes <code>*fronpartfrontpart</code>, <code>*backpart</code>, <code>*appendixbodypart</code>, andso on.<code>*backmatter</code> modes.
 {|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, you can 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''', '''*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 languagelanguages. Language Languages are recognized bytheir 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
has a main language , set using with the command <code>\mainlanguage[...]</code> ,that is sued used for
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.
Whenever a language is chosen, its id identifier is set as a mode. The mode for the mainlanguage 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
<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,
<code>*interaction</code> which is set when interaction is enabled, <code>*grid</code> which
is set when grid typesetting is enabled, and <code>*pdf</code> and <code>*dvi</code> 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
[http://pragma-ade.com/general/manuals/mmodes.pdf 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''':
 
<texcode>
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>{|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|-\doifmodeelse{draft}{Draft Version|'''*grid'''| Enabled when grid typesetting is enabled|}{Final Version}</texcode>
<tt>...mode</tt> and <tt>...notmode</tt> let you filter your content sufficient in most cases.{|cellpadding="5" style="border-collapse: collapse;border-width: 1px; border-style: solid;"You can also give several modes like <tt>\startmode[handout,print]</tt>.|'''*pdf'''| Enabled when the main output is pdf|-|'''*dvi'''| Enabled when the main output is dvi|}
Modes 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 also a convenient way too esoteric to comment out sections (typical: "obsolete" mode)describe here. If you are interested, see the modes manual mentioned earlier.
You can typeset the different modes like:= Specific Examples =
<pre>texexec myfile --mode=handout --result=handout.pdf</pre>Different fonts ==
You don't need the <tt>--result</tt>Suppose you want to generate two versions of a document, but otherwise you'd get the same filename for both modesone 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:
And run with one of the following:<pre> texexec --pdf context --mode=palatino filename texexec --pdf context --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<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 Running external commands 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>
\doifmode{startmode[*first}{%] % external program which creates a file figure1fig-1.ps
\executesystemcommand{some_external_program ...}
% convert PS into PDF
\executesystemcommand{texmfstart pstopdf figure1fig-1.ps}}\stopmode
% include the resulting PDF
\externalfigure[figure1fig-1]
</texcode>
{{Getting started navbox}}
[[Category:ConTeXt programming]]
139

edits

Navigation menu