2

I've written some documents using a macro file to make writing math easier. In some of these macros, I use the answer from Applying MakeUppercase to non-English characters in math mode to use \MakeUppercase and \MakeLowercase on greek letters.

The problem occurs now that I'm trying to collect these documents together in a thesis. I've narrowed it down to having something to do with the document class being memoir (or rather, the thesis class uses \LoadClassWithOptions{memoir}).

MWE:

\documentclass{article}
%\documentclass{memoir}
\usepackage[utf8]{inputenc}
\usepackage{xifthen}
\usepackage{xargs}
    
%%%Greek letter case matching%%%
\makeatletter
  \g@addto@macro\@uclclist{%
    \delta\Delta
    \tau\Tau
  }
\newcommand\Tau{\mathrm{T}}

%Math macros%
\newcommandx\setnamestyle[1]
{
    \ifcat\noexpand#1\relax % use mathcal unless control sequence (greek letter)
        \MakeUppercase{#1} %greek letter or multiple chars
    \else
        \mathcal{\MakeUppercase{#1}} % single char
    \fi
}
        
\newcommandx\set[2]
{
    % set (uppercase)
    \expandafter\DeclareRobustCommand\csname#1set\endcsname{\ensuremath{
        \setnamestyle{#2}
     }}
     % element of set (lowercase)
    \expandafter\newcommandx\csname#1\endcsname{\ensuremath{
        \MakeLowercase{#2}
    }}  
    % element in set
    \expandafter\newcommand\csname#1inset\endcsname{\ensuremath{
            \csname#1\endcsname \in \csname#1set\endcsname
    }}
    % sum of elements in set
    \expandafter\newcommand\csname#1sum\endcsname{\ensuremath{
            \sum_{\csname#1inset\endcsname}
    }}
}

\begin{document}
\set{testSetA}{A}
\testSetA\qquad\testSetAinset\qquad\testSetAsum

\set{testSetTau}{\Tau}
\testSetTau\qquad\testSetTauinset\qquad\testSetTausum

\set{testSetDelta}{\delta}
\testSetDelta\qquad\testSetDeltainset\qquad\testSetDeltasum
\end{document}

Using the article document class yields the expected result of:

enter image description here

Whereas when using the memoir class, the greek letters are not correctly manipulated:

enter image description here

Any insight on how to fix this would be greatly appreciated.

6
  • I'm not sure whether typing \SetDeltasum is better than \sum_{\delta\in\Delta}.
    – egreg
    Mar 11, 2021 at 15:05
  • 2
    Note that memoir uses \usepackage[overload]{textcase} and thus replaces \MakeUppercase by \MakeTextUppercase, and that seems to be the problem. You get the same result if you add \usepackage[overload]{textcase} to your article example.
    – daleif
    Mar 11, 2021 at 15:13
  • Additionally I kind of agree with egreg, this kind of syntax might end up biting you in the long run.
    – daleif
    Mar 11, 2021 at 15:14
  • I had no idea memoir replaced \MakeUppercase, thanks @daleif. Mar 12, 2021 at 7:36
  • 1
    We did that quite a while ago especially because of math in the headers (memoirs default headers are in upper case, tough I normally always disable this in all my documents)
    – daleif
    Mar 12, 2021 at 8:02

2 Answers 2

1

One possibility is to re-write your document to use Unicode and expl3, which give you some better primitives for this. (ETA: I see that @egreg went ahead and wrote that.) However, the minimal fix to make this work in PDFTeX is:

  • Include alphabeta so that \alpha, \Tau, etc. are defined in text mode and \MakeUppercase and \MakeLowercase work on them
  • Include amsmath or amstext to be able to insert text-mode commands as math symbols
  • Render your Greek letters in text-mode, wrapped in \textnormal
\documentclass{memoir}
\usepackage[LGR, T1]{fontenc}
\usepackage{amsmath}
\usepackage{alphabeta}
\usepackage{xifthen}
\usepackage{xargs}

%Math macros%
\newcommandx\setnamestyle[1]
{
    \ifcat\noexpand#1\relax % use mathcal unless control sequence (greek letter)
        \mathord{\textnormal{\MakeUppercase{#1}}} %greek letter or multiple chars
    \else
        \mathcal{\MakeUppercase{#1}} % single char
    \fi
}
        
\newcommandx\set[2]
{
    % set (uppercase)
    \expandafter\DeclareRobustCommand\csname#1set\endcsname{\ensuremath{
        \setnamestyle{#2}
     }}
     % element of set (lowercase)
    \expandafter\newcommandx\csname#1\endcsname{\ensuremath{
        \mathord{\textnormal{\itshape\MakeLowercase{#2}}}
    }}  
    % element in set
    \expandafter\newcommand\csname#1inset\endcsname{\ensuremath{
            \csname#1\endcsname \in \csname#1set\endcsname
    }}
    % sum of elements in set
    \expandafter\newcommand\csname#1sum\endcsname{\ensuremath{
            \sum_{\csname#1inset\endcsname}
    }}
}

\begin{document}
\set{testSetA}{A}
\testSetA\qquad\testSetAinset\qquad\testSetAsum

\set{testSetTau}{\Tau}
\testSetTau\qquad\testSetTauinset\qquad\testSetTausum

\set{testSetDelta}{\delta}
\testSetDelta\qquad\testSetDeltainset\qquad\testSetDeltasum
\end{document}

Computer Modern sample

Listing the fonts in the document would show that this is technically using a LGR-encoded text font rather than your OML or OT1-encoded math font, but for the default font family, most of the glyphs are the same. You might run into problems with some letters, such as \lambda, \vartheta and \varphi. If you need to fix this, seriously consider the expl3 approach instead.

If you wanted to be able to insert Greek UTF-8 characters into your source, it would be possible to make that work in expl3, but I left that part of the code unchanged.

1
  • Thanks, @Davislor. This fixes the problem without requiring many changes. Although expl3 does look interesting. I'll look into that in the future. Mar 12, 2021 at 7:42
1

The problem is that memoir uses \MakeUppercase as modified by the textcase package, which is meant to ignore uppercasing for math.

You can get the same result with a different approach, not relying on \MakeUppercase or \MakeLowercase.

To be honest, I don't think you gain much by typing something like \SetAsum instead of \sum_{a\in A} and you lose in flexibility, because you can't do \sum_{a'\in A}, for instance.

%\documentclass{article}
\documentclass{memoir}
    
\providecommand\Tau{\mathrm{T}}

\ExplSyntaxOn
%Math macros
\cs_new_protected:Nn \rasmus_set_namestyle:n
 {
  \token_if_cs:NTF #1 { #1 } { \mathcal{#1} }
 }

\NewDocumentCommand{\set}{mm}
 {
  \cs_new_protected:cpn { #1set }
   {
    \rasmus_set_namestyle:n { #2 }
   }
  % element of set (lowercase)
  \cs_new_protected:cpx { #1 }
   {
    \token_if_cs:NTF { #2 }
     {
      \exp_not:c { \str_lowercase:f { \cs_to_str:N #2 } }
     }
     {
      \str_lowercase:n { #2 }
     }
   }
  % element in set
  \cs_new_protected:cpx { #1inset }
   {
    \exp_not:c { #1 } \exp_not:N \in \exp_not:c { #1set }
   }
  % sum of elements in set
  \cs_new_protected:cpx { #1sum }
   {
    \exp_not:n { \sum\sb } { \exp_not:c { #1inset } }
   }
 }
\ExplSyntaxOff

\begin{document}

\set{testSetA}{A}
$\testSetA\qquad\testSetAinset\qquad\testSetAsum$

\set{testSetTau}{\Tau}
$\testSetTau\qquad\testSetTauinset\qquad\testSetTausum$

\set{testSetDelta}{\delta}
$\testSetDelta\qquad\testSetDeltainset\qquad\testSetDeltasum$

\end{document}

enter image description here

I removed all \ensuremath parts that just add to the complication. Being able to type \SetDelta in text mode is not much more economic than $\SetDelta$ which instead carries semantics.

Note: if I ask LaTeX to show the definition of the commands with

\texttt{\meaning\testSetDelta}

\texttt{\meaning\testSetDeltainset}

\texttt{\meaning\testSetDeltasum}

I get

enter image description here

so no \csname in the replacement texts.

You must log in to answer this question.

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