This is an old question and this is not so much an answer, but an overly long comment.
The \@ before the commas (as is shown in egreg's excellent answer) is not redundant. TeX's treatment of \spacefactor is straight-forward, but obscure.
The TeXbook and TeX by Topic have all the details—and most of this is taken from TeX by Topic—but essentially the following happens. When TeX inserts a space between words, the amount of space inserted depends on several factors. The key factors are the current font parameters 2, 3, 4, and 7, along with \spaceskip, \xspaceskip, and \spacefactor. \spaceskip and \xspaceskip are used to override the font parameters. As they're rarely used, let's ignore them here.
Normally, when a space is inserted, it has a natural width (font parameter 2), a stretch component (font parameter 3) and a shrink component (font parameter 4). The \spacefactor modifies this: The stretch component is multiplied by \spacefactor/1000 whereas the shrink component is divided by \spacefactor/1000.
When \spacefactor is at least 2000, then TeX increases the natural width of the space by font parameter 7. This is done to have wider spaces between sentences.
Each character added to the a line has an associated space factor code, \sfcode. The \spacefactor is set after each character as follows. Let n be the \sfcode for the character.
- If the n = 0,
\spacefactor is unchanged. (This enables punctuation like parentheses and brackets to not affect the \spacefactor.)
- If n > 1000 and
\spacefactor < 1000, then the \spacefactor is set to 1000. (This slightly confusing behavior enables D. Knuth to use a normal space.)
- Otherwise,
\spacefactor is set to n.
Finally, the \spacefactor is set to 1000 at the beginning of paragraphs (including after \indent or \noindent), as well as after \vrule, an accent, or a box in horizontal mode.
So, with that in mind, let's consider some consequences of this using Computer Modern 10pt roman fonts.
- Spaces have an unmodified (by
\spacefactor) glue of "3.33333pt plus 1.66666pt minus 1.11111pt" which is to say their natural width is 3.33333pt but can stretch by an additional 1.66666pt (without penalty) and shrink by 1.11111pt.
- Spaces following lower case letters (which have
\sfcode 1000) have exactly the glue listed above.
- Spaces following upper case letters (which have
\sfcode 999) have glue 3.33333pt plus 1.66498pt minus 1.11221pt. This is imperceptibly different from spaces following lower case letters.
- Spaces following commas (which have
\sfcode 1250) which themselves follow a lower case letter (e.g., the space in foo, bar) have glue 3.33333pt plus 2.08331pt minus 0.88889pt.
- Spaces following periods (which have
\sfcode 3000) which themselves follow a lower case letter (e.g., the space in foo. bar) have glue 4.44444pt plus 4.99997pt minus 0.37036pt. Note that the natural width has been augmented by font parameter 7 because \sfcode >= 2000.
- Spaces following periods (or commas) which themselves follow an upper case letter have the same glue as in 1.
Let's now consider the three short paragraphs in the following LaTeX document.
\documentclass{article}
\tracingoutput=1
\showboxbreadth=1000
\showboxdepth=1000
\begin{document}
Languages like JS, HTML, etc. were not used by King Henry III. Next.
Languages like JS, HTML, etc.\ were not used by King Henry III\@. Next.
Languages like JS\@, HTML\@, etc.\ were not used by King Henry III\@. Next.
\end{document}
Note that I've instructed TeX to write out what each page of output looks like to the log file. This output is pretty verbose, but you can see each box, glue, and character. For example, the first paragraph consists of this.
...\hbox(6.94444+1.94444)x345.0, glue set 16.08281fil
....\hbox(0.0+0.0)x15.0
....\OT1/cmr/m/n/10 L
....\OT1/cmr/m/n/10 a
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 g
....\OT1/cmr/m/n/10 u
....\OT1/cmr/m/n/10 a
....\OT1/cmr/m/n/10 g
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 s
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 i
....\OT1/cmr/m/n/10 k
....\kern-0.27779
....\OT1/cmr/m/n/10 e
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 J
....\OT1/cmr/m/n/10 S
....\OT1/cmr/m/n/10 ,
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 H
....\OT1/cmr/m/n/10 T
....\OT1/cmr/m/n/10 M
....\OT1/cmr/m/n/10 L
....\OT1/cmr/m/n/10 ,
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 t
....\OT1/cmr/m/n/10 c
....\OT1/cmr/m/n/10 .
....\glue 4.44444 plus 4.99997 minus 0.37036
....\OT1/cmr/m/n/10 w
....\kern-0.27779
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 e
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 o
....\OT1/cmr/m/n/10 t
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 u
....\OT1/cmr/m/n/10 s
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 d
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 b
....\kern-0.27779
....\OT1/cmr/m/n/10 y
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 K
....\OT1/cmr/m/n/10 i
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 g
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 H
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 y
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 I
....\kern0.27779
....\OT1/cmr/m/n/10 I
....\kern0.27779
....\OT1/cmr/m/n/10 I
....\OT1/cmr/m/n/10 .
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 N
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 x
....\OT1/cmr/m/n/10 t
....\OT1/cmr/m/n/10 .
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
There's a lot of interesting stuff here which I'm going to skip over to focus on the key points.
- The glue set after
JS, and HTML, are normal spaces: \glue 3.33333 plus 1.66666 minus 1.11111
- The glue set after
etc. is an inter-sentence space: \glue 4.44444 plus 4.99997 minus 0.37036
- The glue set after
III. is a normal space.
This is precisely what we'd expect by following the rules given above.
The minimum one should do to fix these problems is the second paragraph:
- The glue set after
JS, and HTML, are still normal spaces.
- The glue set after
etc.\ is a normal space.
- The glue set after
III\@. is an inter-sentence space.
The correct thing to do is what egreg said and given in the third paragraph:
- The glue set after
JS\@, and HTML\@, are \glue 3.33333 plus 2.08331 minus 0.88889.
- The glue set after
etc.\ is a normal space.
- The glue set after
III\@. is an inter-sentence space.
What does this matter? Imagine you had written Ruby, JS, and HTML\@. instead. We might expect (and would certainly want) the space following Ruby, and the space following JS, to be the same. Unfortunately, following the rules detailed above, this doesn't happen.
...\hbox(6.94444+1.94444)x345.0, glue set 232.08315fil
....\hbox(0.0+0.0)x15.0
....\OT1/cmr/m/n/10 R
....\OT1/cmr/m/n/10 u
....\OT1/cmr/m/n/10 b
....\kern-0.27779
....\OT1/cmr/m/n/10 y
....\kern-0.83334
....\OT1/cmr/m/n/10 ,
....\glue 3.33333 plus 2.08331 minus 0.88889
....\OT1/cmr/m/n/10 H
....\OT1/cmr/m/n/10 T
....\OT1/cmr/m/n/10 M
....\OT1/cmr/m/n/10 L
....\OT1/cmr/m/n/10 ,
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 a
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 d
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 J
....\OT1/cmr/m/n/10 S
....\OT1/cmr/m/n/10 .
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
In this format, it's readily apparent that the two spaces after the commas have different stretch and shrink components. Writing, Ruby, JS\@, and HTML\@. has the correct behavior.
egreg writes, "The simplest thing is to go \frenchspacing and forget about this." It's certainly true that that is the simplest thing to do, but unless it's common to typeset all spaces with the same base width in your language/journal/whatever, I recommend not doing that.
\@was not original defined for the use after a dot, as done in my answer. However, it works nicely and seems to be actually the right thing to do (see egreg's analysis). – Martin Scharrer Jul 07 '11 at 18:30\for something that doesn't end a sentence, and\@for something that does. – barbara beeton Jul 07 '11 at 18:53\@and the underlying\spacefactoralso confused me as an advanced user. I personally stopped a while ago to use\ieand writei.e.\instead. It also avoids all the hassle with\xspaceand the definition of a new macro. – Martin Scharrer Jul 07 '11 at 18:59\@before the commas? I ask primarily because in my document, I am typesetting language names in a separate font, so I have macros like\def\JS{\textsf{JS}}, and I'd like to harden that macro against subsequent punctuation, such that I could write "\JS, \HTML, and \CSS; also \XML." and have it Just Work for all punctuation. I can figure out how to code\or\@depending on the following characters, but I just need to know which to use :) – Ben Lerner Jul 07 '11 at 19:13\@in at the end of a macro definition. this is standard practice in tugboat, where this definition is used:\newcommand\acro[1]{\textSMC{#1}\@}(seeltugboat.clsfor the definition of\textSMC, which requires its arguments to be uppercase; we don't like the too-small small caps for acronyms). – barbara beeton Jul 08 '11 at 14:47\(slash-space) is defined to be an ordinary space. it has\catcode= 10 and is conceptually equivalent to\spaceso it overrides any resetting of the spacefactor, – barbara beeton Jul 08 '11 at 20:06etc.there should be\. – egreg Jul 08 '11 at 22:29\afteretc.; added. (hangs head in embarrassment.) – barbara beeton Jul 31 '11 at 14:40latex manualthat you are speaking of? – Pouya Jun 09 '14 at 14:17JS, HTML,as egreg does? Your version is the one I learnt (probably from Kopka and Daly). I always tend to writeetc\@.if I'm ending a sentence, but only because I can never remember whether I need the\@in that case or not. (I seem to have 'etc.needs special handling' inscribed in my brain, so I always want to put something unless I'm ending a paragraph.) – cfr Dec 16 '19 at 15:26\@before a period (after an uppercase letter) if it is the end of a sentence, and "\" (slash-space) after the period if it is an abbreviation and not the end of a sentence. That's what the TeXbook specifies, and that's what I learned, and I'm sticking to it. (I also find it easier to explain than the egreg solution.) Go with Kopka and Daly -- they made very few mistakes! – barbara beeton Dec 16 '19 at 16:32\@following an uppercase letter and preceding punctuation indicates that the space following the punctuation should be handled in an exceptional manner (unless\frenchspacingis in effect). Thus the space will be set wider than an ordinary interword space. TeX's usual action is to assume that an uppercase letter before punctuation (most commonly a period) is an initial, where (since an initial is an integral part of a name) only an ordinary interword space should be used. – barbara beeton Nov 29 '20 at 16:09