9

I am trying to make a new command called \com which can do the following:

  • If no argument is provided to \com, $\com$ produces the symbol $\lambda$.
  • If one argument is provided, e.g. $\com{f}$, the macro produces $\lambda [f]$ (with square brackets).
  • If two arguments are provided, e.g. $\com{f}{x}$, the macro produces symbol $\lambda {f}(x)$ (with curly braces and round parentheses, resp.).

I have tried if else commands from the other posts but I am unable to make this work.

If some one can show me how to do this, I would be grateful.

  • 1
    This is a command with two optional arguments, effectively. – user31729 Mar 17 '17 at 19:36
  • That is true. But I won't know how to program this. – Jessica Simonelli Mar 17 '17 at 19:37
  • Should your third bullet say $\lambda \{f\}(x)$? – David Richerby Mar 18 '17 at 13:44
  • You can even aim higher and it's easier with xparse. \com = \lambda; \com[f] = \lambda[f]; \com{f}(x) = \lambda\{f\}(x). That way your code resembles the output and is easier to understand. – Manuel Mar 18 '17 at 14:46
  • Related/duplicate: Variable number of arguments in a command – Werner Mar 18 '17 at 23:45
11

This is quite easy with xparse and \NewDocumentCommand, having two optional arguments, however, you need to check for their existence.

Please note that oo could be replaced by gg to allow for optional {}{} arguments, but that's not recommended, but see below in this answer as an alternative.

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\com}{oo}{%
  \lambda%
  %Check if the first arg is given
  \IfValueT{#1}{%
    % Now check if has a 2nd argument as well. 
    \IfValueTF{#2}{% Yes, the 2nd one is present, use {f}(x) style
      \{#1\}(#2)%
    }{% No, use [f] style
      [#1]% 
    }%
  }%
}

\begin{document}

$\com$

$\com[f]$

$\com[f][x]$

\end{document}

enter image description here

Update with gg type (use it with care!) and another optional argument to use that instead of \lambda

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\com}{oo}{%
  \lambda%
  %Check if the first arg is given
  \IfValueT{#1}{%
    % Now check if has a 2nd argument as well. 
    \IfValueTF{#2}{% Yes, the 2nd one is present, use {f}(x) style
      \{#1\}(#2)%
    }{% No, use [f] style
      [#1]% 
    }%
  }%
}

\NewDocumentCommand{\comother}{O{\lambda}gg}{%
  #1%
  %Check if the first arg is given
  \IfValueT{#2}{%
    % Now check if has a 2nd argument as well. 
    \IfValueTF{#3}{% Yes, the 2nd one is present, use {f}(x) style
      \{#2\}(#3)%
    }{% No, use [f] style
      [#2]% 
    }%
  }%
}


\begin{document}

$\com$

$\com[f]$

$\com[f][x]$


$\comother$

$\comother{f}$

$\comother{f}{x}$

% Now with \beta instead of \lambda

$\comother[\beta]$

$\comother[\beta]{h}$

$\comother[\beta]{h}{y}$
\end{document}

enter image description here

9

Of course, the syntax uses the standard LaTeX convention of optional arguments in square brackets, in this case for both optional arguments.

Also, the OP implied that the command should be used not in math mode, so I have accommodated that.

\documentclass{article}
\newcommand\com[1][\relax]{\ifx\relax#1$\lambda$\else\def\firstarg{#1}\comhelp\fi}
\newcommand\comhelp[1][\relax]{\ifx\relax#1$\lambda [\firstarg]$%
  \else$\lambda \{\firstarg\}(#1)$\fi}
\begin{document}
\com\quad\com[f]\quad\com[f][x]
\end{document}

enter image description here

For a version that instead oeprates in math mode, here it is:

\documentclass{article}
\newcommand\com[1][\relax]{\ifx\relax#1\lambda\else\def\firstarg{#1}\comhelp\fi}
\newcommand\comhelp[1][\relax]{\ifx\relax#1\lambda [\firstarg]%
  \else\lambda \{\firstarg\}(#1)\fi}
\begin{document}
$\com\quad\com[f]\quad\com[f][x]$
\end{document}
8

Here's a LuaLaTeX-based solution. It works as a preprocessor: The Lua function comscan runs at a very early stage of processing, before TeX gets to do its usual work. The Lua function find all instances of \com and replaces with a different macro, depending on whether \com is found to have 0, 1, or 2 arguments.

enter image description here

% !TeX program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function comscan ( s )
  s = string.gsub ( s , "\\com(%b{})(%b{})" , "\\lambda\\{%1\\}(%2)" )
  s = string.gsub ( s , "\\com(%b{})", "\\lambda[%1]" )
  s = string.gsub ( s , "\\com(%A)" , "\\lambda%1" )
  return ( s )
end
luatexbase.add_to_callback( "process_input_buffer", comscan, "comscan" )
\end{luacode}
\providecommand{\command}{aaa} % dummy command
\begin{document}
$\com{f}{x}$, $\com{g}$, $ \com $, \command
\end{document}
  • 1
    One might also consider using the token scanner to do this without using the callback ... – Joseph Wright Mar 18 '17 at 9:12
  • 1
    @JosephWright - An excellent idea. :-) Do you want to provide a separate answer to show to achieve the OP's objective via the token scanner? (I'm afraid my knowledge of Lua(La)TeX isn't deep enough in this regard.) – Mico Mar 18 '17 at 9:57
5

Since you are going to use non-standard arguments, I think you could aim to a more easier to read code. That way [f] outputs brackets, {f} outputs curly braces (here's where you avoid typing \{f\}) and (f) outputs parenthesis.

With this minimal code, you ensure that \com, \com[f] and \com{f}(g) behave as you would expect (the only intelligence given to the command is to convert {f} to \{f\}, the rest is left unchanged and works as you would expect).

\usepackage{xparse}
\NewDocumentCommand\com{g}{\lambda\IfValueT{#1}{\{#1\}}}

If you really need those to be treated as arguments and you need a bit more intelligence, then you need to define the full command

\NewDocumentCommand\com{o}{\lambda\IfValueTF{#1}{[#1]}{\comaux}}
\NewDocumentCommand\comaux{gd()}{\IfValueT{#2}{\{#1\}}\IfValueT{#2}{(#2)}}
  • I mentioned the usage of g already yesterday in my answer (+1 anyway ;-) ) – user31729 Mar 18 '17 at 16:14
  • @ChristianHupfer Well, my answer was more into the “use natural markup” which can be easy with xparse; true that it uses g as your answer, but that was not the core of my answer so that's why I posted it. – Manuel Mar 18 '17 at 17:04

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.