I attempted to modify the \funcdef macro from egreg's solution from A macro adding or removing parenthesis automatically to use pgfkeys, but am running into some difficulty (probably related to some expansion issues). The text highlighted in red details the failing conditions:
Notes:
- The MWE seems long due to the
\funcdefcode, which is here in case one wishes to see the results with the other macro. The issues here are all related to the\FunctionMapmacro. The main differences between the
\FunctionMapmacro here and the linked\funcdef(other than usingpgfkeysinstead ofkeyval) is that\FunctionMap:- Requires both
domain=andcodomain=to be specified. - If
variable=is provided thennotation=must also be provided. - Only use an
arrayifvariable=is provided.
- Requires both
Questions:
- What changes are needed to resolve the failing conditions highlighted in red.
What case requires the use of the
\ifx\Notation\@empty \expandafter\@gobble \else \expandafter\@firstofone \fi
References:
- What do \@firstoftwo and \@secondoftwo do?.
- The
funcdefmacro is from A macro adding or removing parenthesis automatically. - How to use of
pgfkeysis explained How to create a command with key values?.
Code:
\documentclass{article}
\usepackage{amsmath,keyval}
\usepackage{pgfkeys}
\usepackage{xstring}
\usepackage{xcolor}
\makeatletter%% ------ egreg's version from https://tex.stackexchange.com/a/149727/4301
\newcommand{\funcdef@key}[1]{%
\define@key{funcdef}{#1}{\@namedef{cet@#1}{##1}}%
\expandafter\let\csname cet@#1\endcsname\@empty
}
\funcdef@key{name}
\funcdef@key{domain}
\funcdef@key{codomain}
\funcdef@key{variable}
\funcdef@key{variables}
\funcdef@key{notation}
\funcdef@key{definition}
\newcommand{\funcdef@check}[1]{%
\expandafter\ifx\csname cet@#1\endcsname\@empty
\@latex@error{Missing `#1'}{Provide `#1'}%
\fi
}
\newcommand{\funcdef}[1]{%
\begingroup
\setkeys{funcdef}{#1}%
\ifx\cet@codomain\@empty\let\cet@codomain\cet@domain\fi
\funcdef@check{name}%
\funcdef@check{domain}%
\ifx\cet@variables\@empty
\funcdef@check{variable}%
\fi
\begin{array}{l@{}r@{}l@{}l}
\cet@name\colon{} &
\cet@domain &
{}\to \cet@codomain \\
&
\ifx\cet@variable\@empty
(\cet@variables)
\else
\cet@variable
\fi &
{}\mapsto
\ifx\cet@notation\@empty
\cet@name(
\ifx\cet@variable\@empty
\cet@variables
\else
\cet@variable
\fi
)
\else
\cet@notation
\fi
\ifx\cet@definition\@empty
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{& {}\mathrel{:}=\cet@definition}
\\
\end{array}
\endgroup
}
\makeatletter
%% -------------------------------- Modified pgfkeys version.
\pgfkeys{%
%% https://tex.stackexchange.com/a/34318/4301
/FunctionMap/.is family,% Define family directory
/FunctionMap,% Switch to this directory
default/.style={% Defaults
variable={},
%%notation={},%% No default so we get an error if variable is specified, but notation is not
},
name/.estore in = \Name,
domain/.estore in = \Domain,
codomain/.estore in = \Codomain,
variable/.estore in = \Variable,
notation/.estore in = \Notation,% Error if this is not specified, but variable is
}%
\newcommand{\FunctionMap}[1]{%
%% Requires both "domain=" and "codomain=" to be specified.
%% if "variable=" is provided then "notation=" must also be provided.
%% Only use an array if variable is provided
\begingroup%
\pgfkeys{/FunctionMap, default, #1}%
\IfStrEq{\Variable}{}{%
\Name\colon{}
\Domain
{}\mathrel{\to} \Codomain
}{%
\begin{array}{@{}l@{}r@{}l@{}l}
% https://tex.stackexchange.com/a/37791/4301
\Name\colon{}
& \Domain
& {}\mathrel{\to} \Codomain
\\
& \Variable
\ifx\Notation\@empty
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
& {}\mathrel{\mapsto} \Notation
\end{array}%
}%
\endgroup
}%
%% To switch to use \funcdef
%\let\FunctionMap\funcdef
\newcommand*{\Error}[1]{(\textcolor{red}{#1})}%
\begin{document}
\noindent
Simple function \Error{want to use `$\mathbf{R}$' here instead of `$R$'}:
\[
\FunctionMap{%
name=f,
domain=R, %\mathbf{R},% fails
codomain=R,% \mathbf{R},% fails
variable=x,
notation=f(x),
}
\]
Simple function with declaration:
\[
\FunctionMap{%
name=f,
domain=R,
codomain=R,
variable=x,
notation=x^2,
}
\]
Function with alternative writing \Error{Want to use `$\exp$' here instead of `$f$'}:
\[
\FunctionMap{%
name=f, %% \exp,% <-- fails
domain=R,
codomain=R,
variable=x,
notation=e^x
}
\]
Function with alternative writing and declaration:
\[
\FunctionMap{%
name=g,
variable=x,
domain=R,
codomain=R,
notation={e^x:=\lim\limits_{n\to\infty}\left(1+\frac xn\right)^n}
}
\]
Function with different domain and codomain
\Error{Want to use `$\operatorname{sqrt}$' and `$\sqrt{n}$' here instead of `$sqrt$'}:
\[
\FunctionMap{%
name=sqrt, %%\operatorname{sqrt},% <-- fails
domain=N, %\mathbf{N},% <-- fails
codomain=R,%\mathbf{R},% <-- fails
variable=n,
notation=sqrt{n}, %% \sqrt{n},% <-- fails
}
\]
%Function with different domain and codomain, alternative writing
%and declaration:
%\[
%\FunctionMap{%
% name=\operatorname{sqrt},
% domain=\mathbf{N},
% codomain=\mathbf{R},
% variable=n,
% notation=\sqrt{n},
% definition=\exp\bigl(\frac{1}{2}\ln n\bigr)
%}
%\]
Function of two variables:
\[
\FunctionMap{%
name=f,
domain=A\times B,
codomain=C,
variable={(a,b)},
notation=f(x),
}
\]
Function of with just domain and codomain:
\[
\FunctionMap{%
name=f,
domain=X,
codomain=Y,
}
\]
\end{document}
