1

Another tex user has helped me get to the following solution to switch between my colour styles:

\newcommand{\jackclass@definetheme}[2]{\@namedef{jack@theme@#1}{#2}}
\newcommand{\usetheme}[1]{\@nameuse{jack@theme@#1}}

\jackclass@definetheme{colour-theme-formal}{%
  \definecolor{soft}{gray}{0.75}%
  \definecolor{glow}{RGB}{001,176,236}%
  \definecolor{canvas}{RGB}{200,100,100}%
  \definecolor{prime}{RGB}{255,100,100}%
}
\jackclass@definetheme{colour-theme-vibrant}{%
  \definecolor{soft}{gray}{0.75}%
  \definecolor{glow}{RGB}{001,176,236}%
  \definecolor{canvas}{RGB}{255,100,100}%
  \definecolor{prime}{RGB}{255,100,100}%
}

This now allows me to use \usetheme{colour-theme-vibrant} or \usetheme{colour-theme-formal} to switch between colour themes in my document. For example, one page could have a blue theme and another could have a red theme.

This works great for colours.

Now for the question: How can I achieve the same, but for something a bit more than just setting colours? Lets say something like:

\newcommand{\jackclass@definestyle}[2]{\@namedef{#1}{#2}}
\newcommand{\usestyle}[1]{\@nameuse{jack@style@#1}}

\jackclass@definestyle{style-theme-formal}{
  \newcommand{\highlight}[1]
  {\setulcolor{red}\ul{#1}}   
}

\jackclass@definestyle{style-theme-vibrant}{
  \newcommand{\highlight}[1]
  {\bfseries{\color{blue} #1}}
}

So that I could swap between underlining text and bold print by changing the style with \usestyle{style-theme-vibrant}. This is probably completely the wrong way of going about it (and doesn't work). I'm trying to create my own simple class that allows swapping colour themes (as the first part) and swapping styles (as in the last part).

If I try the code above, I get Illegal parameter number in definition of \colour-theme-formal.

Any help or advice will be appreciated.

  • Is this a trick question? It seems to me that is is enough to add \newcommand\highlight[1]{\textbf{#1}} and \newcommand\highlight[1]{\underline{#1}} to the corresponding \jackclass@definestyle{...} commands? – Andrew Jul 22 '18 at 12:13
  • Thanks @Andrew but if I do that I get and error: Illegal parameter number in definition of \colour-theme-for mal. – Jack Jul 22 '18 at 20:46
  • Ah, right, you'll need to use ##1. – Andrew Jul 23 '18 at 4:48
3

First, if you want to switch midway you may need to use \renewcommand instead of \newcommand to avoid errors due to redefinition of \highlight.

Second, the error you are getting is due to how nested arguments work. To fix it use ##1:

\newcommand{\jackclass@definestyle}[2]{\@namedef{jack@style@#1}{#2}}
\newcommand{\usestyle}[1]{\@nameuse{jack@style@#1}}

\newcommand{\highlight}[1]% DEFAULT
  {\setulcolor{red}\ul{#1}}

\jackclass@definestyle{style-theme-formal}{
  \renewcommand{\highlight}[1]
  {\setulcolor{red}\ul{##1}}
}

\jackclass@definestyle{style-theme-vibrant}{
  \renewcommand{\highlight}[1]
  {\bfseries{\color{blue} ##1}}
}

The reason #1 does not work is that when you define a command in the definition of another you need to disambiguate which arguments you are referring to, for example:

\newcommand{\outercmd}[1]{
   \newcommand{\innercmd}[1]{
      \textcolor{#1}{##1}
   }
}

Calling \outercmd{blue} will define \innercmd{arg} to rewrite to \textcolor{blue}{arg}. The number of # you prepend to a positional argument indicates to which argument list the argument reference belongs in the stack of nested definitions.

In your case the nested definition is indirect in the way you pass the second argument of \jackclass@definestyle to \namedef which is a command definition in disguise.

Finally, you forgot to add the prefix jack@style@ to the \namedef call in \jackclass@definestyle causing the \nameuse in \usestyle to have no effect.

  • Wow, that is a really nice answer, thanks a stack :-) – Jack Jul 22 '18 at 21:56

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.