Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question

3 Answers 3

\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}
share|improve this answer
    
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! –  Reinhold Kainhofer Aug 27 '11 at 16:17

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.

share|improve this answer
    
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. –  Reinhold Kainhofer Aug 31 '11 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. –  Bruno Le Floch Aug 31 '11 at 18:49
\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}
share|improve this answer
    
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. –  Reinhold Kainhofer Aug 27 '11 at 16:21
    
it is available with every teX distribution –  Herbert Aug 27 '11 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 :( –  Reinhold Kainhofer Aug 27 '11 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. –  David Hammen Aug 28 '11 at 3:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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