[XeTeX] incompatibility with amsmath

Ross Moore ross at ics.mq.edu.au
Mon Aug 4 01:56:16 CEST 2008

Hi Will, Andrew, David, and others,

On 03/08/2008, at 2:11 PM, Andrew Moschou wrote:
> 2008/8/3 Will Robertson <wspr81 at gmail.com>
> In terms of how to fix this problem, the easiest is simply to  
> ensure that amsmath is loaded first and your definition is  
> \AtBeginDocument:
> \@ifpackageloaded{amsmath}{%
>  \AtBeginDocument{\XeTeXmathcode`\-="2 \symMRM "2212}%
> }{%
>  \AtBeginDocument{%
>    \@ifpackageloaded{amsmath}{%
>      \PackageError{fontspec}{%
>        Please load amsmath before fontspec%
>      }{Bad things happen when amsmath changes things behind my back.}%
>    }}%
> }{}

> I might look into this. Right now, this code has the problem that  
> if amsmath is not loaded at all, then the minus is not defined!
> Andrew

Yes; the problem lies within  amsmath.sty  itself.

The use of \AtBeginDocument here:

>>     %    \begin{macrocode}
>>     \AtBeginDocument{%
>>       \mathchardef\std at minus\mathcode`\-\relax
>>       \mathchardef\std at equal\mathcode`\=\relax
>>     }
>>     %    \end{macrocode}

is quite redundant, as it is just defining mathcode parameters
for internal macros  \std at minus  and  \std at equal .
It could easily do this immediately or \AtEndOfPackage ,
since its unlikely that any other package would subsequently
affect control-sequences having these internal names.

On the other hand, another package might well affect the \mathcode
of non-internals `\-  and/or `\=  .
Indeed, this is exactly what we want with Unicode-math in XeLaTeX.

Thus the problem is to delay the code line

     \XeTeXmathcode`\-="2 \symMRM "2212

until *after* the delayed amsmath.sty coding has taken effect.
Testing to see whether  amsmath.sty  is already loaded is not
enough, since this package might be loaded after the test has
been performed.

Thus the test can be first done immediately, but if it fails
to detect amsmath already then it must also be repeated later.
This modification to Will's coding handles everything, and
throws an error when  amsmath  comes after  fontspec :

\@ifpackageloaded{amsmath}{%  amsmath loaded already
  \AtBeginDocument{\XeTeXmathcode`\-="2 \symMRM "2212}%
}{%      amsmath not loaded yet
    \@ifpackageloaded{amsmath}{%  amsmath loaded
        Please load amsmath before fontspec%
      }{Bad things happen when amsmath changes things behind my back.}%
    }{%    amsmath not loaded
      \XeTeXmathcode`\-="2 \symMRM "2212\relax
    }%  end of  \@ifpackageloaded
  }%   end of  \AtBeginDocument
}%  end of amsmath not loaded yet

To remove the \PackageError  part requires having a 2nd hook
in LaTeX's expansion of \document (called by \begin{document}),
called  \AfterBeginDocument  say.

There are other reasons for having such a 2nd hook, and there
is a package  ldump.sty  which implements this, at least for
early versions of LaTeX-2e.
(It's not a standard package, since it needs to be checked with
each new release of LaTeX in case some internals have changed.)

Furthermore,  hyperref.sty  has coding that checks for
the existence of  \AfterBeginDocument .
If not found then it does
so that things work normally when  ldump.sty  is not loaded.

[GlenMorangie:~] rossmoor% grep -n -C 1 AfterBegin `kpsewhich  
101-\def\Hy at Info#1{\PackageInfo{hyperref}{#1}}
103:  \def\AfterBeginDocument{\AtBeginDocument}%
1863-    \typeout{Hyperref stopped early}%
1864:    \AfterBeginDocument{%
1865-      \PDF at FinishDoc
1940-           \typeout{Hyperref stopped early}%
1941:           \AfterBeginDocument{%
1942-             \PDF at FinishDoc
2758-    \typeout{Hyperref stopped early}%
2759:    \AfterBeginDocument{%
2760-      \PDF at FinishDoc
2805-              \typeout{Hyperref stopped early}%
2806:              \AfterBeginDocument{%
2807-                \PDF at FinishDoc
2968-  \ifHy at texht
3977-\let\Hy at footnote@currentHref\@empty
3979-  \Hy at pdfstringtrue
4040-  \if at filesw

Maybe it is about time the problems solved by  ldump.sty
become a standard part of LaTeX?

What was  ldump.sty  designed for?

It allows the \dump  of specialised formats built upon LaTeX,
including all the "safe" parts of included packages.
The "unsafe" parts are commands which open auxiliary files for
reading and writing, such as the usual .aux and for indexes,
minitoc, etc. The internal identifiers for such read- and
write-channels cannot be preserved within a  .fmt  file,
as these will be different at each run of the LaTeX job.

Anything else that may change on each run should be deemed
"unsafe" also, so must use \AfterBeginDocument  rather than
\AtBeginDocument , if loaded or defined within the preamble.

Because of the .aux file being opened by LaTeX, it is
necessary to reorder the tasks done by \document ,
in order to separate the "safe" and "unsafe" tasks.


Hope this helps,


Ross Moore                                       ross at maths.mq.edu.au
Mathematics Department                           office: E7A-419
Macquarie University                             tel: +61 (0)2 9850 8955
Sydney, Australia  2109                          fax: +61 (0)2 9850 8114

More information about the XeTeX mailing list