Changes

Jump to navigation Jump to search
1,982 bytes added ,  07:39, 25 January 2017
m
typo correction
< [[Main Page]]> == Programming Topics == === ConTeXt Features ===* [[Modes]]: Conditional processing of text* [[Setups]]: An alternative to macros for storing chunks of code === Commands and Arguments ===* [[System Macros]] (''Recommended reading''. Topics: temporary variables, expansion control, argument grabbing and handling, definitions and assignments, branches and decisions, cases, comma separated lists, assignments and parameters, user interaction.)* [[Programming in LuaTeX]] (Topic: alleviating the more cumbersome sides of TeX programming.)* [[Commands with KeyVal arguments|Commands with Key=Value arguments]]: (Topic: things like <code>\command[thiskey=thatvalue]</code>.) * [[Commands with optional arguments]]: (Topic: one or more optional arguments within brackets.) === Module Parameters ===* [[Module Parameters]]: Passing parameters to modules. === Programming Techniques ===* [[Processing Lists]]: Processing lists of values* [[Counters]]: Manipulating counters in context* [[Expressions]]: Evaluating expressions of type number, dimen, glue or muglue* [[executesystemcommand]]: process contents of an environment by another program* Loops and expansion [http://randomdeterminism.wordpress.com/2009/03/05/tex-programming-the-past-the-present-and-the-future/ (blog post)] === Debugging === * [[Console Mode]]: Using ConTeXt on keyboard input directly, rather than loading a <tt>.tex</tt> file.
== Using variables ==
 
There are several ways to handle variables in ConTeXt.
The recommended and easiest method is to use the
<tt>\setvariables</tt> and <tt>\getvariable</tt> macros.
Doing it this way you also avoid to get in conflict with
already defined stuff (as variables use their own namespace).
 
To store variables, you can use the <tt>\setvariables</tt>
macro.
<texcode>
% stores value in variable namespace:key
\setvariables[namespace][key=value]
% stores the expanded value
\setevariables[namespace][key=value]
% global
\setgvariables[namespace][key=value]
% global and expanded value
\setxvariables[namespace][key=value]
</texcode>
 
Use <tt>\getvariable</tt> to process a variable. Reading an undefined
variable results in the <tt>\empty</tt> token. This is not a serious problem,
as long as you expect text only.
But be warned: the compilation process breaks, if you expect a dimension
or number. So better take care, that you define your variables, before you use them.
 
<texcode>
% gets value of the variable namespace:key
\getvariable{namespace}{key}
</texcode>
 
To avoid problems, also pay attention to the following:
 
You can set several variables (same namespace) at the same time.
So the command <tt>\setvariables</tt> logically uses the '''plural''' form
and works with '''square brackets'''.
On the other hand you can only process one variable at the same time, so
<tt>\getvariable</tt> uses the '''singular''' form and works with '''braces'''.
 
OK, here comes a simple example. Let's say, that we want to have variable
space before and after a letter macro called <tt>\Opening</tt>.
 
<texcode>
\long\def\Opening#1{%
\getvariable{Letter:opening}{before}
\noindent{\begstrut#1\endstrut}
\getvariable{Letter:opening}{after}
}
</texcode>
 
By using variables in your macros, you can separate the layout definition,
so that your macros get much more flexible.
Just ensure, that all variables are set, before you use them!
 
In this example we want to have a blank line in front of the opening, and
two blank lines right after it. The value for the second key contains
square brackets, so it must be enclosed in braces.
 
<texcode>
\setvariables[Letter:opening]
[before=\blank,
after={\blank[2*big]},
]
</texcode>
 
You can now save this style setup (among others) in a separate file and
include it at the start of your document (before <tt>\Opening</tt> is
defined or at least used).
 
And don't forget:
'''Ensure that all variables are set before you use them!'''
 
== Defining new commands ==
'''=== Special characters in command names'''===
Some commands have special characters in their names, that TeX normally does not consider to be
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>.
'''See also''':
[[Commands with KeyVal arguments|Commands with Key=Value arguments]],
[[Commands with optional arguments]]
>
== Processing lists of values ===== Processing a comma-separated list of values =Passing verbatim text as macro parameter ==
Suppose you defined a command like this one somewhere in your document:<texcode>\def\IHaveTo#1#2{I have (For passing text to LuaTex verbatim, see the [[Programming_in_LuaTeX#1 Manipulating_verbatim_text_for_dummies|Programming in LuaTeX]] article on #2.\par}</texcode>So calling<texcode>\IHaveTo{tidy up}{Monday}</texcode>Will print out I have to tidy up on Mondaythis wiki.)
But sometimes In case you have want to repeat some task more than once. In this case write macros that should handle verbatim text,you can define a new command:use the tex primitives <texcodett>\def\MyMumOrderedMeTo[#1]#2% {\processcommalist[#1]{obeyspaces</tt> and <tt>\IHaveTo{#2}}}obeylines</texcodett>Calling.<texcodett>\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}obeyspaces</texcodett>changes the category code of the space character,will spare you some typing so that spaces become significant. <itt>(however not tidying up!)\obeylines</itt>:does the same for thenewline character.
I have to tidy up on Monday. I have to tidy up on Wednesday. I have to tidy up on Saturday.This works fine for the following example:
In case a command <tt>\IHaveTo</tt> is already defined in a slightly different way:
<texcode>
\def\IHaveTo[#1]#2{I have to #2 on #1.\par}
</texcode>
you can define <tt>\MyMumOrderedMeTo</tt> as:
<texcode>
\def\MyMumOrderedMeTo[#1]#2% framed{\begingroup \def\processitem##1obeyspaces{\IHaveTo[##1]{#2A gap from here to there!}}% \processcommalist[#1]\processitem \endgroup}
</texcode>
=== Processing a dash-separated list of values ===<context>\framed{\obeyspaces{A gap from here to there!}}</context>
Sometimes But if you have more work to do than just that borring stuff at home. And pass this text as it is quite important as well, you don't want to loose a parameter for your time enumerating all of the tasks. Being able to do something likeown macro<texcodett>\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}TextWithSpaces</texcodett>may sound like a good idea.
Suppose you already defined:
<texcode>
\def\IHaveToDoTheTask[TextWithSpaces#1]#2{The task \framed{\obeyspaces#1 has }}%\TextWithSpaces{A gap from here to be done #2.\parthere!}
</texcode>
You have to define some macros first (thanks to Taco!):<texcodecontext>% a few auxiliary core macros are needed to uncompress the list.%% \uncompresslist is the twin of the already existing def\TextWithSpaces#1{\framed{\compresslistobeyspaces#1}}% which works in the other direction (syst-new)%\TextWithSpaces{A gap from here to there!}\unprotect</context>
% I guess this function is already available but couldnt find it..the additional spaces are '''ignored'''.%This happens because the category code change is not yet in effect when\def\apptomac#1#2%the argument is parsed, and the spaces are removed during parsing. To keep {\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1the spaces,#2}\fi}the catcode change must be done '''before''' the argument is parsed.
% Here is a two-part solution for the next macro does this:%% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}%% problem (the 1+ and -1 are needed to solve a counter offset.''suggested by Taco Hoekwater'')\def\itemwithdash#1-#2-% {\@EA\dorecurse\@EA {\the\numexpr 1+#2-#1\relax}% {\@EA\apptomac\@EA\uncompressedlist\@EA {\the\numexpr #1-1+\recurselevel\relax}}}%:
% top level. The result will be in \uncompressedlist<texcode>\def\uncompresslist[#1]% TextWithSpaces{\defbgroup\obeyspaces\uncompressedlist{doTextWithSpaces}% \def\processitem#doTextWithSpaces#1% {\doifinstringelseframed{-}{##1} {\itemwithdash##1-egroup} {\apptomac\uncompressedlist{##1}}}% \processcommalist[#1]\processitem }</texcode>
\protect</texcode>Another way is to postpone argument loading (''suggested by Hans Hagen'').
And then you're ready to define
<texcode>
\def \IHaveToDoTheTasks[#1]#2% TextWithSpaces {\begingroup framed\bgroup\obeyspaces\uncompresslist[#1]% <= Yeah!doTextWithSpaces} \def\processitem#doTextWithSpaces #1{\IHaveToDoTheTask[##1]{#2}}% \processcommacommand[\uncompressedlist]\processitem \endgroupegroup}
</texcode>
Guess what! Your Both of these produce the desired result: <ttcontext>\IHaveToDoTheTasks[1-4,7,9-11]def \TextWithSpaces {until tomorrow\framed\bgroup\obeyspaces\doTextWithSpaces}</tt> resulted in: The task \def\doTextWithSpaces #1{#1 has to be done until tomorrow. The task 2 has to be done until tomorrow. The task 3 has to be done until tomorrow. The task 4 has to be done until tomorrow. The task 7 has to be done until tomorrow. The task 9 has to be done until tomorrow. The task 10 has to be done until tomorrow. The task 11 has to be done until tomorrow.\egroup}
So - what are you still waiting for? Go back \TextWithSpaces{A gap from here to work and do them right awaythere!}</context>
=== Comments ===Resulted from thread [http[Category://archive.contextgarden.net/thread/20050704.151237.f815d89d.htmlInside ConTeXt]] and will be used in some modules such as [[RawStepsCategory:ConTeXt programming]]. It would be nice if processing dash-separated lists of values would make it into the ConTeXt core.
19

edits

Navigation menu