Open main menu

Changes

362 bytes removed ,  10:11, 16 December 2021
Add hints on bracket usage; c&p from the list: https://www.mail-archive.com/ntg-context@ntg.nl/msg87937.html
< [[Main Page]] >= Programming Topics =
== Using variables 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 <texcodecode>\command[thiskey=thatvalue]</code>.) \setvariables* [[namespaceCommands with optional arguments]]: (Topic: one or more optional arguments within brackets.) == Module Parameters ==* [[keyModule Parameters]]: Passing parameters to modules. ==valueProgramming Techniques ==* [[Processing Lists]]: Processing lists of values\getvariable{namespace}{key}* [[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/texcode>(blog post)]
{{todo|This could really use a specific example or two.}}== Debugging ==
== Defining new commands ==* [[Console Mode]]: Using ConTeXt on keyboard input directly, rather than loading a <tt>.tex</tt> file.
=== Special characters in command names ==Use of brackets =
Some commands have special characters in their names, that TeX normally does One must '''not consider to be ''' confuse with the LaTeX convention where "mandatory"letters: <tt>@</tt>, <tt>!</tt> and <tt>?</tt>. Before arguments are contained in curly braces and after the use or definition of such protected commands in your input files, the catcode of these brackets indicatecharacters has to be changed"optional" arguments. This is done by <cmd>unprotect</cmd> and <cmd>protect</cmd>:
<texcode>Curly braces not only give grouping but generallyare used for objects to be typeset, as for \unprotect\def\!testin{Figure}{alfaa} \protect </texcode>[fig:ref].
The newly defined command <tt>\!test</tt> For new users, it is worth repeating here that arguments within bracescan be either a comma-separated list of course only be called upon when we are in the <cmd>unprotect</cmd>ed statewords OR a comma-separatedlist of keyword=value pairs, otherwise TeX reads the command <tt>\!</tt>, followed by the word <tt>test</tt> (and probably complains loudly about not being in math mode)BUT NOT A MIXTURE OF BOTH. These protection/unprotection commands can be nested. When the nesting becomes deeper than one levelGenerally, the system reports the current protection level. It is a good habit to always start your macro files with <cmd>unprotect</cmd> keyword=value exists for all words, for example \cite[authoryear][ref]and end them with <cmd>protect</cmd>.\cite[alternative=authoryear,reference=ref]
=== See also ===values can be grouped using curly braces, as in\cite[[Commands with KeyVal arguments|Commands with Keyalternative=authoryear,lefttext=Value arguments{{see },}][ref1,ref2], where the[[Commands lefttext is associated with the first cite reference (and none with optional arguments]]the>second). This can be tricky but is in fact rather straight-forward.
== Processing lists of values ===== Processing a comma-separated list of values ==Using variables =
Suppose you defined a command like this one somewhere There are several ways to handle variables in your document:ConTeXt.The recommended and easiest method is to use the<texcodett>\def\IHaveTo#1#2{I have to #1 on #2.\par}setvariables</texcodett>So callingand <texcodett>\IHaveTo{tidy up}{Monday}getvariable</texcodett>macros.Doing it this way you also avoid to get in conflict withThis will print out:already defined stuff (as variables use their own namespace).
To store variables, you can use the <contexttt>\def\IHaveTo#1#2{I have to #1 on #2.\par}\IHaveTo{tidy up}{Monday}setvariables</contexttt>macro.
But sometimes you have to repeat some task more than once. In this case you can define a new command:
<texcode>
% stores value in variable namespace:key\defsetvariables[namespace][key=value]% stores the expanded value\MyMumOrderedMeTosetevariables[#1namespace]#2[key=value]%global {\processcommalistsetgvariables[#1namespace]{[key=value]% global and expanded value\IHaveTo{#2}}}setxvariables[namespace][key=value]
</texcode>
Calling
<texcode>
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}
</texcode>
will spare you some typing <i>(but not some tidying up!)</i>:
 
<context>
\def\IHaveTo#1#2{I have to #1 on #2.\par}
\def\MyMumOrderedMeTo[#1]#2%
{\processcommalist[#1]{\IHaveTo{#2}}}
\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}
</context>
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.
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% gets value of the variable namespace:<texcode>key\def\MyMumOrderedMeTo[#1]#2% getvariable{\begingroup \def\processitem##1namespace}{\IHaveTo[##1]{#2}}% \processcommalist[#1]\processitem \endgroupkey}
</texcode>
ThisTo avoid problems, again, producesalso pay attention to the following:
You can set several variables (same namespace) at the same time.So the command <tt>\setvariables<context/tt>logically uses the '''plural''' form\def\IHaveTo[#1]#2{I have to #2 on #1and works with '''square brackets'''.\par}\def\MyMumOrderedMeTo[#1]#2%On the other hand you can only process one variable at the same time, so {<tt>\begingroup \def\processitem##1{\IHaveTo[##1]{#2}}% \processcommalist[#1]\processitem \endgroup}\MyMumOrderedMeTo[Monday,Wednesday,Saturday]{tidy up}getvariable</contexttt>uses the '''singular''' form and works with '''braces'''.
=== Processing OK, here comes a dash-separated list of values ===simple example. Let's say, that we want to have variablespace before and after a letter macro called <tt>\Opening</tt>.
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
<texcode>
\IHaveToDoTheTasks[long\def\Opening#1-4,7,9-11]{until tomorrow% \getvariable{Letter:opening}{before} \noindent{\begstrut#1\endstrut} \getvariable{Letter:opening}{after}}
</texcode>
may sound like a good idea.
Suppose By using variables in your macros, you already defined:can separate the layout definition,<texcode>\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2so that your macros get much more flexible.\par}</texcode>Just ensure, that all variables are set, before you use them!
You In this example we want to have to define some macros first (thanks to Taco!):<texcode>% a few auxiliary core macros are needed to uncompress the list.%% \uncompresslist is the twin blank line in front of the already existing \compresslistopening, and% which works in the other direction (syst-new)%\unprotect % I guess this function is already available but couldnt find two blank lines right after it...%\def\apptomac#1#2%The value for the second key contains {\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1square brackets,#2}\fi} % the next macro does this:%% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}%% (the 1+ and -1 are needed to solve a counter offset.)\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 so it must be enclosed in \uncompressedlist\def\uncompresslist[#1]% {\def\uncompressedlist{}% \def\processitem##1% {\doifinstringelse{-}{##1} {\itemwithdash##1-} {\apptomac\uncompressedlist{##1}}}% \processcommalist[#1]\processitem } \protect</texcode>braces.
And then you're ready to define
<texcode>
\def\IHaveToDoTheTaskssetvariables[#1Letter:opening]#2% {[before=\begingroupblank, \uncompresslist[#1]% <after= Yeah! \def\processitem##1{\IHaveToDoTheTaskblank[##12*big]{#2}}%, \processcommacommand[\uncompressedlist ]\processitem \endgroup}
</texcode>
Guess what! Your You can now save this style setup (among others) in a separate file andinclude it at the start of your document (before <tt>\IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}Opening</tt> results in:isdefined or at least used).
<context>And don't forget:\def\IHaveToDoTheTask[#1]#2{The task #1 has to be done #2.\par}'''Ensure that all variables are set before you use them!'''
% a few auxiliary core macros are needed == CLD ==How to pass variable from TeX to uncompress the listLua and vice versa? See [[CLD_passing_variables#Variables|CLD passing variables]].%% \uncompresslist is the twin of the already existing \compresslist% which works in the other direction (syst-new)%\unprotect
% I guess this function is already available but couldnt find it...%\def\apptomac#1#2% {\ifx#1\empty\def#1{#2}\else \@EA\def\@EA#1\@EA{#1,#2}\fi}= Defining new commands =
% the next macro does this:%% \itemwithdash<<9-11>>- => \dorecurse {<<1+11-9>>}% {\apptomac\uncompressedlist<<9-1+\recurselevel>>}%% (the 1+ and -1 are needed to solve a counter offset.)\def\itemwithdash#1-#2-% {\@EA\dorecurse\@EA {\the\numexpr 1+#2-#1\relax}% {\@EA\apptomac\@EA\uncompressedlist\@EA {\the\numexpr #1-1+\recurselevel\relax}}}%= Special characters in command names ==
% top level. The result will Some commands have special characters in their names, that TeX normally does not consider to be in \uncompressedlist\def\uncompresslist[#1]%letters: <tt>@</tt>, <tt>!</tt> and <tt>?</tt>. {\def\uncompressedlist{}%Before and after the use or definition of such protected commands in your input files, the catcode of these \def\processitem##1% characters has to be changed. This is done by {\doifinstringelse{-cmd|unprotect}{##1} and {\itemwithdash##1-} {\apptomac\uncompressedlist{##1}}cmd|protect}% \processcommalist[#1]\processitem }:
<texcode>\protectunprotect\def\IHaveToDoTheTasks[#1]#2% {\begingroup \uncompresslist[#1]% <= Yeah! \def\processitem##1{\IHaveToDoTheTask[##1]test{#2}alfa}% \processcommacommand[\uncompressedlist]\processitem \endgroup} \IHaveToDoTheTasks[1-4,7,9-11]{until tomorrow}protect </contexttexcode>
So - what The newly defined command <tt>\!test</tt> can of course only be called upon when we are you still waiting for? Go back in the {{cmd|unprotect}}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 work always start your macro files with {{cmd|unprotect}} and do end them right away!with {{cmd|protect}}.
=== Comments ===
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.
= Passing verbatim text as macro parameter =
== Passing (For passing text to LuaTex verbatim text as macro parameter ==, see the [[Programming_in_LuaTeX#Manipulating_verbatim_text_for_dummies|Programming in LuaTeX]] article on this wiki.)
In case you want to write macros that should handle verbatim text,
</context>
[[Category:Inside ConTeXtProgramming and Databases]][[Category:Tools]]
57

edits