7

Using fontspec together with amsmath breaks the use of capital greek letters in \DeclareMathOperator. Instead, the greek letter just is omitted.

Here is a minimal working example:

%! TEX program = xelatex
\documentclass{article}

\usepackage{fontspec}
\usepackage{amsmath}

\DeclareMathOperator{\exterior}{\Lambda}

\begin{document}
\begin{align*}
    \exterior^k V \\
    \Lambda^k V
\end{align*}
\end{document}

This is the output:

Two lines, first is the broken output, second is the expected output

Removing \usepackage{fontspec} makes the Lambda appear.

Funnily enough, if one also adds unicode-math in the mix, i.e.

\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage{amsmath}

it works. But unicode-math recommends to load it after amsmath, so it can override commands. Though this breaks it again, which is really confusing to me.

Is there a sensible way to use fontspec and amsmath together? Did I miss something?

2
  • Alternatively, you could typeset the operator using a properly changed variant of \wedge as shown here. (I guess that the convention of using \Lambda for exterior product space powers is due to laziness, not semactics... using \wedge seems more consistent to me.) Commented Mar 4, 2019 at 18:08
  • Yeah I actually came from this. Though mostly the symbol is too big for my taste (e.g. \bigwedge), or does not scale in subscripts (e.g. the solution using mbox). I also do not understand the more involved solutions, and am not particularly keen to add those. Commented Mar 4, 2019 at 18:14

3 Answers 3

7

\DeclareMathOperator uses internally the operator font, and this is changed by fontspec. Why the new font does have a Lambda, it doesn't have it in the same glyph slot.

You could either load fontspec with the [no-math] option, or use the real glyph:

\documentclass{article}
\usepackage{amsmath}
\usepackage{fontspec}

\DeclareMathOperator{\exterior}{Λ}
\begin{document}


\begin{align*}
    \exterior^k V\\
    \Lambda^k V
\end{align*}
\end{document}

enter image description here

14
  • Thanks. Any idea why the glyph slot is changed? That seems not very reasonable... Commented Mar 4, 2019 at 13:53
  • unicode engines and unicode fonts do change slots. You can't expect that a Lambda is at the same place in a OT1 legacy font than in unicode font. Commented Mar 4, 2019 at 14:06
  • 1
    @red_trumpet It’s a little complicated to go into in the comments. Traditionally, \Lambda came from a special math-letter font in the legacy OML encoding. Then, amsmath operators set the font to \operator@font and are really intended to typeset text like \sin or \log. If you load fontspec, it tries to enable modern fonts in text mode and still support legacy math fonts that contain Lambda. One thing it does is change \operator@font to the text font. But it does this in such a way that \Lambda doesn’t work. It ends up trying to load the wrong codepoint.
    – Davislor
    Commented Mar 4, 2019 at 17:38
  • 1
    @red_trumpet The solution is to use a different command to either load the Unicode character Λ from the operator font (the default, Latin Modern Roman, has it), or use a different math-mode command to get a Lambda. For example, \mathnormal\Lambda overrides the operator font and works (although this is slanted by default), \upLambda from unicode-math, \Uplambda, \Lambdaup, etc. from various legacy packages.
    – Davislor
    Commented Mar 4, 2019 at 17:42
  • 1
    @red_trumpet Another alternative is not to use \DeclareMathOperator at all. You can just define it as \mathop{\Lambda} to get operator-like spacing.
    – Davislor
    Commented Mar 4, 2019 at 17:44
7

The definition of \Lambda is \mathchar"7003, which means that when \operator@font is in effect, the glyph from slot 3 in that font is used, which doesn't exist.

You can avoid it with a trick:

\documentclass{article}

\usepackage{fontspec}
\usepackage{amsmath}

\newcommand{\opgreek}[1]{\begingroup\mathgroup-1 #1\endgroup}

\DeclareMathOperator{\exterior}{\opgreek{\Lambda}}

\begin{document}

\begin{align*}
    \exterior^k V \\
    \Lambda^k V
\end{align*}
\end{document}

enter image description here

Otherwise

\newcommand{\exterior}{\mathop{\kern0pt\Lambda}}
2

Why That Happened

There are two great answers, but since you asked me to give you more information about why this happens, I’d like to oblige. And I especially want to thank Ulrike Fischer for correcting my mistakes and teaching me something about LaTeX.

To see what’s going on, let’s extend your example a bit:

\documentclass[varwidth]{standalone}

\usepackage{fontspec}
\usepackage{amsmath}

\DeclareMathOperator{\exterior}{\lambda\Lambda\phi\Phi\omega\Omega}

\begin{document}
\(
    \exterior^k V
\)
\end{document}

enter image description here

It seems that all the Greek capital letters fail to display, but the lowercase ones show up fine. Why is this?

As Egreg said, “The definition of \Lambda is \mathchar"7003, which means that when \operator@font is in effect, the glyph from slot 3 in that font is used, which doesn't exist.” How does that work?

If you check The LaTeX Font Encoding Guide, you’ll see that character slot 3 of the OT1 encoding is Λ, and that the first eleven slots are the upright capital Greek letters that don’t look the same as a Latin letter. (The rest don’t exist in classic LaTeX; there is no \Alpha macro in the kernel and you just use the glyph A. In the days of 7-bit encodings, DEK didn’t think that was a good use of one of the precious 128 slots.)

In theory, every LaTeX text encoding has to support a minimal set of characters in the same slots as ASCII. In practice, some (such as LGR) don’t, but all font packages will avoid breaking commands such as \sin, \lim and \log. So, even if you change the text font encoding to something like T1, \DeclareMathOperator will still try to load \Lambda from an OT1 math alphabet. As you’ve seen, though, some font packages will break your example, since that’s a non-traditional use of the command.

What does fontspec do? It changes the text font to a Unicode-encoded font. If you check the Unicode code tables, the Greek letters from OT1 all map to non-graphing control characters in ASCII and Unicode. This is also why you will sometimes see an old PDF misspell “efficient flow” as “e cient ow.” The classic OT1 encoding mapped ligatures such as ff, fi, fl and ffi to slots with no glyph in ASCII too.

What about the lowercase Greek letters, which did work? Again, checking the encoding tables, they aren’t in OT1, but a different font encoding, OML. Changing the operator font doesn’t mess that up.

So, how to fix this?

Switch Entirely to Unicode

This is always my first option if I can. The unicode-math package does not fix \Lambda in this context, but it does provide math-mode commands \upLambda and \mupLambda, and the alphabet \symup\Lambda. This has the advantage of working even if your text font does not contain Greek letters.

\documentclass[varwidth]{standalone}

\usepackage{amsmath}
\usepackage{unicode-math}

\DeclareMathOperator{\exterior}{\mupLambda}

\begin{document}
\(
    \operatorname{Cl} \exterior^k V
\)
\end{document}

Sample

Ulrike Fischer’s answer does this by using the literal glyph Λ. \DeclareMathOperator{\exterior}{^^^^039b} is equivalent, and \char"039B or \symbol{"039B} would also work. These load the glyph Λ (U+039B) from the Unicode-encoded operator font. By default, this is Latin Modern Roman, which has it.

Use a Simpler Command

If what you want is an upright Λ symbol with the spacing of an operator, you don’t need to change the fonts around. And then fontspec won’t break it. A simplification of an idea from Egreg:

\documentclass[varwidth]{standalone}

\usepackage{fontspec}
\usepackage{amsmath}

\DeclareRobustCommand\exterior{\mathop{\Lambda}}

\begin{document}
\(
    \operatorname{Cl} \exterior^k V
\)
\end{document}

Sample

Use a Different Λ

Anything from a different math alphabet than the operator font would work, including \Uplambda from the upgreek package, the slanted \mathnormal\Lambda from plain LaTeX, loading any LGR font in math mode from mathastext, or the Greek alphabets in isomath.

Change the Font Back

This is what Egreg’s answer does, by starting a new math group within the operator environment. You might also use something like \mbox{\(\Lambda\)}.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .