56

I'd like to create a new command \add that accepts 2 arguments, called entity and title. In other words, the command should look like this: \add{entity}{title}. The output should have the following form: \textit{entity} '{title}'.

So if I, for example, type \add{article}{LaTeX} the result should be article 'LaTeX'.

How can I do this?

1

6 Answers 6

78
\newcommand{\add}[2]{\textit{#1} {`#2'}}

For more reading material on this, see

2
  • 2
    you are welcome, AND welcome to TeX.SE! :)
    – nickpapior
    Nov 29, 2013 at 23:23
  • 3
    @Jeroen If you want correct single quotation marks for the second argument should use `#2'.
    – osjerick
    Nov 29, 2013 at 23:27
23

I'm going to suggest a very different approach which might seem like a bit of overkill in this particular situation but can pay off in the long run.

I would suggest using keys to accomplish what you want.

So, I would set up keys as follows:

\documentclass{article}
\usepackage{pgfkeys}
\makeatletter
\pgfkeys{/jeroen/entities/.cd,
  title/.initial=,
  entity/.initial=,
  }
\def\jeroen@set@keys#1{%%
  \pgfkeys{/jeroen/entities/.cd,#1}}
\def\jeroen@get#1{%%
  \pgfkeysvalueof{/jeroen/entities/#1}}

\newcommand\Add[1]{%%
  \bgroup
  \jeroen@set@keys{#1}%%
  \textit{\jeroen@get{entity}} `\jeroen@get{title}'%%
  \egroup}

\makeatother

\begin{document}

\Add{title=\LaTeX,entity=article}

\end{document}

In the shortrun, this is a lot of overhead to create for what seems like a simple command. But, in the long run this can pay off dividends.

In my experience, I find instances where I want to use essentially the same underlying macro, but rewriting the macro can be a pain in the neck. For example, I might want to use the macro without calling one of its arguments; I might want to add a third argument or even an optional argument. Using key values, it can be much easier to modify your code or improve upon implementation later.

Key values also get around the issue of remembering which argument is for which content.

By using \bgroup and \egroup, you can more easily define default behaviors when a key has not been called. For example,

\documentclass{article}
\usepackage{pgfkeys}
\makeatletter
\pgfkeys{/jeroen/entities/.cd,
  title/.initial=,
  entity/.initial=article,
  }
\def\jeroen@set@keys#1{%%
  \pgfkeys{/jeroen/entities/.cd,#1}}
\def\jeroen@get#1{%%
  \pgfkeysvalueof{/jeroen/entities/#1}}
\newcommand\Add[1]{%%
  \bgroup
  \jeroen@set@keys{#1}%%
  \textit{\jeroen@get{entity}} `\jeroen@get{title}'%%
  \egroup}
\makeatother

\begin{document}

\Add{title=\LaTeX,entity=article}

\Add{title=long nosed creature,entity=elephant}

\Add{title=mathematics}

\end{document}

enter image description here

9

An interesting example of how one can define commands with different syntax, but doing the same thing, with minumum effort.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

% Define the keys
\keys_define:nn { jeroen/add }
 {
  title  .tl_set:N  = \l_jeroen_add_title_tl,
  title  .initial:n = {},
  entity .tl_set:N  = \l_jeroen_add_entity_tl,
  entity .initial:n = article,
 }

% The key-value interface
\NewDocumentCommand{\Add} { m }
 {
  \group_begin:
  \keys_set:nn { jeroen/add } { #1 }
  \jeroen_add:VV \l_jeroen_add_entity_tl \l_jeroen_add_title_tl
  \group_end:
 }

% The two argument interface
\NewDocumentCommand{\add} { m m }
 {
  \jeroen_add:nn { #1 } { #2 }
 }

% The main command
\cs_new:Nn \jeroen_add:nn
 {
  \textit{#1}\nobreakspace`#2'
 }

% The variant needed for the key-value interface
\cs_generate_variant:Nn \jeroen_add:nn { VV }
\ExplSyntaxOff

\begin{document}

Key-value syntax:

\Add{title=\LaTeX,entity=article}

\Add{title=long nosed creature,entity=elephant}

\Add{title=mathematics}

\medskip

Two argument syntax:

\add{article}{\LaTeX}

\add{elephant}{long nosed creature}

\add{article}{mathematics}

\end{document}

enter image description here

The difference between \jeroen_add:nn and \jeroen_add:VV is that the former expects two standard braced arguments and the latter uses the value of two variables passed as arguments (unbraced). It isn't really necessary in this case, because

\jeroen_add:nn { \l_jeroen_add_entity_tl } { \l_jeroen_add_title_tl }

would work the same. In other cases, creating the variant could solve many subtle problems. It is also conceptually better.

8

Using \def should be avoided as there is no "compile type checking" whether or not the macro being defined clashes the existing macro with the same name. Use \newcommand instead.

\documentclass[preview,border=12pt]{standalone}

%\def\Marco#1#2{arg1: #1 and arg2: #2} <== it is not recommended as a best practice.
\newcommand\Marco[2]{arg1: #1 and arg2: #2}

\begin{document}
\Marco{Van}{Basten}
\end{document}
1
  • 2
    It is set to community wiki to prevent me from getting reputation points whenever you like this answer and vote it up. Nov 29, 2013 at 23:49
4

xparse can save life with its features some times. Here is an example:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\Add}{mm}{\textit{#1}{} `#2'}
\begin{document}
 \Add{article}{\LaTeX}
\end{document}

enter image description here

For details texdoc xparse or visit texdoc.net

2
  • 1
    details please :-)
    – azetina
    Nov 29, 2013 at 23:28
  • @azetina My typing is not trustworthy ;-)
    – user11232
    Nov 29, 2013 at 23:29
2

\def\Add#1#2{\textit{#1}\ '{#2}'}. Name \Add seems to be safer.

Or, if one dislikes \def, \newcommand{\Add}[2]{\textit{#1}\ '{#2}'}

4
  • 7
    Not \def, please!
    – egreg
    Nov 29, 2013 at 23:21
  • Those 'in the know' are aware, but \def is the right way only when working with Plain TeX -- a format entirely separate from LaTeX. (This question, as asked, could apply to either.) Dec 22, 2015 at 17:41
  • @egreg There are cases where \def can be exactly what you need. For instance with the subpreambles option active when including multiple standalone files containing different implementations for identically named commands, using \def ensures that each file uses its own version.
    – Janosh
    Aug 22, 2020 at 9:54
  • @Casimir If you like to live dangerously.
    – egreg
    Aug 23, 2020 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .