# Using active characters to swap fonts?

I should probably say in advance that this question is inspired by sheer bloody-mindedness, and also apologize in advance if it's unanswerable or just silly. I've gotten it into my head that when I type NO, XeLaTeX should replace it with the character №. Which was easy enough to accomplish: I just duplicated the tex-text mapping and added a ligature.

LHSName "Numero"
RHSName "UNICODE"

pass(Unicode)

; establish numero ligature
U+004E U+004F   > U+2116 ; NO

; ligatures from Knuth's original CMR fonts

[...]


Having done this, however, I discovered that my favorite font doesn't include the numero character. So in order to make this work, I'd need to swap the font each time I typed NO. Aside from doing it by hand, the only solution I could come up with was to make the Unicode numero active, and define it like this:

\catcode\№=\active
\def №{{\fontspec[Mapping=numero]{Mshtakan}NO}}


Which works fine, and isn't the worst solution. It just calls for more inconvenient copying and pasting than I'd ideally like to engage in, defeating the purpose of the ligature definition. I guess that in a perfect world, I'd be able to cut out the font-map change and define the sequence "NO" as active, then do something like this:

\catcode\NO=\active
\def NO{{\fontspec{Mshtakan}\char"2116}}


But if there's documentation on activating two sequential characters extant then some pretty aggressive Googling hasn't turned it up. The only other solution that comes to mind is replacing a little-used but type-able character with the numero sign, but that seems sloppy.

I'd be massively grateful for any suggestions. Though I suspect I'm either missing something embarrassingly obvious or trying to force TeX to do something it simply wasn't built for.

After I posted this, I found a very similar question in these forums. It looks like another way to arbitrarily change the font for a single character is to adapt the answer there. Here's how it came out for me:

\XeTeXinterchartokenstate=1   % enable character classes
\newXeTeXintercharclass\CharNumero   % create a new class
\XeTeXcharclass № \CharNumero   % add № to the class

% Between any character of class 0 ["most characters are class 0 by default"] and \CharNumero change the font:
\XeTeXinterchartoks 0 \CharNumero = {\begingroup\fontspec{Mshtakan}}

% Between \CharNumero and any character end the group:
\XeTeXinterchartoks \CharNumero 0 = {\endgroup}

% Between a word boundary and \CharNumero change the font:
\XeTeXinterchartoks 255 \CharNumero = {\begingroup\fontspec{Mshtakan}}

% Between \CharNumero and a word boundary end the group:
\XeTeXinterchartoks \CharNumero 255 = {\endgroup}


Though I wound up using the answer given below, since I wanted NO to produce the symbol, this might be useful if ever someone is missing another character.

-
Please, don't use \fontspec{Mshtakan}: it's very inefficient. Use \newfontface (only one font, with no variations based on context) or \newfontfamily (probably, seeing what Mshtakan is, the former). The solution with interchartoks is similar to mine, but less efficient, as \newunicodechar works with macro expansion. –  egreg Jun 13 '12 at 11:31
@egreg Okay, thanks! I've switched to \newfontface and I'm playing with \newunicodechar, too. Much obliged. –  Daniel Jun 13 '12 at 16:17

I cannot see that it really makes sense. However, you can test the next character following the N:

\documentclass{article}
\usepackage{fontspec}
\newfontface\Msh{Mshtakan}

\begin{document}
\makeatletter
\catcode\N=\active
\def N{\@ifnextchar{O}{{\Msh\char"2116}\@gobble}{\string N}}
\makeatother

foo NO NOT No

\end{document}


-
Thank you so much! That worked great. I really appreciate the help. –  Daniel Jun 13 '12 at 8:12
Activating N might be dangerous: control sequences having N in their names will not be recognized any more. –  egreg Jun 13 '12 at 8:13
@egreg: that's obvious ... –  Herbert Jun 13 '12 at 8:16

The easiest way to accomplish your needs is

\usepackage{newunicodechar}
\newunicodechar{№}{{\mshtakan №}}


after having said

\newfontfamily{\mshtakan}{Mshtakan}


which is more efficient than calling \fontspec each time. No need of fancy map files.

Then you'll input normally

foo №123

-