6

In a package, I'm building macro names from the values of options passed to a function. Now, the values should also allow a - inside, but the command names I'm building with \csname do not. So, I need to remove all - from the option value inside the \csname...\endcsname. How can I do this.

Simple example:

\documentclass{report}

\makeatletter
% Create tex name of the form "test@ARGUMENT". 
% PROBLEM: Need to remove - from #1...
\newcommand{\process}[1]{\typeout{Process called with `#1'} \csname test@#1\endcsname}
\newcommand{\test@mytag}{\typeout{test@mytag called} It worked}
\makeatother

\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag} % Doesn't work, needed for values like shade-tb-inverse
\process{mytag} % Works, but ugly with values like shadetbinverse
\end{document}

I want a command that takes an argument (in my case, an option value filtered by xkeyval's choicekey to one of certain valid values). Now, I want to call a command \test@VALUE. Unfortunately, the option values should allow dashes, like my-tag or shade-lr. As LaTeX does not allow dashes in commands, I need to filter all - inside the \csname. How can I do that?

0

3 Answers 3

7
\documentclass{report}

\makeatletter
\newcommand\textdash{-}
\begingroup
\catcode`\-=\active
\newcommand\dashtodash{}
\gdef\dashtodash{\def-{\textdash}}
\newcommand\ignoredash{}
\gdef\ignoredash{\def-{}}
\endgroup

\newcommand{\process}{\begingroup\catcode`\-=\active \@process}
\newcommand\@process[1]{\endgroup\dashtodash\typeout{Process called with `#1'}\ignoredash \csname test@#1\endcsname}
\newcommand{\test@mytag}{\typeout{test@mytag called} It worked}
\makeatother

\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag} % Doesn't work, needed for values like shade-tb-inverse
\process{mytag} % Works, but ugly with values like shadetbinverse
\end{document}
1
  • Thanks, that looked really promising. Unfortunately, it only works if not catcodes have been assigned yet to the argument of process. If you got the argument to \process already from latex (e.g. as command options), then making - active is too late. Example: \newcommand{\handle}[1]{\process{#1}} \handle{my-tag} % process will NOT see - as an active character! Aug 27, 2011 at 16:17
5

I don't understand why you would need to remove dashes from your string to pass it to a \csname construction, but here is a package-less solution. I'm assuming that there are no spaces and that eTeX is available, otherwise, you need more work.

\newcommand*{\csremovedashes}[1]
  {\csname\expandafter\csremovedashes@\detokenize{#1}-\endcsremovedashes-}
\newcommand*{\csremovedashes@}{}
\long\def\csremovedashes@#1-{#1\csremovedashes@}
\newcommand*{\endcsremovedashes}[1]{\endcsname}

In two steps, \csremovedashes{ab-c} expands to \abc.

2
  • The idea behind the approach is that a user can say \begin{posterbox}[background=shade-tb-inverse]...\end{posterbox}. The options are handled by xkeyval and basically call a handler macro \posterbox@background@OPTIONVALUE. xkeyval makes sure only allowed values are passed, and this approach saves lots of hardcoded \ifcase...... The problem is that \posterbox@background@shaded-tb-inverse is not a valid macroname, so instead I have to use \posterbox@background@shadedtbinverse internally, i.e. remove all - when assembling the call from the option value. Aug 31, 2011 at 12:19
  • @Reinhold: technically, you can have - in csname constructs, but I understand your point. By the way, I had a missing -, now added. Aug 31, 2011 at 18:49
4
\documentclass{report}
\usepackage{xstring}

\makeatletter
\newcommand\process[1]{%
  \StrDel{#1}{-}[\myString]%
  \typeout{Process called with `\myString'} \csname test@\myString\endcsname}
\newcommand\test@mytag{\typeout{test@mytag called} It worked}
\makeatother

\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag}
\process{mytag}

\end{document}
4
  • Thanks, that would really be the simplest option, if I could be sure that xstring is available. I'm trying to extend the baposter class, and thus keep the non-standard packages to an absolute minimum. Aug 27, 2011 at 16:21
  • it is available with every teX distribution
    – user2478
    Aug 27, 2011 at 16:23
  • Ubuntu, for example, provides the xstring.{tex,sty} package only in the texlive-latex-extra package, which is not a requirement, so we cannot rely on xstring being installed :( Aug 27, 2011 at 16:54
  • xstring is a standard package, period. The Linux community does not define what comprises the "standard" packages. Ask your sysadmin to install texlive. Or install it yourself. It isn't hard. Aug 28, 2011 at 3:15

You must log in to answer this question.

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