4

Considering this newcommand (it works fine)

\newcommand\createCMDSH[4]{%
  \expandafter\@ifdefinable\csname #3#2\endcsname{%
    \expandafter\xdef\csname #3#2\endcsname{%
      \noexpand\vcenteredhbox{\noexpand\includegraphics[height=\noexpand\taille,trim=0 0 1 -1]{BD_CATIA/#4/#1.png}}%
    }%
  }%
}

I can obtain a command with a name specified by #3#2 for displaying a picture.

The idea is to change the xdef command for building a new #3#2 command with one argument. How can I do this? Is xdef the right command?

Explanation (#3#2=cmdperso):

  • old version \cmdperso{}
  • new version \cmdperso{0.5} (50% of the \textwidth)

I have tried this but it is not working:

\newcommand\createCMDM[4]{%
  \expandafter\@ifdefinable\csname #3#2\endcsname{%
    \expandafter\xdef\csname #3#2\endcsname[1][]{%
      \noexpand\includegraphics[width=\noexpand##1\textwidth]{BD_CATIA/#4/#1.png}%
    }%
  }%
}

SOLUTION

\newcommand\createCMDM[4]{%
  \expandafter\@ifdefinable\csname #3#2\endcsname{%
    \expandafter\xdef\csname #3#2\endcsname##1{%
      \noexpand\includegraphics[width=##1\noexpand\hsize]{BD_CATIA/#4/#1.png}%
    }%
  }%
}
  • Since you're expanding nothing in the replacement text for \xdef, what are you using it for? – egreg Jan 30 '15 at 12:10
  • In fact I call \createCMDM using: \createCMDM{...}{\txtA}{\txtB}{...} and \txtA and \txtB contain perso and cmd. But maybe I misunderstand the expand process. – Guuk Jan 30 '15 at 12:15
2

You combine the \newcommand syntax of parameter declarations with \xdef primitive. But primitive commands have normal and elegant syntax without square brackets.

\def\createCMDM#1#2#3#4{% I don't understand why #3 is merged with #2
  \expandafter\@ifdefinable\csname #3#2\endcsname{%
    \expandafter\gdef\csname #3#2\endcsname##1{%
      \includegraphics[width=##1\hsize]{BD_CATIA/#4/#1.png}%
    }%
  }%
}

If you are using \cmdperso{} for full \hsize and \cmdperso{0.5} for half \hsize, then you don't need to implement the optional parameter.

Edit: I replace \xdef to \gdef and remove one \noexpand. The \xdef is not needed here.

  • Actually, the OP needs \xdef, as explained in the last comment to the question. – egreg Feb 1 '15 at 10:35
4

You could create an emulation of what \newcommand with two optional argument does, but I think it's better using xparse and expl3 for this:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\createCMDSH}{mmmm}
 {
  \guuk_create_cmdsh:cxx { #3#2 } { #1 } { #4 }
 }

\cs_new_protected:Nn \guuk_create_cmdsh:Nnn
 {
  \NewDocumentCommand{#1}{}
   {
    \vcenteredhbox{
     \includegraphics[height=\taille,trim=0~0~1~-1]{BD_CATIA/#3/#2.png}
    }
   }
 }
\cs_generate_variant:Nn \guuk_create_cmdsh:Nnn { cxx }

\NewDocumentCommand{\createCMDM}{mmmm}
 {
  \guuk_create_cmdm:cxx { #3#2 } { #1 } { #4 }
 }

\cs_new_protected:Nn \guuk_create_cmdm:Nnn
 {
  \NewDocumentCommand{#1}{O{}}
   {
    \vcenteredhbox{
     \includegraphics[width=##1\textwidth]{BD_CATIA/#3/#2.png}
    }
   }
 }
\cs_generate_variant:Nn \guuk_create_cmdm:Nnn { cxx }
\ExplSyntaxOff

\newcommand{\txtA}{TEXTA}
\newcommand{\txtB}{TEXTB}
\createCMDSH{\txtA}{\txtB}{X}{Y} % this will create \XTEXTB

\createCMDM{\txtA}{\txtB}{ZZZ}{WWW} % this will create `\ZZZTEXTB`

The command \ZZZTEXTB will have an optional argument, so \ZZZTEXTB would print the image \textwidth wide, while \ZZZTEXTB[0.5] will print it half of the textwidth.

  • Thanks but Can I use the same syntax as I used in my first command? Just by adding some argument? – Guuk Jan 30 '15 at 12:38
  • @Guuk If you want a regular (braced) argument, just add ##1 after \endcsname, instead of [1][]. With the xparse/expl3 approach it's easier to manage expansions. – egreg Jan 30 '15 at 13:47

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.