14

I'm trying to adapt the solution provided in Different command definitions with and without optional argument to change the behavior of my new command. I'd like to use basic command to avoid some non basic packages.

I'm defining a command \mysign to produce my signature at the end of the document. But sometimes I need the date above and sometimes not. So I'd like to have an optional argument to insert it (for example\mysign[date]).

Also, sometimes I need to insert some personal ID and I'd like to have a second optional argument, but independent with the first one.

So, the result would be something like this:

  • \mysign only the signature
  • \mysign[date] the signature with date
  • \mysign[id] the signature with ID
  • \mysign[date, id] full signature

The problem is that \@ifnextchar[ is working only for one option. I can not adjust to work only with second option.

Any idea?

6
  • Would a key=value approach be valid for you? Jul 8, 2013 at 22:27
  • @GonzaloMedina, thanks, but I have no idea what you are asking. Probably yes since I simply would like to turn on/off the date and ID on my signature.
    – Sigur
    Jul 8, 2013 at 22:28
  • 1
    I mean \mysign produces signature; \mysign[date=<value>] produces signature+date; \mysign[id=<value>] gives signature+id; \mysign[date=<value>,id=<value>] gives signature+date+id. Jul 8, 2013 at 22:31
  • Great! It'll be very useful for me.
    – Sigur
    Jul 8, 2013 at 22:32
  • Doing with only one optional argument requires knowing the format of the ID, so that it's distinguishable from the date.
    – egreg
    Jul 8, 2013 at 22:59

5 Answers 5

8

A key=value approach

\documentclass{article}
\usepackage{graphicx}
\usepackage{xkeyval}

\makeatletter
\def\SigurId{}
\define@key{sigur}{date}{\def\SigurDate{#1}}
\define@boolkey{sigur}{id}{
  \ifKV@sigur@id
    \def\SigurId{\includegraphics[height=1.2ex,width=2cm]{example-image-a}}%
  \else
  \fi%
}

\makeatother
\newcommand\mysig[1][]{%
  \begingroup
    \setkeys{sigur}{date={},id=false}
    \setkeys{sigur}{#1}
    Sigur~\SigurDate\unskip~\SigurId\unskip
  \endgroup
}

\begin{document}

\mysig 

\mysig[date={\today}]

\mysig[id=true]

\mysig[date=\today,id=true]

\end{document}

enter image description here

5
  • Ow, thanks. Almost there. The ID is in fact an image, so I'm trying to adjust to make use of \includegraphics if the option id is passed. In your code I should pass the complete command to the value id?
    – Sigur
    Jul 8, 2013 at 23:04
  • @Sigur Will it always be the same image? Jul 8, 2013 at 23:13
  • Yes, my scanned signature.
    – Sigur
    Jul 8, 2013 at 23:14
  • I'd defined a command to the whole command to include the graphics and now I can pass the key id=\myid.
    – Sigur
    Jul 8, 2013 at 23:39
  • 1
    @Sigur please see my updated answer with a new boolean key for the image. Jul 8, 2013 at 23:55
6

From the comments to the answer of Gonzalo Medina I conclude that the optional argument ID is constant and rather a flag. Then LaTeX also knows an optional star as syntax element. The following example defines \mysign without the need of further packages the following way:

  • If a star follows, then the signature ID is set.
  • If an optional argument follows, then the date is set.
  • If the optional argument is empty, then \today is used as date.

The example file:

\documentclass{article}
\usepackage{graphicx}

\makeatletter
\newcommand*{\SetId}{%
  % tabular is only used for vertical centering
  % and ghostscript's example tiger.eps is the dummy
  % for the real scanned signature
  \begin{tabular}{@{}c@{}}%
    \includegraphics[height=2em,trim=0 50mm 0 0,clip]{tiger}%
  \end{tabular}%
}
\newcommand*{\mysign}{%
  \@ifstar{%
    \let\@DoId=\SetId
    \@mysign
  }{%
    \let\@DoId=\relax
    \@mysign
  }%
}
\newcommand*{\@mysign}[1][\relax]{%
  Signature%
  \def\@mysign@relax{\relax}%
  \def\@mysign@date{#1}%
  \ifx\@mysign@date\@mysign@relax
  \else
    , %
    \ifx\@mysign@date\@empty
      \today
    \else
      #1%
    \fi
  \fi
  \ifx\@DoId\relax
  \else
    , %   
    \@DoId
  \fi
}
\makeatother

\begin{document}
\renewcommand*{\arraystretch}{2}
\begin{tabular}{ll}
\verb|\mysign| & \mysign \\
\verb|\mysign*| & \mysign* \\
\verb|\mysign[]| & \mysign[] \\
\verb|\mysign[2001-02-03]| & \mysign[2001-02-03] \\
\verb|\mysign*[]| & \mysign*[] \\
\verb|\mysign*[2001-02-03]| & \mysign*[2001-02-03] \\
\end{tabular}
\end{document}

Result

1
  • Ow, many thanks. I'm learning a lot with these kind of solutions.
    – Sigur
    Jul 9, 2013 at 0:31
4

Another solution based again on a key-based interface: it exploits pgfkeys.

The code:

\documentclass[a4paper,11pt]{article}
\usepackage{tikz}
\usepackage{mwe}

% key definition
\newif\ifbaseline
\pgfkeys{/signature/.cd, baseline/.is if=baseline}
\pgfkeys{/signature/.cd,
  date/.initial={},
  date/.get=\signdate,
  date/.store in=\signdate,
  id/.initial={},
  id/.get=\id,
  id/.store in=\id,
}

% Basic command
\newcommand{\signature}[2][]{
\pgfkeys{signature/.cd,
  date={},
  id={},
  baseline=false,
  #1}
#2\space\signdate\space%
\ifbaseline
 \tikz[baseline=-0.5ex]\node[inner sep=0pt]{\id};
\else
 \id
\fi%
}

\begin{document}
\signature{Sigur}

\signature[date=\today]{Sigur}

\signature[id={\includegraphics[width=2em,height=2em]{example-image}}]{Sigur}

\signature[baseline,id={\includegraphics[width=2em,height=2em]{example-image}}]{Sigur}

\signature[baseline,
  id={\includegraphics[width=2em,height=2em]{example-image}},
  date={June 28, 2013}]{Sigur}

\signature[id={\includegraphics[width=2em,height=2em]{example-image}},
  date={June 28, 2013}]{Sigur}
\end{document}

TikZ is not really needed, actually it can be loaded pgfkeys in its place, but then I enjoyed the possibility to put the picture aligned on the baseline.

The result:

enter image description here

3
  • the twoopt package provides \newcommand, \renewcommand and \providecommand variants, that all accept two optional arguments. Jul 9, 2013 at 10:22
  • 1
    @wasteofspace: what if they are three or six? With key-based approaches it's just matter of defining new keys. Please, also consider that there's the xparse package able to define commands with more optional arguments, but I really believe that a key-based approach is the best. Jul 9, 2013 at 10:28
  • 1
    This is really the only right approach.
    – Ryan Reich
    Aug 20, 2013 at 15:49
2

The poor man's solution:

\newcommand\mysig[3][Sigur]{#2 #1 #3}

Example:

\documentclass{article}

\newcommand\mysig[3][Sigur]{#2 #1 #3}

\begin{document}

\mysig{date}{id}

\mysig{date}

\mysig{}{id}

\mysig

\end{document}

MWE

1
  • Poor, but with rich soul. Thanks.
    – Sigur
    Jul 9, 2013 at 0:26
0

what about doing something like:

\usepackage{ifthen}
\newcommand{\mysign}[2]{%
    \ifthenelse{\equal{#1}{}}{}{#1\\}%
    SIGNATURE CODE%
    \ifthenelse{\equal{#2}{}}{}{\\#2}}

and then just invoke with the fields you don't want to use blank

i.e. \mysign{date}{} fot just date, etc...

2
  • 1
    Do you know if the package ifthen comes with basic install?
    – Sigur
    Jul 8, 2013 at 23:05
  • 1
    according to apt-file it comes packaged in texlive-latex-baseso it should come by default
    – John C
    Jul 8, 2013 at 23:11

You must log in to answer this question.

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