Difference between revisions of "System Macros/Fundamentals"

From Wiki
Jump to navigation Jump to search
Line 56: Line 56:
 
=== Guard against double-loading of input files ===
 
=== Guard against double-loading of input files ===
  
Because modules can be used in various contexts, we want to be able to prevent macro files from being loaded more than once. This can be done using:
+
Sometimes, macro or layout definition files can be used from within various contexts inside a single typesetting run. If that is the case, it can come in handy to be able to prevent macro files from being loaded more than once. This can be done using:
  
 
<texcode>
 
<texcode>
Line 64: Line 64:
 
where <code>\command</code> is a command defined in the module to be loaded only once.
 
where <code>\command</code> is a command defined in the module to be loaded only once.
  
For example, [[source:syst-gen.tex| syst-gen.tex]] implements <code>\writestatus</code>, and therefore it starts with:
+
For example, [[source:syst-gen.tex| syst-gen.tex]] implements <code>\writestatus</code>, and therefore it could start with:
  
 
<texcode>
 
<texcode>
Line 70: Line 70:
 
</texcode>
 
</texcode>
  
Actually you don't need this macro for modules, since <code>\usemodule</code> does it's own bookkeeping.  It is intended for files that are loaded via the TeX primitive <code>\input</code>.
+
Normally, you don't need this macro at all, it is purely intended for files that are loaded via the TeX primitive <code>\input</code>.
 +
<code>\usemodule</code> does its own bookkeeping, and combining it with <code>\usetypescriptfile</code> is generally not a good idea.
  
 
=== Protecting internal macros ===
 
=== Protecting internal macros ===

Revision as of 11:17, 24 December 2006

| Top: System Macros | Next: Mnemonics & Aliases >

The ConTeXt version

Even though ConTeXt does not have a rigid versioning interface, there are a few macros that deal with versions.

\contextversion contains the ConTeXt version string. If you need to make sure you are running under ConTeXt, check for this macro. This macro is not defined in syst-gen.tex, but in context.tex, because syst-gen.tex is sometimes loaded under LaTeX, and it would be bad to define \contextversion in that case. The expansion of the macro is something like this:


\fmtname is defined at the same time, and it always expands to this:


\contextformat is also defined at the same time, and it contains the name of the current format. The expansion of the macro is something like this:


\contextmark is also defined in context.tex, and it contains the ConTeXt major release marker. You can read more on this internal versioning marker in ConTeXt, mkii & mkiv. The expansion of the macro is something like this:


\contextversionnumber is defined in mult-ini.tex, by interpreting \contextversion and attaching the \contextmark. The expansion of the macro is something like this:


\newcontextversion is the last macro in this section. It is set in cont-new.tex, the file that is read in at runtime. This macro is a security measure: its content is compared with the value of \contextversion that was stored in the format file, and if the two do not match up, the job is aborted.

Conditional execution of engine-specific code

In syst-prm.tex, a few macros are defined that can be used to delimit code that uses engine-specific features. \beginTEX and \beginETEX are mutually exclusive, depending on whether or not the format file was compiled under an e-TeX-enabled executable. In the latest ConTeXt releases, this will always imply using the \beginETEX code, because e-TeX availability has recently become a requirement for ConTeXt. The macros will stay, however, because bits and pieces of ConTeXt are used in formats like LaTeX and mptopdf, that are not necesarily e-TeX.

A typical way of setting up your code to use e-TeX is like this:

\beginTEX
\def\ifundefined#1%
  {\expandafter\ifx\csname#1\endcsname\relax}
\endTEX

\beginETEX \ifcsname
\def\ifundefined#1%
  {\unless\ifcsname#1\endcsname}
\endETEX


Code delimited by \beginOMEGA ... \endOMEGA is only executed if ConTeXt runs under Aleph.

Code within \beginXETEX ... \endXETEX is only run when XeTeX is used.

Experimental code for LuaTeX can be put between \beginMETATEX ... \endMETATEX.


An optional argument after the \begin... can be used to give some more information to the viewer: the example above will print the following string to the terminal:

system (E-TEX) : [line 833] \ifcsname

Guard against double-loading of input files

Sometimes, macro or layout definition files can be used from within various contexts inside a single typesetting run. If that is the case, it can come in handy to be able to prevent macro files from being loaded more than once. This can be done using:

\abortinputifdefined\command

where \command is a command defined in the module to be loaded only once.

For example, syst-gen.tex implements \writestatus, and therefore it could start with:

\abortinputifdefined\writestatus

Normally, you don't need this macro at all, it is purely intended for files that are loaded via the TeX primitive \input. \usemodule does its own bookkeeping, and combining it with \usetypescriptfile is generally not a good idea.

Protecting internal macros

We can shield macros from users by using some special characters in their names. Some characters that TeX normally does not consider to be letters (and therefore used) are: @, ! and ?. Before and after the definition of protected macros, we have to change the <catcode> of these characters. This is done by \unprotect and \protect, for instance:

\unprotect
\def\!test{alfa}
\protect

The newly defined command \!test can of course only be called upon when we are in the \unprotect'ed state, otherwise TeX reads the command \!, followed by the word test and probably complains loudly about not being in math mode.

The protection/unprotection commands can be nested (unlike \makeatletter in LaTeX). This nesting is a convenience, since it allows one to use the protection pair regardless of whether protection is already turned on.

When the nesting becomes deeper than one level, the system reports the current protection level.

It is a good habit to always start your macro files with \unprotect and end them with \protect.

| Top: System Macros | Next: Mnemonics & Aliases >