15

I have a XeLaTeX document in which I want some unicode symbols to be auto-substituted, like ¼ → 1/4, » → >>, « → <<. But instead of a long list like

\catcode`\¼=\active\def¼{1/4}
\catcode`\«=\active\def«{<<}
...

I want something more elegant, like

\subst¼{1/4}
\subst«{<<}
\subst—{---}

So, I need a macro which will take two parameters, make #1 active, and \def it with #2. The first part was easy:

\def\subst#1#2{
  \catcode`#1=\active
  ...
}

The tricky part is the nested \def: no matter how I try, I cannot come up with anything working. The closest I got so far is defining commands like \¼ with

\expandafter\def\csname #1\endcsname{#2}

Which is of course not sufficient :)

How do I make it define those newly-made-active characters?

Sergey
  • 253

2 Answers2

14

The problem here is that the character must be already active when used for \def. The #1 argument however holds the same character in its previous catcode and this won't be affected by \catcode. There is a trick using \lowercase but I'm not sure if it works well with non-ASCII characters with normal LaTeX.

You can use \scantokens (an eTeX extension available in modern LaTeX versions) to reread the tokens under the current catcodes:

\def\subst#1#2{%
  \catcode`#1=\active
  \scantokens{\def#1}{#2}%
}

In this case you don't even need to read the second argument, because \def will do that for you:

\def\subst#1{%
  \catcode`#1=\active
  \scantokens{\def#1}%
}
Martin Scharrer
  • 262,582
  • 1
    You're right, \lowercase trick must do (it's exactly what the above-mentioned newunicodechar package uses). Thanks! – Sergey May 13 '11 at 09:15
12
\usepackage{newunicodechar}
\newunicodechar{¼}{1/4}
\newunicodechar{«}{<<}
\newunicodechar{—}{---}
egreg
  • 1,121,712
  • Thanks a lot! That's not exactly what I needed (my above example is a bit oversimplified), but I believe I found the clue to how to do it in that package's source. – Sergey May 13 '11 at 09:13
  • Does this work with PDFLaTeX or does it require XeLaTeX or LuaLaTeX? – Martin Scharrer May 13 '11 at 09:16
  • @Sergey: if you feel it can be of general interest, you should add the case to the question, so maybe I'll add something to the package. – egreg May 13 '11 at 09:16
  • 1
    @Martin: The package was born in order to extend the character set made available by the utf8 option for inputenc without having to look at the Unicode tables. So yes, it works also with pdflatex. – egreg May 13 '11 at 09:19