System Macros/Action Processing

From ConTeXt wiki
Jump to navigationJump to search

< Prev: Loops & Recursion | Top: System Macros | Next: Comma Separated Lists >

ConTeXt makes extensive use of a sort of case or switch command. Depending of the presence of one or more provided items, some actions is taken. These macros can be nested without problems.

\processaction           [x]     [a=>\a,b=>\b,c=>\c]
\processfirstactioninset [x,y,z] [a=>\a,b=>\b,c=>\c]
\processallactionsinset  [x,y,z] [a=>\a,b=>\b,c=>\c]

This macro is most often used in the key-value parser, like in this (simplified) example, where the user has said width=small or something similar:

\processaction
    [\TESTwidth] % should expand to 'small'
    [small=>\message{small was chosen},
     medium=>\message{medium was chosen}]

You can supply both a default action and an action to be undertaken when an unknown value is met:

\processallactionsinset
    [x,y,z]
    [a=>\a,
     b=>\b,
     c=>\c,
     default=>\default,
     unknown=>\unknown{... \commalistelement ...}]

If the first argument is empty, this macro scans the list for the keyword default and executes the related action, if present. If the first argument is not empty but also not in the list, the action related to unknown is executed. Both keywords must be at the end of list #2. Afterwards, the actually found keyword is available in \commalistelement.

Sometimes an action needs to be undertaken that depends only on the first character of something (for instance, checking if some string represents a number or not). This macro get this character and puts it in \firstcharacter.

\getfirstcharacter {string}

Problems with expansion

Be aware that \processaction is not fully expandable. This means that the following won't work.

\def\MyMacro#1{\processaction[#1][a=>\a,b=>\b]}
\edef\x{\MyMacro{a}}

A solution in MkIV proposed by Taco on [2010-05-13] is to define \MyMacro as follows

\def\MyMacro#1{\directlua{
    local known = {a = '\a', b = '\b'}
    tex.sprint(known['#1'] or '\a')}}

Another way that should work in MkII too:

\getparameters[MyMacro:][a=\a,b=\b]
\def\MyMacro#1{\doifdefinedelse{MyMacro:#1}{\getvalue{MyMacro:#1}}{\a}}


< Prev: Loops & Recusion | Top: System Macros | Next: Comma Separated Lists >