I would like to be able to create a command (using pgfkeys
) that can take inputs that are of a limited set of forms, and for which certain pieces will come from a limited set of values. More specifcally, any input will have some piece A
(which will come from a known list), and for some values of A
, additional information #1
, #2
, etc. (not from a known list) can also be specified, using a limited set of forms, but need not be.
For a made-up example, let's say that my command is \meal
, and A
will be an element of the list
chicken, beef, tofu
When A
is either chicken
or beef
, the following forms of additional information can be specified like this:
chicken with #1
chicken on a bed of #1
beef with #1
beef with #1 or #2
I would like to have the greatest possible versatility in what happens once the correct form is determined, and the input is understood. For example, suppose I want
\meal{chicken} -> Chicken
\meal{chicken with #1} -> CHICKEN (with #1? uggh)
\meal{chicken on a bed of #1} -> #1, underneath chicken
\meal{beef} -> Beef
\meal{beef with #1} -> Beef and a side of #1
\meal{beef with #1 or #2} -> Beef with your choice of #1 or #2 as a side
\meal{tofu} -> Tofu
I realize this is already a pretty tall order (ha ha), but for some modicum of simplicity, assume that we will never need to write
\meal{chicken on a bed of beef with chicken}
or other things that would be confusing to the computer.
Now, I was doing some preliminary testing (before trying to make something that did all of the things I wanted), and I ran into a problem. The code I wrote, after being adapted to this made-up example, would be
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{%
mealname/.initial = ,%
overform/.style args = {#1 over #2}{mealname = #1 over #2},%
andform/.style args = {#1 and #2}{mealname = #1 and #2}%
noform/.style = {mealname = #1}%
}
\newcommand{\meal}[1]{%
\pgfkeys{%
overform/.try = #1,%
andform/.retry = #1,%
noform/.retry = #1,%
mealname/.get = \mealname}%
\mealname%
}
\begin{document}
\meal{A over B}
\end{document}
This runs fine; however, when I replace A over B
with A and B
, I get the error
File ended while scanning use of \pgfkeys@code
What I assume is happening is that pgfkeys
is attempting to find an occurrence of the word over
in the input A and B
, and is in an infinite loop or in one way or another breaks because it cannot find it. I had hoped that after failing to find over
anywhere, an error would be thrown that told /.try
to stop, but this does not appear to be the case.
Now, I realize that what I am asking for may be a little silly, given that pgfkeys
is for "key-value arguments", because a solution that is much easier to code (but slightly less intuitive to use) would be to have each of the different forms (chicken
, chicken with
, etc.) be its own key, and accept inputs like this:
\meal{chicken}
\meal{chicken with = #1}
...
or alternatively, have each value of A
be a family, with the forms as subkeys; e.g., calling the key chicken
would /.cd
us into the /chicken/
family, where there are keys /chicken/with
and /chicken/on a bed of
, so that one could write
\meal{chicken}
\meal{chicken, with = #1}
...
Perhaps I am just being unreasonably picky in wanting to avoid the equals signs; but to the greatest extent possible, I would want the code of my document to model natural English expressions (in addition to just wanting to figure out how to do it out for the challenge / out of curiosity).
So, my question is: is there any way of achieving my desired command with pgfkeys
? Is there some other package or approach that can do it? Assuming my approach was at least somewhat on the right track: is there any way I can use the /.style args
key handler (perhaps together with the /.try
handler?) to determine which form the input is, and do the correct operations for that form, without running into an infinite loop trying to test whether the input is of a given form?
\meal{meal=chicken, with=<1> or <2>, on a bed of=<3>}
(or\meal{chicken}{with=…, on a bed of=…}
) wheremeal
is a.is choice
key (so you can pre-define which values are allowed), andor <2>
is optional (as well as the use ofwith
andon a bed of
, of course). With the filtering facilities of PGF keys it is probably also doable to deactivate any use ofwith
andon a bed of
whenmeal=Tofu
.