(updated the code to ensure that the Lua function doesn't perform string substitutions inside verbatim-like environments)
Here's a LuaLaTeX-based approach. It combines the \kn
macro from David Carlisle's earlier answer with a Lua function (assigned to the process_input_buffer
callback) that scans the input stream and automatically replaces all matches of <Upppercase Letter>$<punctuation mark>
with David C's code. The Lua function may be switched on and off via the LaTeX macros \adjustcommaOn
and \adjustcommaOff
.
The application used in the following code is inspired by this question, which was closed as a duplicate of the present question. Note that the Lua function suspends its operations if LaTeX is inside verbatim-like environments such as verbatim
, Verbatim
, and lstlisting
.

\documentclass{article}
% cf. https://tex.stackexchange.com/a/101059/5001:
\def\kn#1#2{{\sbox0{$#1#2$}\sbox2{$#1\mkern0mu#2$}\kern\dimexpr\wd0-\wd2\relax}#2}
\usepackage{luacode,geometry}
\begin{luacode}
in_verbatim = false
function ajust_punctuation ( s )
if string.find ( s , "\\begin{[vV]erbatim}" )
or string.find ( s , "\\begin{lstlisting}" ) then
in_verbatim = true
elseif string.find ( s , "\\end{[vV]erbatim}" )
or string.find ( s , "\\end{lstlisting}" ) then
in_verbatim = false
elseif in_verbatim == false then
-- scan for "<UppercaseLetter><$><PunctuationMark>" pattern:
s = string.gsub ( s , "(%u)%$(%p)", "%1$\\kn %1%2" )
end
return s
end
\end{luacode}
\newcommand{\adjustcommaOn}{%
\luadirect{luatexbase.add_to_callback(
"process_input_buffer", ajust_punctuation, "ajust_punctuation" )}}
\newcommand{\adjustcommaOff}{%
\luadirect{luatexbase.remove_from_callback(
"process_input_buffer", "ajust_punctuation" )}}
\setlength\parindent{0pt} % just for this example
\obeylines
\begin{document}
Proper spacing: $A$, $E$, $Q$, $R$.
\adjustcommaOn
Proper spacing: $A$, $E$, $Q$, $R$. --- Virtually no change.
\smallskip
\adjustcommaOff
Acceptable spacing: $B$, $C$, $D$, $G$, $O$, $S$, $Z$.
\adjustcommaOn
Acceptable spacing: $B$, $C$, $D$, $G$, $O$, $S$, $Z$. --- A little bit better.
\smallskip
\adjustcommaOff
Poor spacing: $F$, $H$, $I$, $J$, $K$, $M$, $N$, $P$, $T$, $U$, $V$, $W$, $X$, $Y$.
\adjustcommaOn
Poor spacing: $F$, $H$, $I$, $J$, $K$, $M$, $N$, $P$, $T$, $U$, $V$, $W$, $X$, $Y$. --- A major improvement.
% Note that "\adjustcommaOn" is in effect.
\begin{verbatim}
Proper spacing: $A$, $E$, $Q$, $R$.
Acceptable spacing: $B$, $C$, $D$, $G$, $O$, $S$, $Z$.
Poor spacing: $F$, $H$, $I$, $J$, $K$, $M$, $N$, $P$, $T$, $U$, $V$, $W$, $X$, $Y$.
\end{verbatim}
\end{document}
,
while fixing the distance, also$v\in V\!$,
could be used here, while other combination of a letter and some punctuation might require a different negative horizontal space.A bsence
could be mollified in the kerning table:-)