Problem with my understanding of expandafter and newcommand with arguments and sout

You should be aware of the fact that \Kat requires more than one expansion step in order to deliver the stored text: after the first expansion step you get

\expandafter\csname INT\rom{1}intKATAkatNUM\rom{1}num\endcsname

This \expandafter does nothing at all, because it tries to expand I.

You can force “almost full” expansion, which is what you need here, with the `\romannumeral trick:

\documentclass{article}
\usepackage{ulem,lipsum}
\usepackage[T1]{fontenc}

\newcommand*{\rom}[1]{\romannumeral #1}

\newcommand\INTiintKATAkatNUMinum{%
  Test Text for demonstration. In the original this command is constructed. %
}

\newcommand{\Kat}[4]{% Command to piece together the constructed commands.
  \csname INT\rom{#1}intKAT#2katNUM\rom{#3}num#4\endcsname
}

\newcommand\soutt[1]{% sout with expansion
  \expandafter\sout\expandafter{\romannumeral-`Q#1}%
}

\begin{document}

\parbox{2cm}{
 \sout{The sout makro of ulem is able to handle hyphenation and linebreaks in text entered directly but not as macro see next line!}
 \soutt{\INTiintKATAkatNUMinum} %works
 \soutt{\Kat{1}{A}{1}{}} %doesn't
}

\end{document}

enter image description here

And no, \sout doesn't do hyphenation.

The \romannumeral trick has been explained several times, but here's a brief illustration.

The primitive \romannumeral wants a <number> after it and here we exploit a peculiar feature of TeX: after an explicit <number>, TeX looks for an <optional space> after it, expanding tokens during this lookup; it stops expansion upon finding either an explicit space token or an unexpandable token.

An “explicit <number>” can be expressed in several ways:

  • a sequence of digits;
  • a hexadecimal number, that is, a sequence of digits or characters among ABCDEF, if the first token is ";
  • an octal number, that is, a sequence of digits among 01234567 if the first token is ';
  • an alphabetical constant, if the first token is ` (a backquote).

In all cases, a minus sign should precede the radix notation "'`, if we want to specify a negative number.

In the first three cases, TeX performs expansion until finding something that doesn't qualify as an admissible digit.

The case that interests us is the last one. An alphabetic constant is a character token or a control sequence whose name consists of a single character (and need not be defined). So

`Q  `\Q

are equivalent ways to ask for number 81 (the ASCII code of Q). The escaped notation is essential for characters with “strange” category code, such as

`\% `\^^@

(the latter is 0).

The fact that TeX expands tokens after the alphabetical constants is decisive for this application: the <number> is already fully known, and in our case it is -81, but TeX expands tokens nonetheless. After ending the search for the optional space, TeX will proceed to finalize the expansion of \romannumeral-`Q, which is empty because the number is negative.

We cannot use \romannumeral-81 directly, because if the following token after expansion happens to be a digit, it would be taken as part of the <number>.

A limitation of this method is that an initial space in the final expansion will be gobbled.

In the next release of TeX Live, all engines will have \expanded (currently only available with LuaTeX); MiKTeX based engines should already have it. With \expanded, the thing will be simpler:

\newcommand\soutt[1]{% sout with expansion
  \expandafter\sout\expandafter{\expanded{#1}}
}

because \expanded delivers the full expansion of its argument in a single step.


You can use soul, if you want hyphenation. The corresponding macro is \st (or \textst). Just for a change, I'll implement it in expl3, where the \romannumeral is available as “f-expansion”.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{soul}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\Kat}{mmmm}
 {
  \use:c
   {
    INT \int_to_roman:n {#1} intKAT #2 katNUM \int_to_roman:n {#3} num #4
   }
 }
\NewExpandableDocumentCommand{\soutt}{m}
 {
  \oberreiter_sout:f { #1 }
 }
\cs_new_protected:Nn \oberreiter_sout:n { \textst{#1} }
\cs_generate_variant:Nn \oberreiter_sout:n { f }

\ExplSyntaxOff

\newcommand\INTiintKATAkatNUMinum{%
  Test Text for demonstration. In the original this command is constructed. %
}

\begin{document}

\parbox{2cm}{
 \st{The st macro of soul is able to handle hyphenation and linebreaks
   in text entered directly but not as macro see next line!}
 \soutt{\INTiintKATAkatNUMinum} %works
 \soutt{\Kat{1}{A}{1}{}} %doesn't
}

\end{document}

enter image description here