https://wiki.contextgarden.net/api.php?action=feedcontributions&user=171.64.119.38&feedformat=atomWiki - User contributions [en]2024-03-28T14:59:10ZUser contributionsMediaWiki 1.34.1https://wiki.contextgarden.net/index.php?title=Commands_with_optional_arguments&diff=1869Commands with optional arguments2005-08-04T01:41:46Z<p>171.64.119.38: Added examples.</p>
<hr />
<div>< [[Inside ConTeXt]] | [[Commands with KeyVal arguments]] ><br />
<br />
In LaTeX you define a new command with an optional argument with "newcommand":<br />
<br />
<texcode><br />
\newcommand{\MyCommand}[2][World]{{#2Hello #1!}}<br />
\MyCommand{\bfseries}<br />
\MyCommand[Hans]{\scshape}<br />
</texcode><br />
<br />
<context><br />
{\bf Hello World!}<br />
{\sc Hello Hans!}<br />
</context><br />
<br />
In ConTeXt, the optional argument processing is handled as a two-step process. First, we write the command for the end-user as a wrapper command, which calls <cmd>dodoubleempty</cmd> (from [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex]) to handle the arguments properly -- including the optional ones -- and then calls a "private" command that contains the internals of the macro. Note that this function call does not explicitly refer to the arguments at all.<br />
<br />
<texcode><br />
\def\MyCommand{\dodoubleempty\doMyCommand}<br />
</texcode><br />
<br />
We then create the "private" macro (<tt>\doMacroName</tt> is the traditional ConTeXt name for these), with all the arguments defined as nonoptional. Default values for the arguments need to be handled somewhat more explicitly than with LaTeX; macros such as <cmd>ifsecondargument</cmd> are used to determine whether the given argument was specified, as follows:<br />
<br />
<texcode><br />
\def\doMyCommand[#1][#2]{#1Hello<br />
\ifsecondargument<br />
#2%<br />
\else<br />
World%<br />
\fi<br />
!}<br />
</texcode><br />
<br />
Note that this makes both arguments optional -- something that is much more difficult to do in LaTeX ([http://www.tex.ac.uk/cgi-bin/texfaq2html?label=twooptarg but can be done]). This also means that we should reverse the order of arguments, since if the user specifies only one argument it will be treated as the first argument.<br />
<br />
(Also, note that <tt>\MyCommand</tt> without the second argument ends up gobbling the following spaces, so we need to explicitly include one with "<tt>\ </tt>".)<br />
<br />
<texcode><br />
\MyCommand[\bf]\ %<br />
\MyCommand[\sc][Hans]<br />
</texcode><br />
<br />
<context><br />
\def\MyCommand{\dodoubleempty\doMyCommand}<br />
\def\doMyCommand[#1][#2]{#1Hello<br />
\ifsecondargument<br />
#2%<br />
\else<br />
World%<br />
\fi<br />
!}<br />
\MyCommand[\bf]\ %<br />
\MyCommand[\sc][Hans]<br />
</context><br />
<br />
If you ''don't'' want any optional arguments, but still want your arguments enclosed in <tt>[]</tt> with appropriate handling for spaces (or line breaks) between the square brackets, use <cmd>dodoublearguments</cmd> instead of <cmd>dodoubleempty</cmd>. There are of course versions for other numbers of arguments, found by replacing <tt>double</tt> with <tt>single</tt> through <tt>seventuple</tt>; see [http://source.contextgarden.net/tex/context/base/syst-gen.tex syst-gen.tex] for the exact names.<br />
<br />
----<br />
<br />
To define <tt>\mycommand[.1.][.2.]{.3.}</tt>, i.e., with curly braces around a non-optional third argument, you just define<br />
<br />
<texcode><br />
\def\mycommand{\dodoubleempty\doMycommand}<br />
\def\doMycommand[#1][#2]#3{whatever}<br />
</texcode><br />
<br />
----<br />
<br />
<i>Can someone test to see if <cmd>dosingleempty</cmd> and <cmd>dodoubleargument</cmd> can be chained, to get two square-bracketed arguments only one of which is optional?</i> --[[User:Brooks|Brooks]]</div>171.64.119.38https://wiki.contextgarden.net/index.php?title=Inside_ConTeXt&diff=1861Inside ConTeXt2005-08-04T01:07:47Z<p>171.64.119.38: Added real example to dash-separated-lists section.</p>
<hr />
<div>< [[Main Page]]<br />
<br />
== Using variables ==<br />
<br />
<texcode><br />
\setvariables[namespace][key=value]<br />
\getvariable{namespace}{key}<br />
</texcode><br />
<br />
== Defining new commands ==<br />
'''Special characters in command names'''<br />
<br />
Some commands have special characters in their names, that TeX normally does not consider to be <br />
letters: <tt>@</tt>, <tt>!</tt> and <tt>?</tt>. <br />
Before and after the use or definition of such protected commands in your input files, the catcode of these <br />
characters has to be changed. This is done by <cmd>unprotect</cmd> and <cmd>protect</cmd>:<br />
<br />
<texcode><br />
\unprotect<br />
\def\!test{alfa} <br />
\protect <br />
</texcode><br />
<br />
The newly defined command <tt>\!test</tt> can of course only be called upon when we are in the <cmd>unprotect</cmd>ed state, otherwise TeX reads the command <tt>\!</tt>, followed by the word <tt>test</tt> (and probably complains loudly about not being in math mode). These protection/unprotection commands can be nested. 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 <cmd>unprotect</cmd> and end them with <cmd>protect</cmd>.<br />
<br />
'''See also''':<br />
[[Commands with KeyVal arguments|Commands with Key=Value arguments]], <br />
[[Commands with optional arguments]]<br />
><br />
<br />
== Processing lists of values ==<br />
=== Processing a comma-separated list of values ===<br />
<br />
Suppose you defined a command like this one somewhere in your document:<br />
<texcode><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
</texcode><br />
So calling<br />
<texcode><br />
\IHaveTo{tidy up}{Monday}<br />
</texcode><br />
This will print out:<br />
<br />
<context><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
\IHaveTo{tidy up}{Monday}<br />
</context><br />
<br />
But sometimes you have to repeat some task more than once. In this case you can define a new command:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\processcommalist[#1]{\IHaveTo{#2}}}<br />
</texcode><br />
Calling<br />
<texcode><br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</texcode><br />
will spare you some typing <i>(but not some tidying up!)</i>:<br />
<br />
<context><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\processcommalist[#1]{\IHaveTo{#2}}}<br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</context><br />
<br />
<br />
In case a command <tt>\IHaveTo</tt> is already defined in a slightly different way:<br />
<texcode><br />
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}<br />
</texcode><br />
you can define <tt>\MyMumOrderedMeTo</tt> as:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\begingroup<br />
\def\processitem##1{\IHaveTo[##1]{#2}}%<br />
\processcommalist[#1]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
This, again, produces:<br />
<br />
<context><br />
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}<br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\begingroup<br />
\def\processitem##1{\IHaveTo[##1]{#2}}%<br />
\processcommalist[#1]\processitem<br />
\endgroup}<br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</context><br />
<br />
=== Processing a dash-separated list of values ===<br />
<br />
Sometimes you have more work to do than just that boring stuff at home. And as it is quite important as well, you don't want to loose your time enumerating all of the tasks. Being able to do something like<br />
<texcode><br />
\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}<br />
</texcode><br />
may sound like a good idea.<br />
<br />
Suppose you already defined:<br />
<texcode><br />
\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2.\par}<br />
</texcode><br />
<br />
You have to define some macros first (thanks to Taco!):<br />
<texcode><br />
% a few auxiliary core macros are needed to uncompress the list.<br />
%<br />
% \uncompresslist is the twin of the already existing \compresslist<br />
% which works in the other direction (syst-new)<br />
%<br />
\unprotect<br />
<br />
% I guess this function is already available but couldnt find it...<br />
%<br />
\def\apptomac#1#2%<br />
{\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1,#2}\fi}<br />
<br />
% the next macro does this:<br />
%<br />
% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}<br />
% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}<br />
%<br />
% (the 1+ and -1 are needed to solve a counter offset.)<br />
\def\itemwithdash#1-#2-%<br />
{\@EA\dorecurse\@EA<br />
{\the\numexpr 1+#2-#1\relax}%<br />
{\@EA\apptomac\@EA\uncompressedlist\@EA<br />
{\the\numexpr #1-1+\recurselevel\relax}}}%<br />
<br />
% top level. The result will be in \uncompressedlist<br />
\def\uncompresslist[#1]%<br />
{\def\uncompressedlist{}%<br />
\def\processitem##1%<br />
{\doifinstringelse{-}{##1}<br />
{\itemwithdash##1-}<br />
{\apptomac\uncompressedlist{##1}}}%<br />
\processcommalist[#1]\processitem }<br />
<br />
\protect<br />
</texcode><br />
<br />
And then you're ready to define<br />
<texcode><br />
\def\IHaveToDoTheTasks[#1]#2%<br />
{\begingroup<br />
\uncompresslist[#1]% <= Yeah!<br />
\def\processitem##1{\IHaveToDoTheTask[##1]{#2}}%<br />
\processcommacommand[\uncompressedlist]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
Guess what! Your <tt>\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}</tt> results in:<br />
<br />
<context><br />
\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2.\par}<br />
<br />
% a few auxiliary core macros are needed to uncompress the list.<br />
%<br />
% \uncompresslist is the twin of the already existing \compresslist<br />
% which works in the other direction (syst-new)<br />
%<br />
\unprotect<br />
<br />
% I guess this function is already available but couldnt find it...<br />
%<br />
\def\apptomac#1#2%<br />
{\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1,#2}\fi}<br />
<br />
% the next macro does this:<br />
%<br />
% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}<br />
% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}<br />
%<br />
% (the 1+ and -1 are needed to solve a counter offset.)<br />
\def\itemwithdash#1-#2-%<br />
{\@EA\dorecurse\@EA<br />
{\the\numexpr 1+#2-#1\relax}%<br />
{\@EA\apptomac\@EA\uncompressedlist\@EA<br />
{\the\numexpr #1-1+\recurselevel\relax}}}%<br />
<br />
% top level. The result will be in \uncompressedlist<br />
\def\uncompresslist[#1]%<br />
{\def\uncompressedlist{}%<br />
\def\processitem##1%<br />
{\doifinstringelse{-}{##1}<br />
{\itemwithdash##1-}<br />
{\apptomac\uncompressedlist{##1}}}%<br />
\processcommalist[#1]\processitem }<br />
<br />
\protect<br />
<br />
\def\IHaveToDoTheTasks[#1]#2%<br />
{\begingroup<br />
\uncompresslist[#1]% <= Yeah!<br />
\def\processitem##1{\IHaveToDoTheTask[##1]{#2}}%<br />
\processcommacommand[\uncompressedlist]\processitem<br />
\endgroup}<br />
<br />
\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}<br />
</context><br />
<br />
So - what are you still waiting for? Go back to work and do them right away!<br />
<br />
=== Comments ===<br />
Resulted from thread [http://archive.contextgarden.net/thread/20050704.151237.f815d89d.html] and will be used in some modules such as [[RawSteps]]. It would be nice if processing dash-separated lists of values would make it into the ConTeXt core.<br />
<br />
<br />
== Passing verbatim text as macro parameter ==<br />
<br />
In case you want to write macros that should handle verbatim text,<br />
you can use the tex primitives <tt>\obeyspaces</tt> and <tt>\obeylines</tt>.<br />
<tt>\obeyspaces</tt> changes the category code of the space character,<br />
so that spaces become significant. <tt>\obeylines</tt> does the same for the<br />
newline character.<br />
<br />
This works fine for the following example:<br />
<br />
<texcode><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</texcode><br />
<br />
<context><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</context><br />
<br />
But if you pass this text as a parameter for your own macro<br />
<tt>\TextWithSpaces</tt><br />
<br />
<texcode><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</texcode><br />
<br />
<context><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</context><br />
<br />
the additional spaces are '''ignored'''.<br />
This happens because the category code change is not yet in effect when<br />
the argument is parsed, and the spaces are removed during parsing. To keep<br />
the spaces, the catcode change must be done '''before''' the argument is parsed.<br />
<br />
Here is a two-part solution for the problem (''suggested by Taco Hoekwater''):<br />
<br />
<texcode><br />
\def\TextWithSpaces{\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces#1{\framed{#1}\egroup}<br />
</texcode><br />
<br />
Another way is to postpone argument loading (''suggested by Hans Hagen'').<br />
<br />
<texcode><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
</texcode><br />
<br />
Both of these produce the desired result:<br />
<br />
<context><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
<br />
\TextWithSpaces{A gap from here to there!}<br />
</context></div>171.64.119.38https://wiki.contextgarden.net/index.php?title=Inside_ConTeXt&diff=1789Inside ConTeXt2005-08-04T01:05:27Z<p>171.64.119.38: Added real examples to processing comma-separated lists.</p>
<hr />
<div>< [[Main Page]]<br />
<br />
== Using variables ==<br />
<br />
<texcode><br />
\setvariables[namespace][key=value]<br />
\getvariable{namespace}{key}<br />
</texcode><br />
<br />
== Defining new commands ==<br />
'''Special characters in command names'''<br />
<br />
Some commands have special characters in their names, that TeX normally does not consider to be <br />
letters: <tt>@</tt>, <tt>!</tt> and <tt>?</tt>. <br />
Before and after the use or definition of such protected commands in your input files, the catcode of these <br />
characters has to be changed. This is done by <cmd>unprotect</cmd> and <cmd>protect</cmd>:<br />
<br />
<texcode><br />
\unprotect<br />
\def\!test{alfa} <br />
\protect <br />
</texcode><br />
<br />
The newly defined command <tt>\!test</tt> can of course only be called upon when we are in the <cmd>unprotect</cmd>ed state, otherwise TeX reads the command <tt>\!</tt>, followed by the word <tt>test</tt> (and probably complains loudly about not being in math mode). These protection/unprotection commands can be nested. 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 <cmd>unprotect</cmd> and end them with <cmd>protect</cmd>.<br />
<br />
'''See also''':<br />
[[Commands with KeyVal arguments|Commands with Key=Value arguments]], <br />
[[Commands with optional arguments]]<br />
><br />
<br />
== Processing lists of values ==<br />
=== Processing a comma-separated list of values ===<br />
<br />
Suppose you defined a command like this one somewhere in your document:<br />
<texcode><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
</texcode><br />
So calling<br />
<texcode><br />
\IHaveTo{tidy up}{Monday}<br />
</texcode><br />
This will print out:<br />
<br />
<context><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
\IHaveTo{tidy up}{Monday}<br />
</context><br />
<br />
But sometimes you have to repeat some task more than once. In this case you can define a new command:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\processcommalist[#1]{\IHaveTo{#2}}}<br />
</texcode><br />
Calling<br />
<texcode><br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</texcode><br />
will spare you some typing <i>(but not some tidying up!)</i>:<br />
<br />
<context><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\processcommalist[#1]{\IHaveTo{#2}}}<br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</context><br />
<br />
<br />
In case a command <tt>\IHaveTo</tt> is already defined in a slightly different way:<br />
<texcode><br />
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}<br />
</texcode><br />
you can define <tt>\MyMumOrderedMeTo</tt> as:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\begingroup<br />
\def\processitem##1{\IHaveTo[##1]{#2}}%<br />
\processcommalist[#1]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
This, again, produces:<br />
<br />
<context><br />
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}<br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\begingroup<br />
\def\processitem##1{\IHaveTo[##1]{#2}}%<br />
\processcommalist[#1]\processitem<br />
\endgroup}<br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</context><br />
<br />
=== Processing a dash-separated list of values ===<br />
<br />
Sometimes you have more work to do than just that borring stuff at home. And as it is quite important as well, you don't want to loose your time enumerating all of the tasks. Being able to do something like<br />
<texcode><br />
\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}<br />
</texcode><br />
may sound like a good idea.<br />
<br />
Suppose you already defined:<br />
<texcode><br />
\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2.\par}<br />
</texcode><br />
<br />
You have to define some macros first (thanks to Taco!):<br />
<texcode><br />
% a few auxiliary core macros are needed to uncompress the list.<br />
%<br />
% \uncompresslist is the twin of the already existing \compresslist<br />
% which works in the other direction (syst-new)<br />
%<br />
\unprotect<br />
<br />
% I guess this function is already available but couldnt find it...<br />
%<br />
\def\apptomac#1#2%<br />
{\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1,#2}\fi}<br />
<br />
% the next macro does this:<br />
%<br />
% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}<br />
% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}<br />
%<br />
% (the 1+ and -1 are needed to solve a counter offset.)<br />
\def\itemwithdash#1-#2-%<br />
{\@EA\dorecurse\@EA<br />
{\the\numexpr 1+#2-#1\relax}%<br />
{\@EA\apptomac\@EA\uncompressedlist\@EA<br />
{\the\numexpr #1-1+\recurselevel\relax}}}%<br />
<br />
% top level. The result will be in \uncompressedlist<br />
\def\uncompresslist[#1]%<br />
{\def\uncompressedlist{}%<br />
\def\processitem##1%<br />
{\doifinstringelse{-}{##1}<br />
{\itemwithdash##1-}<br />
{\apptomac\uncompressedlist{##1}}}%<br />
\processcommalist[#1]\processitem }<br />
<br />
\protect<br />
</texcode><br />
<br />
And then you're ready to define<br />
<texcode><br />
\def\IHaveToDoTheTasks[#1]#2%<br />
{\begingroup<br />
\uncompresslist[#1]% <= Yeah!<br />
\def\processitem##1{\IHaveToDoTheTask[##1]{#2}}%<br />
\processcommacommand[\uncompressedlist]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
Guess what! Your <tt>\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}</tt> resulted in:<br />
The task 1 has to be done until tomorrow.<br />
The task 2 has to be done until tomorrow.<br />
The task 3 has to be done until tomorrow.<br />
The task 4 has to be done until tomorrow.<br />
The task 7 has to be done until tomorrow.<br />
The task 9 has to be done until tomorrow.<br />
The task 10 has to be done until tomorrow.<br />
The task 11 has to be done until tomorrow.<br />
<br />
So - what are you still waiting for? Go back to work and do them right away!<br />
<br />
=== Comments ===<br />
Resulted from thread [http://archive.contextgarden.net/thread/20050704.151237.f815d89d.html] and will be used in some modules such as [[RawSteps]]. It would be nice if processing dash-separated lists of values would make it into the ConTeXt core.<br />
<br />
<br />
== Passing verbatim text as macro parameter ==<br />
<br />
In case you want to write macros that should handle verbatim text,<br />
you can use the tex primitives <tt>\obeyspaces</tt> and <tt>\obeylines</tt>.<br />
<tt>\obeyspaces</tt> changes the category code of the space character,<br />
so that spaces become significant. <tt>\obeylines</tt> does the same for the<br />
newline character.<br />
<br />
This works fine for the following example:<br />
<br />
<texcode><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</texcode><br />
<br />
<context><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</context><br />
<br />
But if you pass this text as a parameter for your own macro<br />
<tt>\TextWithSpaces</tt><br />
<br />
<texcode><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</texcode><br />
<br />
<context><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</context><br />
<br />
the additional spaces are '''ignored'''.<br />
This happens because the category code change is not yet in effect when<br />
the argument is parsed, and the spaces are removed during parsing. To keep<br />
the spaces, the catcode change must be done '''before''' the argument is parsed.<br />
<br />
Here is a two-part solution for the problem (''suggested by Taco Hoekwater''):<br />
<br />
<texcode><br />
\def\TextWithSpaces{\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces#1{\framed{#1}\egroup}<br />
</texcode><br />
<br />
Another way is to postpone argument loading (''suggested by Hans Hagen'').<br />
<br />
<texcode><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
</texcode><br />
<br />
Both of these produce the desired result:<br />
<br />
<context><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
<br />
\TextWithSpaces{A gap from here to there!}<br />
</context></div>171.64.119.38https://wiki.contextgarden.net/index.php?title=Hiding_Content&diff=1795Hiding Content2005-08-04T00:54:27Z<p>171.64.119.38: Clarified language, added another example for comparison.</p>
<hr />
<div>< [[Visuals]] | [[Presentations]] | [[Layers]] ><br />
<br />
Probably for your [[Presentations|slides]], probably for some [[Animation|animation]] or for whatever reason you may want it: you can hide some content from the document, while leaving exactly the same amount of space as that content would need if typeset in the usual way. This is done by placing the content on a layer that is not normally visible when the document is displayed.<br />
<br />
You can try something like:<br />
<br />
<texcode><br />
\defineproperty[my-secrets][layer][state=top]<br />
<br />
I don't tell this to everybody:<br />
%<br />
\startproperty[my-secrets]%<br />
\quotation{\ConTeXt\ goes beyond the limits of imagination, that's why I love it!}<br />
\stopproperty<br />
%<br />
You'll understand that once you get to know it better.<br />
</texcode><br />
<br />
which results in<br />
<br />
<context><br />
\setupcolors[state=start]<br />
\defineproperty[my-secrets][layer][state=top]<br />
<br />
I don't tell this to everybody:<br />
%<br />
\startproperty[my-secrets]%<br />
%<br />
% for the curious eyes: this effect was faked on Wiki as it doesn't work otherwise<br />
% (when PNG is generated from the PDF, the hidden layer becomes visible)<br />
%<br />
\color[white]{\quotation{\ConTeXt\ goes beyond the limits of imagination, that's why I love it!}}<br />
\stopproperty<br />
%<br />
You'll understand that once you get to know it better.<br />
</context><br />
<br />
This can be compared to the non-hidden version, which is:<br />
<br />
<context><br />
I don't tell this to everybody:<br />
{\quotation{\ConTeXt\ goes beyond the limits of imagination, that's why I love it!}}<br />
You'll understand that once you get to know it better.<br />
</context><br />
<br />
<b>Just as a hint</b>: Don't ever think about hiding your secrets or solutions to the problems for your students that way!<br><br />
If you happen to have Adobe Acrobat Professional, you can select <i>Layers</i> on the left and switch the hidden layer on again.<br><br />
<font color="red">YOU HAVE BEEN WARNED!</font><br />
<br />
[[http://archive.contextgarden.net/thread/20050707.223338.a9169811.html]]</div>171.64.119.38https://wiki.contextgarden.net/index.php?title=Verbatim_text&diff=1998Verbatim text2005-08-04T00:50:56Z<p>171.64.119.38: Clarified wording, added examples.</p>
<hr />
<div>< [[Visuals]]<br />
<br />
=Displayed text=<br />
<cmd>starttyping</cmd>,<br />
<cmd>typebuffer</cmd><br />
<br />
=In-line text=<br />
<br />
=Interesting features=<br />
The <tt>option=commands</tt> setting allows the usage of ConTeXt commands inside verbatim text, as in this example:<br />
<texcode><br />
\definetyping[C][option=commands]<br />
\startC<br />
#include <stdio.h><br />
int main(){<br />
return 0;<br />
/BTEX{\em unreachedCode;}/ETEX<br />
}<br />
\stopC<br />
</texcode><br />
<br />
<context><br />
\definetyping[C][option=commands]<br />
\startC<br />
#include <stdio.h><br />
int main(){<br />
return 0;<br />
/BTEX{\em unreachedCode;}/ETEX<br />
}<br />
\stopC<br />
</context><br />
<br />
The tab character normally corresponds to one character, as can be seen above. That value can be adjusted, using the following code (available in the 2005.06.01 version and later):<br />
<texcode><br />
\definetyping[C][tab=3]<br />
% for older ConTeXt versions: \chardef\spacespertab=3<br />
\startC<br />
int func(int a){<br />
if(a > 4)<br />
return 0;<br />
else<br />
return 10;<br />
}<br />
\stopC<br />
</texcode><br />
<br />
<context><br />
\definetyping[C][tab=3]<br />
\startC<br />
int func(int a){<br />
if(a > 4)<br />
return 0;<br />
else<br />
return 10;<br />
}<br />
\stopC<br />
</context></div>171.64.119.38https://wiki.contextgarden.net/index.php?title=Inside_ConTeXt&diff=1788Inside ConTeXt2005-08-04T00:45:35Z<p>171.64.119.38: Edited text for clarity (and extraneous commas), added examples.</p>
<hr />
<div>< [[Main Page]]<br />
<br />
== Using variables ==<br />
<br />
<texcode><br />
\setvariables[namespace][key=value]<br />
\getvariable{namespace}{key}<br />
</texcode><br />
<br />
== Defining new commands ==<br />
'''Special characters in command names'''<br />
<br />
Some commands have special characters in their names, that TeX normally does not consider to be <br />
letters: <tt>@</tt>, <tt>!</tt> and <tt>?</tt>. <br />
Before and after the use or definition of such protected commands in your input files, the catcode of these <br />
characters has to be changed. This is done by <cmd>unprotect</cmd> and <cmd>protect</cmd>:<br />
<br />
<texcode><br />
\unprotect<br />
\def\!test{alfa} <br />
\protect <br />
</texcode><br />
<br />
The newly defined command <tt>\!test</tt> can of course only be called upon when we are in the <cmd>unprotect</cmd>ed state, otherwise TeX reads the command <tt>\!</tt>, followed by the word <tt>test</tt> (and probably complains loudly about not being in math mode). These protection/unprotection commands can be nested. 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 <cmd>unprotect</cmd> and end them with <cmd>protect</cmd>.<br />
<br />
'''See also''':<br />
[[Commands with KeyVal arguments|Commands with Key=Value arguments]], <br />
[[Commands with optional arguments]]<br />
><br />
<br />
== Processing lists of values ==<br />
=== Processing a comma-separated list of values ===<br />
<br />
Suppose you defined a command like this one somewhere in your document:<br />
<texcode><br />
\def\IHaveTo#1#2{I have to #1 on #2.\par}<br />
</texcode><br />
So calling<br />
<texcode><br />
\IHaveTo{tidy up}{Monday}<br />
</texcode><br />
Will print out<br />
I have to tidy up on Monday.<br />
<br />
But sometimes you have to repeat some task more than once. In this case you can define a new command:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\processcommalist[#1]{\IHaveTo{#2}}}<br />
</texcode><br />
Calling<br />
<texcode><br />
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}<br />
</texcode><br />
will spare you some typing <i>(however not tidying up!)</i>:<br />
<br />
I have to tidy up on Monday.<br />
I have to tidy up on Wednesday.<br />
I have to tidy up on Saturday.<br />
<br />
In case a command <tt>\IHaveTo</tt> is already defined in a slightly different way:<br />
<texcode><br />
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}<br />
</texcode><br />
you can define <tt>\MyMumOrderedMeTo</tt> as:<br />
<texcode><br />
\def\MyMumOrderedMeTo[#1]#2%<br />
{\begingroup<br />
\def\processitem##1{\IHaveTo[##1]{#2}}%<br />
\processcommalist[#1]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
=== Processing a dash-separated list of values ===<br />
<br />
Sometimes you have more work to do than just that borring stuff at home. And as it is quite important as well, you don't want to loose your time enumerating all of the tasks. Being able to do something like<br />
<texcode><br />
\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}<br />
</texcode><br />
may sound like a good idea.<br />
<br />
Suppose you already defined:<br />
<texcode><br />
\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2.\par}<br />
</texcode><br />
<br />
You have to define some macros first (thanks to Taco!):<br />
<texcode><br />
% a few auxiliary core macros are needed to uncompress the list.<br />
%<br />
% \uncompresslist is the twin of the already existing \compresslist<br />
% which works in the other direction (syst-new)<br />
%<br />
\unprotect<br />
<br />
% I guess this function is already available but couldnt find it...<br />
%<br />
\def\apptomac#1#2%<br />
{\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1,#2}\fi}<br />
<br />
% the next macro does this:<br />
%<br />
% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}<br />
% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}<br />
%<br />
% (the 1+ and -1 are needed to solve a counter offset.)<br />
\def\itemwithdash#1-#2-%<br />
{\@EA\dorecurse\@EA<br />
{\the\numexpr 1+#2-#1\relax}%<br />
{\@EA\apptomac\@EA\uncompressedlist\@EA<br />
{\the\numexpr #1-1+\recurselevel\relax}}}%<br />
<br />
% top level. The result will be in \uncompressedlist<br />
\def\uncompresslist[#1]%<br />
{\def\uncompressedlist{}%<br />
\def\processitem##1%<br />
{\doifinstringelse{-}{##1}<br />
{\itemwithdash##1-}<br />
{\apptomac\uncompressedlist{##1}}}%<br />
\processcommalist[#1]\processitem }<br />
<br />
\protect<br />
</texcode><br />
<br />
And then you're ready to define<br />
<texcode><br />
\def\IHaveToDoTheTasks[#1]#2%<br />
{\begingroup<br />
\uncompresslist[#1]% <= Yeah!<br />
\def\processitem##1{\IHaveToDoTheTask[##1]{#2}}%<br />
\processcommacommand[\uncompressedlist]\processitem<br />
\endgroup}<br />
</texcode><br />
<br />
Guess what! Your <tt>\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}</tt> resulted in:<br />
The task 1 has to be done until tomorrow.<br />
The task 2 has to be done until tomorrow.<br />
The task 3 has to be done until tomorrow.<br />
The task 4 has to be done until tomorrow.<br />
The task 7 has to be done until tomorrow.<br />
The task 9 has to be done until tomorrow.<br />
The task 10 has to be done until tomorrow.<br />
The task 11 has to be done until tomorrow.<br />
<br />
So - what are you still waiting for? Go back to work and do them right away!<br />
<br />
=== Comments ===<br />
Resulted from thread [http://archive.contextgarden.net/thread/20050704.151237.f815d89d.html] and will be used in some modules such as [[RawSteps]]. It would be nice if processing dash-separated lists of values would make it into the ConTeXt core.<br />
<br />
<br />
== Passing verbatim text as macro parameter ==<br />
<br />
In case you want to write macros that should handle verbatim text,<br />
you can use the tex primitives <tt>\obeyspaces</tt> and <tt>\obeylines</tt>.<br />
<tt>\obeyspaces</tt> changes the category code of the space character,<br />
so that spaces become significant. <tt>\obeylines</tt> does the same for the<br />
newline character.<br />
<br />
This works fine for the following example:<br />
<br />
<texcode><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</texcode><br />
<br />
<context><br />
\framed{\obeyspaces{A gap from here to there!}}<br />
</context><br />
<br />
But if you pass this text as a parameter for your own macro<br />
<tt>\TextWithSpaces</tt><br />
<br />
<texcode><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</texcode><br />
<br />
<context><br />
\def\TextWithSpaces#1{\framed{\obeyspaces#1}}%<br />
\TextWithSpaces{A gap from here to there!}<br />
</context><br />
<br />
the additional spaces are '''ignored'''.<br />
This happens because the category code change is not yet in effect when<br />
the argument is parsed, and the spaces are removed during parsing. To keep<br />
the spaces, the catcode change must be done '''before''' the argument is parsed.<br />
<br />
Here is a two-part solution for the problem (''suggested by Taco Hoekwater''):<br />
<br />
<texcode><br />
\def\TextWithSpaces{\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces#1{\framed{#1}\egroup}<br />
</texcode><br />
<br />
Another way is to postpone argument loading (''suggested by Hans Hagen'').<br />
<br />
<texcode><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
</texcode><br />
<br />
Both of these produce the desired result:<br />
<br />
<context><br />
\def \TextWithSpaces {\framed\bgroup\obeyspaces\doTextWithSpaces}<br />
\def\doTextWithSpaces #1{#1\egroup} <br />
<br />
\TextWithSpaces{A gap from here to there!}<br />
</context></div>171.64.119.38