Ho capito. Infatti, con $f”(x)$ la compilazione si blocca. Aspetto fiducioso uno dei tuoi proverbiali incantesimi.
Va modificata la definizione di \pr@m@s, perché occorre fare il confronto con ‘ attivo e non di categoria 12. Versione “definitiva”:
`\makeatletter
% Just to be sure we set the catcode of the quote to `other'
\catcode`\'=12
% We define a macro to stand for the quote of category `other'
\def\qu@te{'}
% Make the quote active
\catcode`'=\active
% In the output routine, LaTeX calls \@resetactivechars, in
% order to be safe for a \write; we need to take care of the
% always active quote and so we delete the redefinition of
% the active quote
\begingroup
\obeylines\obeyspaces%
\gdef\@resetactivechars{%
\def^^M{\@activechar@info{EOL}\space}%
\def {\@activechar@info{space}\space}%
}%
\endgroup
% Now we define the active quote with \protected, so that
% it remains itself in a \write
% 1) If we are in math mode we do the usual thing, i.e.,
% “^\bgroup\prim@s”
% 2) Otherwise we peek at the next token and execute \qu@t@
% The strings of \expandafter's are the usual trick to sweep
% away the \else and the \fi, so that the tests look at the
% correct token and not to \else or \fi
\protected\def'{\relax
\ifmmode
\expandafter^\expandafter\bgroup\expandafter\prim@s
\else
\expandafter\futurelet\expandafter\@let@token\expandafter\qu@t@
\fi}
% If we are not in math mode, we execute \qu@t@:
% 1) if the next token is ' (active quote), we need to typeset
% a double quote, i.e., \qu@te\qu@te, which will choose the
% normal ligature; the final \@gobble swallows the active quote
% 2) otherwise we typeset “{}\qu@te{}” in order to eliminate the
% bad kerning of the Minion fonts; then we insert an infinite
% penalty that prohibits a break; finally a zero skip that
% allows hyphenating the following word
\def\qu@t@{%
\ifx'\@let@token
\qu@te\qu@te\expandafter\@gobble
\else
{}\qu@te{}\penalty\@M\hskip\expandafter\z@skip
\fi}
% A last adjustment: in the definition of \pr@m@s that is used in
% math mode to typeset things such as “$f''(x)$” there is a test
% for a following token similar to the one used before. We need
% that the quote in the definition becomes active, so we use
% \scantokens to read again the same replacement text, but under
% a different catcode regime for the quote. The string of
% \expandafter's expands \pr@m@s before \scantokens comes into
% action, so that the argument to \scantokens is actually
% “\def\pr@m@s{
\scantokens\expandafter{%
\expandafter\def\expandafter\pr@m@s\expandafter{\pr@m@s}}
% That's all, folks! 🙂
\makeatother`
Occorreva anche rivedere la definizione di \@resetactivechars, per tener conto del nuovo significato di ‘; invece di un \DeclareRobustCommand uso in modo più efficiente le estensioni e-TeX. Così sui file ausiliari l’apostrofo compare come tale. Ovviamente tutto va a pallino se si usa il modulo spagnolo di babel, che rende attivo l’apostrofo. 🙁 Ma questa caratteristica può essere disabilitata. 🙂
Per chi è curioso, \scantokens legge la lista di token che trova come argomento secondo i codici di categoria attuali, come se facesse \input di un file. L’argomento, che si ottiene seguendo tutti gli \expandafter è
`\def\pr@m@s{
e adesso, quando TeX legge l’argomento di \scantokens, l’apostrofo è attivo. Così mi evito di copiare la definizione da latex.ltx. 😉
Ciao
Enrico
Nota: ho aggiunto alcuni commenti per rendere più comprensibili le macro. 😉