Ellipses & Correct Space Factor
For restricted cases, \@ifnextchar
is sufficient:
\documentclass{article}
\usepackage[utf8]{inputenc}
\newcommand*{\egap}{\kern\fontdimen3\font}
\newcommand*{\wordspace}{\@\space}
\makeatletter\newcommand*{\elip}{.\egap.\egap.\@ifnextchar.\egap\wordspace}\makeatother
\usepackage{newunicodechar}
\newunicodechar{…}{\elip}
\begin{document}
macro: \\
I\elip I \quad(good) \\
I\elip. I \quad(good)
Unicode glyph: \\
I… I \quad(good) \\
I…. I \quad(good)
But— \\
I\elip, I \quad(bad) \\
I\elip! I \quad(bad) \\
I\elip? I \quad(bad)
\end{document}
A fuller version requires a generalization of \@ifnextchar
. Adapting egreg’s answer to a related question leads toward such a generalization:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\elip}{ } { \elip_main: }
\NewDocumentCommand{\addtoelipexceptions}{m}
{
\tl_gput_right:Nn \g_elip_exceptions_tl { #1 }
}
\cs_new_protected:Npn \elip_gap
{
\kern\fontdimen3\font
}
\cs_new_protected:Npn \elip_main:
{
.\elip_gap.\elip_gap.
\bool_set_true:N \l_elip_apply_bool
\peek_catcode_ignore_spaces:NF \c_space_token { \elip_check: }
}
\cs_new_protected:Npn \elip_check:
{
\tl_map_inline:Nn \g_elip_exceptions_tl
{
\token_if_eq_charcode:NNT ##1 \l_peek_token
{\bool_set_false:N \l_elip_apply_bool \prg_map_break: }
}
\bool_if:NTF \l_elip_apply_bool
{ \@~ }
{ \elip_gap }
}
\tl_new:N \g_elip_exceptions_tl
\ExplSyntaxOff
\usepackage{newunicodechar}
\newunicodechar{…}{\elip}
\begin{document}
macro: \\
I\elip I \quad(good) \\
I\elip. I \quad(good)
Unicode glyph: \\
I… I \quad(good) \\
I…. I \quad(good)
But— \\
I…, I \quad(bad) \\
I…! I \quad(bad) \\
I…? I \quad(bad)
\addtoelipexceptions{,.!?}
Now: \\
I…, I \quad(good) \\
I…! I \quad(good) \\
I…? I \quad(good)
\end{document}
(Improvements to expl3 style, or an actual generalized \@ifnextchar
, would be welcome.)