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.

This is kind of a double question but closely connected in my case. Inspired by http://tex.stackexchange.com/a/55769/14159 I tried to make an improved version which allows additional parameters for the defined symbols.

This is my current code:

\documentclass{article}
\usepackage{xparse}
\usepackage{nomencl}
\usepackage{xcolor}

% colorize to distinguish original and renewed command
\NewDocumentCommand{\defsym}{mmmmm} {%
    \NewDocumentCommand{#1}{#2}{%
        \RenewDocumentCommand{#1}{#2}{\textcolor{blue}{#4}}
        \nomenclature{$#1$}{#5}
        \textcolor{red}{#3}
    }
}

\defsym\Uk{O{k}}{U_{#1}}{U_{##1}}{Some variable}

\makenomenclature

\begin{document}
\noindent$\Uk[j]$,$\Uk,$ $\Uk[p], \Uk[q]$ and $\Uk[r]$
\printnomenclature
\end{document}

Result of the code above


Now to the two problems I have are

  1. The double definition #3 and #4 is very ugly, is there some macro which increases the nesting level, i.e. which adds one # to each parameter? So that I could write \incnest{#3} instead of #4
  2. The \RenewDocumentCommand definition is not global so all U's except the \Uk[q] are red. Is there some equivalent to \global or \gdef in xparse. I found something similar for \renewcommand in \global\renewcommand equivalent of \global\def but it's a bit hacky.

Any tricks or workarounds to get it working are welcome.

share|improve this question

1 Answer 1

up vote 5 down vote accepted

This problem of global redefinition can't be solved with \RenewDocumentCommand; with deeper expl3 programming, it can be done by setting a switch (a boolean).

\documentclass{article}
\usepackage{xparse}
\usepackage{nomencl}
\usepackage{xcolor}

% colorize to distinguish original and renewed command
\ExplSyntaxOn
% #1 = command name
% #2 = definition
% #3 = default optional argument
% #4 = description
\NewDocumentCommand{\defsym}{mmmm}
  {
   \bool_new:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \bool_gset_false:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \buergi_defsym:nnnn { #1 } { #2 } { #3 } { #4 }
  }
\cs_new_protected:Npn \buergi_defsym:nnnn #1 #2 #3 #4
 {
  \NewDocumentCommand{#1}{O{#3}}
   {
    \bool_if:cTF  { g_buergi_sym_ \cs_to_str:N #1 _bool }
     { \textcolor{blue}{#2} }
     {
      \textcolor{red}{#2}
      \nomenclature{$#1$}{#4}
      \bool_gset_true:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
     }
   }
 }
\ExplSyntaxOff

\defsym\Uk{U_{#1}}{k}{Some variable}
\defsym\Ak{A(#1)}{k}{Another}

\makenomenclature

\begin{document}
\noindent $\Uk[j]$, $\Uk$, $\Uk[p]$, $\Uk[q]$ and $\Uk[r]$

\noindent $\Ak$, $\Ak[n]$
\printnomenclature
\end{document}

As you see, you can give in the second argument any token list with #1 representing the optional argument, that I've placed third. Just personal preference, if you want to switch the second and third arguments, just change the first definition into

\NewDocumentCommand{\defsym}{mmmm}
  {
   \bool_new:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \bool_gset_false:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \buergi_defsym:nnnn { #1 } { #3 } { #2 } { #4 }
  }

The command \defsym first defines a boolean switch with a name based on the first argument and sets it to false; then executes the core function which does the required \NewDocumentCommand; so \Uk is defined to do its normal job in blue color if the boolean is true, while it does its job in red color. annotates in the nomenclature file the usage and globally sets the boolean to true.

enter image description here

share|improve this answer
    
I've also thought of some flag approach but I thought some simple redefinition would be easier, but this seems not to be the case. Thanks a lot, I'll test your code and accept it as answer as soon as I understand the fancy expl3 syntax, never used it so far. I can't even find a good reference for all these commands, is there some good place to look things up? –  buergi Oct 12 '12 at 13:22
1  
@buergi Fire up texdoc expl3 and texdoc interface3. Redefining might be done, but it exposes you to the problem of doubling the # tokens. –  egreg Oct 12 '12 at 13:25
    
@egrep thank you so much for your effort. With your solution I don't need the doubling any more, it's working as expected without the ugly duplicate argument. I changed O{#3} to #3 as it allows to define symbols with multiple optional arguments (the reason why I used xparse). It seems to be the perfect solution even if it looks a bit ugly :) thanks a lot. –  buergi Oct 12 '12 at 13:37
    
sorry for misspelling your name, guess I used the unix command-line too much :) ans special thanks for the note about interface3.pdf. It's really hard to find the reference if one does not know its name especially since interface3 is not a very obvious name for it. –  buergi Oct 12 '12 at 13:57

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.