[OS X TeX] Defining an if-like macro

Ross Moore ross.moore at mq.edu.au
Thu Feb 6 17:57:08 EST 2014

Hi Jason,

On 07/02/2014, at 8:14, "J. McKenzie Alexander" <jalex at lse.ac.uk> wrote:

> Hello,
>
> I’ve written a simple package which permits conditional inclusion of material with more sophisticated logical constraints on what gets included than can easily be generated with \newif conditionals.  But it misbehaves in one context, and I was wondering if there was some clever way around it…
>
> Let me first describe the package (in case anyone is interested), before I mention the misbehaviour.
>
> The package is available here, in case anyone wants to try it (bug reports appreciated!):
>
> 	https://www.dropbox.com/s/l1vmwlsfui6sbxt/ifkeys.sty
>
> Here’s how it works… You call a macro called \SetKeys with a comma-separated list of key names (spaces permitted). Those keys are true, all other keys are false.

Is \SetKeys  called just once, in the preamble say, or do you change the keys throughout the document?

And is the material that is conditionally supplied complete environments, or can it be material that is inline within paragraphs?

If inline is allowed, then you will be restricted in various ways; nesting of lots of \if...  commands can be very tricky, as you are discovering.

If you only use full environments, then the  comment.sty  package can be very useful.
But the more keys you have, the more \include...  and \exclude... environments will be needed, and you may not be able to change the key settings within the body of the document.
(Not sure on this, as I've not tried it with real typesetting jobs.)

If all possible combinations of keys need to be supported, then the number of environment definitions goes up exponentially as a power of 2.

>
> Another macro, \ifkeys, is defined, which takes an expression in *disjunctive normal form* as its argument. It then checks whether that expression is satisfied and, if so, evaluates to \iftrue, otherwise \iffalse.  The expression uses commas to separate each disjunct, and && to indicate conjunction of key values within each disjunct. And ~ is allowed to specify negation of key values, too. (Since every expression can be written in disjunctive normal form, this allows all logical constraints on keys to be specified, even if at some expense of length.)
>
> Here’s an example of how it can be used (the number of spaces used in keys doesn’t matter):
>
> \SetKeys{ key one, key two, key three, a really long key name }
>
> \ifkeys{ key one && key two }
> This is where you put some additional material to be conditionally included exactly when ``key one'' and ``key two'' are both set.
> \fi
>
> \ifkeys{ key one && ~key three }
> This is where you put some additional material to be conditionally included exactly when ``key one'' is set and ``key three'' is not.
> \else
> You can also use an \verb+\else+ clause to insert material in
> cases where the specified condition is not satisfied.
> \fi

Do you change the \catcode of  & (and ~ ) on the fly?
I can envision big problems using this within tabular contexts.

>
> \ifkeys{a really long key name}
> Keys can have long names with spaces, as well!
> \fi
>
> \ifkeys{ key one && ~key two, ~key three, ~key four}
> Keys which are not mentioned in \verb+\SetKeys+ are assumed to be false, so this will appear.
> \fi
>
>
> Ok — now for the problem… The \ifkeys macro cannot be nested with itself or other conditionals, because TeX has a special mechanism for skipping past material at high speeds once it encounters an \iffalse. (It generates the “Extra \fi” error message.) I suspect that there’s no easy / elegant solution for this, but I wanted to ask just in case.

This is very hard; indeed impossible to do it this way, I think.

The reason is that when skipping over the undesired block, \ifkeys  will not be expanded.
This means that its matching \else and \fi  will be assumed to delimit the previous  \if... .
Thus your logical structure is not properly captured and you will get those “Extra \fi” and “Extra \else” error messages.

You need your delimiters to always be evaluated.

Have a look at  comment.sty   and see whether this is suitable for your actual needs.

>
> Many thanks,
>
> Jason
>
> --
> Prof. J. McKenzie Alexander
> Department of Philosophy, Logic and Scientific Method
> London School of Economics
> Houghton Street, London WC2A 2AE

Hope this helps,

Ross
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://email.esm.psu.edu/pipermail/macosx-tex/attachments/20140207/8cfb6789/attachment.html>