Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally execute a macro depending on the font used

Tags:

latex

xetex

I’m a big fan of ampersands – so much that I heed SimpleBits’ advice to “use the best available ampersand” quite religiously.

For that purpose, I’ve defined the following shortcut in LaTeX:

\let\amp\&
\renewcommand\&{{\scalebox{1.2}{\textnormal{\fontspec{Baskerville}\itshape\amp}}}}

In brief, this changes all uses of the “normal” ampersand to a stylish variant, e.g.:

This is a text \& it contains an ampersand.

(Using \& instead of just & since that’s how LaTeX works – the latter is already reserved to separate columns in table environments.)

However, this always uses the same font – here, Baskerville – no matter whether it fits or not. I’d like to use a different font depending on the font family used. That is, I want to use another ampersand in combination with sans serif text, and in particular I want to prevent rewriting of the ampersand in a monospace context. So in the following two contexts, I don’t want to trigger the above definition:

{\sffamily a \& b}
{\ttfamily a \& b}

How do I do that?

I imagine something like the following:

\renewcommand\&{
  \ifsans
    {\fontspec{Trebuchet MS}{\textnormal{\itshape\amp}}}
  \else
    \ifmono
      \amp
    \else
      {\fontspec{Baskerville}\scalebox{1.2}{\textnormal{\itshape\amp}}}
    \fi
  \fi}
like image 666
Konrad Rudolph Avatar asked Jul 05 '10 15:07

Konrad Rudolph


2 Answers

It works the following way:

\documentclass[letterpaper,10pt]{article}
\usepackage[latin1]{inputenc}
\usepackage{german}
\usepackage{geometry}
\geometry{margin=2cm}
\newcommand*\origsffamily{}
\let\origsffamily\sffamily
\renewcommand*\sffamily{\origsffamily\small {\renewcommand\&{{\scalebox{1.2}{\textnormal{\fontspec{Baskerville}\itshape\amp}}}}}}

\begin{document}


hello, this is \& a \sffamily test \& 


\end{document}

That means, you include the change of the ampersand sign into the definition of (in my example) \sffamily.

The drawback is - of course - that you have to do this for all desired font families.

like image 107
phimuemue Avatar answered Nov 06 '22 02:11

phimuemue


You can test for the standard LaTeX token list \f@family, however, this might not be as reliable as you want. The following code simply checks whether the current family equals the default families set by \setmainfont and \setsansfont, but not whether the fonts are really sans-serif:

\documentclass{article}

\usepackage{fontspec}
\usepackage{expl3}
\usepackage{xparse}

\setmainfont{DejaVu Serif}
\setsansfont{DejaVu Sans}

\makeatletter
\ExplSyntaxOn
\NewDocumentCommand \amp { } {
  \tl_if_eq:NNTF \f@family \rmdefault {
    % this is a roman font
    A
  } {
    \tl_if_eq:NNTF \f@family \sfdefault {
      % this is a sans font
      B
    } {
      % something else
      C
    }
  }
}
\ExplSyntaxOff
\makeatother


\begin{document}

test \amp\ test

\sffamily
test \amp\ test

\ttfamily
test \amp\ test

\end{document}
like image 2
Philipp Avatar answered Nov 06 '22 01:11

Philipp