Marco's already posted a version, but this is I think a bit closer to what you were trying, just fixed the #1
/##1
confusion.
\documentclass{article}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{xkeyval}% http://ctan.org/pkg/xkeyval
\newenvironment{realign}[1][]
{\let\myalignment\relax\setkeys{fam}{#1}\myalignment}% \begin{realign}
{}% \end{realign}
\makeatletter
\define@choicekey*{fam}{align}[\val\nr]{left,center,right}{%
\ifcase\nr\relax
\def\myalignment{\raggedright}% align=left
\or
\def\myalignment{\centering}% align=center
\or
\def\myalignment{\raggedleft}% align=right
\fi
}
\newcommand{\newboolkey}[1]{
\define@boolkey{fam}[@bool@]{#1}[true]{%
\csname if##1\endcsname
\setkeys{fam}{align=#1}%
\csname fi\endcsname
}%
}
\makeatother
\begin{document}
\begin{realign}[align=left]
\lipsum[1]
\end{realign}
\newboolkey{left}% Create a boolean equivalent for align=left
\makeatletter
\if@bool@left\else% Check if key is defined.
\texttt{left} key defined
\fi
\begin{realign}[left]% Doesn't work
\lipsum[1]
\end{realign}
\end{document}
Here is a very elementary view on LaTeX's key-value system using keyval
, similar to what was presented in How to create a command with key values?:
\documentclass{article}
\usepackage{keyval,xparse}% http://ctan.org/pkg/{keyval,xparse}
\makeatletter
% ========= KEY DEFINITIONS =========
\define@key{mymacro}{first}{\def\mm@first{#1}}
\define@key{mymacro}{second}{\def\mm@second{#1}}
\define@key{mymacro}{third}{\def\mm@third{#1}}
\define@key{mymacro}{last}{\def\mm@last{#1}}
\DeclareDocumentCommand{\myMacro}{m}{%
\begingroup%
% ========= KEY DEFAULTS + new ones =========
\setkeys{mymacro}{first={FIRST arg},second={SECOND arg},third={THIRD arg},last={LAST arg},#1}%
First arg: \mm@first \par
Second arg: \mm@second \par
Third arg: \mm@third \par
Last arg: \mm@last
\endgroup%
}
\makeatother
\begin{document}
\myMacro{last=LaSt,first=FiRsT} \par \hrulefill
\myMacro{} \par \hrulefill
\myMacro{third={$x^2$ \textbf{stuff}},second={}}
\end{document}
It should be evident that using a key-value approach removes the requirement to remember the order of the keys. That is, unless the keys have some interaction with one another.
Grouping (via \begingroup
...\endgroup
) localizes the changes to the keys. However, you can make things available globally. It just depends on your application. Moreover, it would be possible to adapt the key-values to actually create key-macros that you can re-use. This may be helpful if you have a area in your document where you perform a bunch of declarations, and want to re-use them later.
The above example translates just as well to document environments.
More extensions are provided by xkeyval
, ltxkeys
and even l3keys
from expl3
(see Programming key–value in expl3
).
Here's a practical example of using key-values to store data regarding movies through a movie declaration (\newMovie{<tag>}{<key-values>}
) and printing it (\showMovie{<tag>}
):
\documentclass{article}
\usepackage{keyval,xparse,url}% http://ctan.org/pkg/{keyval,xparse,url}
\makeatletter
% ========= KEY DEFINITIONS =========
\define@key{movie}{title}{\expandafter\def\csname \movietag @title\endcsname{#1}}
\define@key{movie}{releaseyear}{\expandafter\def\csname \movietag @releaseyear\endcsname{#1}}
\define@key{movie}{genre}{\expandafter\def\csname \movietag @genre\endcsname{#1}}
\define@key{movie}{url}{\expandafter\def\csname \movietag @url\endcsname{#1}}
\DeclareDocumentCommand{\newMovie}{m m}{%
% ========= KEY DEFAULTS + new ones =========
\def\movietag{#1}% Store movie tag (used when setting/storing keys)
\setkeys{movie}{title={},releaseyear={},genre={},url={},#2}% Create keys
}
\DeclareDocumentCommand{\showMovie}{m}{%
\textbf{\csname #1@title\endcsname} (\csname #1@releaseyear\endcsname),
\textit{\csname #1@genre\endcsname},
\expandafter\expandafter\expandafter\url\expandafter\expandafter\expandafter{\csname #1@url\endcsname}.
}
\makeatother
\begin{document}
% Movie declarations
\newMovie{anchorman2}{
url={http://www.imdb.com/title/tt1229340/},
releaseyear=2013,
title={Anchorman: The Legend Continues},
genre=Comedy}
\newMovie{lego}{
title={The Lego Movie},
releaseyear=2014,
url={http://www.imdb.com/title/tt1490017/},
genre={Animation, Action, Comedy}}
\newMovie{magic}{
title={Now You See Me},
url={http://www.imdb.com/title/tt1670345/},
releaseyear=2013,
genre={Crime, Thriller}}
% Show movie details
\showMovie{magic}
\showMovie{anchorman2}
\showMovie{lego}
\end{document}
There are other (perhaps better) ways of dealing with this, but again, this is just to showcase what you can do with key-value approaches to macros (and databases).
Best Answer
There are several packages for defining a key=value syntax. I'll show
keyval
as it's part pf the basic latex distribution, and I know something about it.If you LaTeX the following:
You will see both keys have been processed and the following typeouts are made
The way this works is the package handles the splitting up of the comma separated settings , but for each key "key" and "color" here you have to define a command that does something with the value. Here the key is a number to be saved in
\count@
and the colour is treated as text stored in\thiscolor
, then after processing the keys these values can be used as normal TeX code.