1

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:

enter image description here

Notes:

  • The MWE seems long due to the \funcdef code, which is here in case one wishes to see the results with the other macro. The issues here are all related to the \FunctionMap macro.
  • The main differences between the \FunctionMap macro here and the linked \funcdef (other than using pgfkeys instead of keyval) is that \FunctionMap:

    • 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.

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:

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}
  • /.estore in expands the argument so mathbf is destined to fail there. I think you just need to collect the tokens. – percusse Dec 10 '16 at 2:12
  • @percusse: Well, that certainly was easy.. Thanks. You want to post that as an answer? – Peter Grill Dec 10 '16 at 7:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.