latex3 / latex2e

The LaTeX2e kernel
https://www.latex-project.org/
LaTeX Project Public License v1.3c
1.96k stars 267 forks source link

Questionable behavior in spacing for amsmath \colon #91

Open eg9 opened 6 years ago

eg9 commented 6 years ago

Brief outline of the bug

The current definition of \colon adds unwanted space when followed by an Op atom.

Reference: https://tex.stackexchange.com/q/461537/4427

Minimal example showing the bug

\RequirePackage{latexbug}
\documentclass{article}
\usepackage{amsmath}
\usepackage{etoolbox}

\let\pcolon\colon
\patchcmd{\pcolon}{{:}}{\mathopen:}{}{}

\begin{document}

$f \colon \operatorname{End}(V) \to R$

$f \pcolon \operatorname{End}(V) \to R$

\bigskip

\begin{tabular}{@{}*{8}{l}@{}}
&0&1&2&3&4&5&6 \\
\verb|\colon| &
  $\colon A$ &
  $\colon \max$ &
  $\colon +$ &
  $\colon \sim$ &
  $\colon ($ &
  $\colon )$ &
  $\colon ,$
\\
\verb|\pcolon| &
  $\pcolon A$ &
  $\pcolon \max$ &
  $\pcolon +$ &
  $\pcolon \sim$ &
  $\pcolon ($ &
  $\pcolon )$ &
  $\pcolon ,$
\end{tabular}

\end{document}

Log file (required) and possibly PDF file

This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex 2018.11.16)  24 NOV 2018 14:37
entering extended mode
 restricted \write18 enabled.
 %&-line parsing enabled.
**howard.tex
(./howard.tex
LaTeX2e <2018-04-01> patch level 5
(/usr/local/texlive/2018/texmf-dist/tex/latex/latexbug/latexbug.sty
Package: latexbug 2017/10/12 v1.0d Bug-classification
)
(/usr/local/texlive/2018/texmf-dist/tex/latex/base/article.cls
Document Class: article 2014/09/29 v1.4h Standard LaTeX document class
(/usr/local/texlive/2018/texmf-dist/tex/latex/base/size10.clo
File: size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option)
)
\c@part=\count80
\c@section=\count81
\c@subsection=\count82
\c@subsubsection=\count83
\c@paragraph=\count84
\c@subparagraph=\count85
\c@figure=\count86
\c@table=\count87
\abovecaptionskip=\skip41
\belowcaptionskip=\skip42
\bibindent=\dimen102
)
(/usr/local/texlive/2018/texmf-dist/tex/latex/amsmath/amsmath.sty
Package: amsmath 2017/09/02 v2.17a AMS math features
\@mathmargin=\skip43

For additional information on amsmath, use the `?' option.
(/usr/local/texlive/2018/texmf-dist/tex/latex/amsmath/amstext.sty
Package: amstext 2000/06/29 v2.01 AMS text

(/usr/local/texlive/2018/texmf-dist/tex/latex/amsmath/amsgen.sty
File: amsgen.sty 1999/11/30 v2.0 generic functions
\@emptytoks=\toks14
\ex@=\dimen103
))
(/usr/local/texlive/2018/texmf-dist/tex/latex/amsmath/amsbsy.sty
Package: amsbsy 1999/11/29 v1.2d Bold Symbols
\pmbraise@=\dimen104
)
(/usr/local/texlive/2018/texmf-dist/tex/latex/amsmath/amsopn.sty
Package: amsopn 2016/03/08 v2.02 operator names
)
\inf@bad=\count88
LaTeX Info: Redefining \frac on input line 213.
\uproot@=\count89
\leftroot@=\count90
LaTeX Info: Redefining \overline on input line 375.
\classnum@=\count91
\DOTSCASE@=\count92
LaTeX Info: Redefining \ldots on input line 472.
LaTeX Info: Redefining \dots on input line 475.
LaTeX Info: Redefining \cdots on input line 596.
\Mathstrutbox@=\box26
\strutbox@=\box27
\big@size=\dimen105
LaTeX Font Info:    Redeclaring font encoding OML on input line 712.
LaTeX Font Info:    Redeclaring font encoding OMS on input line 713.
\macc@depth=\count93
\c@MaxMatrixCols=\count94
\dotsspace@=\muskip10
\c@parentequation=\count95
\dspbrk@lvl=\count96
\tag@help=\toks15
\row@=\count97
\column@=\count98
\maxfields@=\count99
\andhelp@=\toks16
\eqnshift@=\dimen106
\alignsep@=\dimen107
\tagshift@=\dimen108
\tagwidth@=\dimen109
\totwidth@=\dimen110
\lineht@=\dimen111
\@envbody=\toks17
\multlinegap=\skip44
\multlinetaggap=\skip45
\mathdisplay@stack=\toks18
LaTeX Info: Redefining \[ on input line 2817.
LaTeX Info: Redefining \] on input line 2818.
)
(/usr/local/texlive/2018/texmf-dist/tex/latex/etoolbox/etoolbox.sty
Package: etoolbox 2018/08/19 v2.5f e-TeX tools for LaTeX (JAW)
\etb@tempcnta=\count100
)
(./howard.aux)
\openout1 = `howard.aux'.

LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 9.
LaTeX Font Info:    ... okay on input line 9.
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 9.
LaTeX Font Info:    ... okay on input line 9.
LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 9.
LaTeX Font Info:    ... okay on input line 9.
LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 9.
LaTeX Font Info:    ... okay on input line 9.
LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 9.
LaTeX Font Info:    ... okay on input line 9.
LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 9.
LaTeX Font Info:    ... okay on input line 9.
 [1

{/usr/local/texlive/2018/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./howa
rd.aux) ) 
Here is how much of TeX's memory you used:
 1628 strings out of 492639
 22941 string characters out of 6129301
 86515 words of memory out of 5000000
 5576 multiletter control sequences out of 15000+600000
 4262 words of font info for 17 fonts, out of 8000000 for 9000
 1141 hyphenation exceptions out of 8191
 27i,8n,21p,771b,486s stack positions out of 5000i,500n,10000p,200000b,80000s
</usr/local/texlive/2018/texmf-dist/fonts/type1/public/amsfonts/cm/cmm
i10.pfb></usr/local/texlive/2018/texmf-dist/fonts/type1/public/amsfonts/cm/cmr1
0.pfb></usr/local/texlive/2018/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10
.pfb></usr/local/texlive/2018/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt10.
pfb>
Output written on howard.pdf (1 page, 38417 bytes).
PDF statistics:
 24 PDF objects out of 1000 (max. 8388607)
 16 compressed objects within 1 object stream
 0 named destinations out of 1000 (max. 500000)
 1 words of extra memory for PDF output out of 10000 (max. 10000000)
screen shot 2018-11-24 at 14 38 24

My suggestion is to add an option such as fixcolon because it would affect spacing in old document and thus change line breaks. Maybe this can become a cumulative option for other fixes.

car222222 commented 6 years ago

This is a change, rather than a fix. So do not call it “fixcolon”.

Every editor in the world has strong views on spacing such ‘defining colons’, particularly those of the ‘ f : . . . subtype. There is no ‘correct spacing’, so no ‘kernel fix’ is needed. Whether an extra option should be added to amsmath I shall leave to its gatekeepers.

Also, I see no logic, visual or other, to making it a ‘mathopen’.

eg9 commented 6 years ago

@car222222

I disagree. The picture clearly shows that a thin space is added in front of a class 1 atom (Op), which is not at all desirable.

\mathopen has the desired feature as regards to spacing.

FrankMittelbach commented 6 years ago

I do agree that the redefinition done by amsmath is kind of unfortunate, but as @car222222 says it is deliberate due to what their editors consider how a colon should be treated and it is there in this form for two decades or more.

TLC says on this subject

However, the amsmath package makes unfortunate major changes to the spacing produced by the command \colon, so that it is useful only for a particular layout in constructions such as f\colon A\to B where it produces f : A → B. It is therefore wise to always use \mathpunct{:} for the simple punctuation colon in mathematics.

Changing to \mathopen also has other implications, as it is not just changing the behavior in front of mathops but also with class 3 and it is also questionable if other mathops like \prod or \sum shouldn't have the space. So I don't really think that anything other than documenting it is really feasible.

car222222 commented 6 years ago

Thanks, Frank, for supplying the details. I should add that I have been professionally involved in such design decisions on math microtypography when setting up latex for commercial use. In particular with the AMS. Other publishers do not like the AMS decisions as they tend to produce very spaced-out (==bad!) Setting. It is all a matter of personal taste. Nothing is right or wrong. Or even good or bad in many cases.

eg9 commented 6 years ago

@FrankMittelbach I still disagree. The added space before a \mathop is a clear oversight. There's no reason for the space after the colon in

\begin{align}
&f\colon R \to S\\
&f\colon \End{V) \to S
\end{align}

to not be the same.

True, \mathpunct would possibly be better, but it requires a computation based on the current value of \thinmuskip:

\nobreak
\mskip 2mu
\mathpunct {}
\nonscript\mkern -\thinmuskip
\mathpunct:
\mskip\muexpr6muplus1mu-\thinmuskip\relax

Whether this is better or worse than a simple \mathpunct: is a question of taste.

car222222 commented 6 years ago

eg9: “The added space before a \mathop is a clear oversight”. I think Frank explained very clearly that it was a deliberate design decision, did he not?
There is nothing to disagree with there, and no oversight.

The differences that occur in the spacing (in a number of situations) before each of the folllwing three is a separate question:

                 E (V)
            \End (V)     %%  \mathop {End}

\mathrm{End} (V)

but it is also a design question, there are no rules! (Repeat after me . . . 🤨 )

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity.

wspr commented 4 years ago

Due to compatibility reasons we will defer this for xmath.

cspiel commented 3 years ago

More fun with \colon.

I needed to allow for a line-break after \colon, so I added \allowbreak right after it. The formula then did break, but a space was introduced at the right margin.

Here is an example that compares the literal colon with the macro and my own "solution", \breakablecolon, which adds \allowbreak right after the (literal) colon and in particular before the skip.

\documentclass{article}

\usepackage{amsmath}

\newcommand*{\sample}[1]{\(f #1 A \to B\), }

\newcount\index
\newcommand*{\samples}[1]{\index=5\loop
  \sample{#1}\advance\index-1\ifnum\index>0\repeat}

\newcommand*{\breakablecolon}{
  \nobreak\mskip 2mu\mathpunct{}\nonscript
  \mkern-\thinmuskip{:}\allowbreak% cls: added `\allowbreak'
  \mskip 6mu plus 1mu\relax
}

\begin{document}
\begin{enumerate}
\item Literal colon\par
  \parbox{1in}{\samples{:}}
\item Colon macro\par
  \parbox{1in}{\samples{\colon}}
\item Colon macro with ``external'' breakpoint\par
  \parbox{1in}{\samples{\colon\allowbreak}}
\item Modified colon macro\par
  \parbox{1in}{\samples{\breakablecolon}}
\end{enumerate}
\end{document}