10

I would like to use € (\€ is also acceptable) in a way which €{9x10,00} (or €[]) produces \SI{9x10,00}{€} (so a particular case of converting € to command). Preferably, if typed alone () it should produce \si{€}, but that's probably extra detail.

The € symbol comes up a lot in some of my documents, and typing \SI{#1}{€} becomes annoying for someone (not me) that doesn't have much latex/programming experience and is used to word, hence the goal of such a simple final command.

I've tried:

\catcode`€=11 %also \catcode8364=11 which is 0x20AC, unicode for €

\newcommand{\€}[1]{\SI{#1}{€}}

but I get an error on catcode because € is utf-8. Also I'd be required to input €{} and would become an error. This is close to what I want, but it relies on catcode.

  • why can't you use utf-8? the command you created \newcommand{\€}[1]{\SI{#1}{€}} works just fine here, under XeLaTex – Runar Jun 23 '16 at 17:53
  • 2
    Use XeLaTeX or LuaLaTeX for good unicode support. – Christoph Frings Jun 23 '16 at 17:54
  • 1
    LaTeX is in the title for a reason :) And I can't use it because it's not provided by my distribution. Edit: Oh crap, no package, but binaries there. I just have never tried any of them, and always heard about compatibility issues. Only recently did I start to use latex in a more complex way – Olivetree Jun 23 '16 at 18:00
  • 2
    LaTeX is a language. pdfLaTeX is a compiler, so are XeLaTeX and LuaLaTeX. So maybe you should change your title to mention pdfLaTeX :) I don't think this is doable with pdfLaTeX. – Christoph Frings Jun 23 '16 at 18:07
  • @ChristophFrings thank you for the clarification :) Title changed! – Olivetree Jun 23 '16 at 18:33
13

It's trivial with Unicode TeX engines like XeTeX or LuaTeX:

\catcode€=\active
\newcommand*€[1]{\SI{...}{...}}

The same applies to the other TeX engines with 8-bit input encodings (for example, latin9).

But it is trickier with UTF-8 bytes as input, because the Euro symbol consists of three UTF-8 bytes. Three bytes cannot be one active byte, also the category codes are usually not "letter" (11), but "other" (12). Thus these UTF-8 bytes cannot be used inside command names.

The following example uses LaTeX's inputenc machinery to assign the UTF-8 byte sequence to a macro:

  • If the macro is immediately followed by the left curly brace (without spaces in between), then the macro takes the number as parameter and passes it to \SI.

  • If the macro is immediately followed by the left square bracket, then an optional argument together with the number is passed to \SI.

  • Otherwise the normal euro sign is printed without using a parameter.

  • \SI{9}{€} works.

  • € is robust for \section and the table of contents.

  • For hyperref's bookmarks, \texteuro can be used or an alternative for the bookmarks can be provided via \texorpdfstring. The euro symbol without arguments can be enabled by:

    \pdfstringdefDisableCommands{\let\EuroMacro\texteuro}
    

Full example:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage{newunicodechar}

\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage{lmodern}

\usepackage{ltxcmds}

\usepackage{siunitx}
\sisetup{output-decimal-marker={,}}
\DeclareSIUnit{\euro}{\texteuro}

\newcommand*{\sieuro}[2][]{\SI[{mode=text,#1}]{#2}{\euro}}

\makeatletter
\newcommand*{\EuroMacro}{}
\protected\def\EuroMacro{%
  \ltx@ifnextchar@nospace\bgroup\sieuro{%
    \ltx@ifnextchar[\sieuro\texteuro
  }%
}
\newunicodechar{€}{\EuroMacro}
\makeatother

\begin{document}
  €{12,34} and the currency is €.

  €[add-integer-zero]{.42}

  \sisetup{mode=text}
  \SI{9}{€}
\end{document}

Result

A version with minimized number of packages in the TeX file. As variation, the euro symbol is generated by package eurosym:

\documentclass{article}

\usepackage[utf8]{inputenc}% UTF-8 input for non-Unicode TeX engines
\usepackage{eurosym}% euro sign
\usepackage{siunitx}

\sisetup{output-decimal-marker={,}}
\DeclareSIUnit{\Euro}{\euro}
\newcommand*{\sieuro}[2][]{\SI[{mode=text,#1}]{#2}{\Euro}}

\makeatletter
\newcommand*{\EuroMacro}{%
  \ifx\@let@token\bgroup
    \expandafter\sieuro
  \else
    \ifx\@let@token[%
      \expandafter\expandafter\expandafter\sieuro
    \else
      \expandafter\expandafter\expandafter\euro
    \fi
  \fi
}
\protected\def\EuroMacroAux{%
  \futurelet\@let@token\EuroMacro
}
\AtBeginDocument{%
  \DeclareUnicodeCharacter{20AC}{\EuroMacroAux}%
}
\makeatother

\begin{document}
  €{12,34} and the currency is €.

  €[add-integer-zero]{.42}

  \sisetup{mode=text}
  \SI{9}{€}
\end{document}

Result

  • This has the same problem as egreg's answear (can't use \SI{9}{€}), requires an extra package, and was answeared (a bit) later. But it would have solved my problem anyway, so +1. Maybe if you solve the problem before egreg? :) – Olivetree Jun 23 '16 at 18:40
  • @Olivetree I do not see your problem with "extra" packages. \newunicodechar{€}{...} is clearly easier to maintain than \DeclareUnicodeCharacter{20AC}{...}. The needed package newunicodechar is small, just provides the macro \newunicodechar and therefore does not have potential to conflict with other packages. Nevertheless I have added a variation in the updated answer, where the number of packages in the TeX file is reduced to quite a minimum. – Heiko Oberdiek Jun 23 '16 at 19:00
  • I have no problem with packages. But I see using more packages (\usepackage{ltxcmds}) than another answear (which also had "short clean code") as a disadvantage. As long as all problems are solved, extra packages don't demean the answear. But you had the same problems, as big an answear, and more packages. Just that :) Now you solved the problem, I can use \SI{9}{€}, so your solution is better! – Olivetree Jun 23 '16 at 19:16
8

You can't set the category code of in pdflatex, because it's three byte long. However, there are other methods.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{textcomp}
\usepackage[right]{eurosym} % I can't stand textcomp euro symbol
\usepackage{newunicodechar}

\makeatletter
\newunicodechar{€}{\olivetree@euro}
\newcommand{\olivetree@euro}{\@ifnextchar\bgroup\EUR{\euro}}
\makeatother

\begin{document}

You owe me €{100.23}; please, pay in €.

\end{document}

enter image description here

If you want to use siunitx features for printing the number,

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{textcomp}
\usepackage[right]{eurosym} % I can't stand textcomp euro symbol
\usepackage{newunicodechar}
\usepackage{siunitx}

\makeatletter
\newunicodechar{€}{\olivetree@euro}
\newcommand{\olivetree@euro}{\@ifnextchar\bgroup\olivetree@euro@arg\euro}
\newcommand{\olivetree@euro@arg}[1]{\num{#1}\,\euro}
\makeatother

\begin{document}

You owe me €{100.23}; please, pay in €.

\end{document}

Some changes are needed for XeLaTeX or LuaLaTeX:

\documentclass{article}
\usepackage{fontspec}
\usepackage{newunicodechar}
\usepackage{siunitx}

\makeatletter
\newcommand{\olivetree@euro}{\@ifnextchar\bgroup\olivetree@euro@arg{€}}
\newcommand{\olivetree@euro@arg}[1]{\num{#1}\,€}
\newunicodechar{€}{\olivetree@euro}
\makeatother

\begin{document}

You owe me €{100.23}; please, pay in €.

\end{document}
  • This is almost perfect, but now I can't use \SI{9}{€}, it says \olivetree@euro@arg has an extra }. I can, however, use {€}. I know it sounds silly to want to want to use that, but this means it might be broken elsewhere. Do you have any idea? (this is still the exact solution I wanted). – Olivetree Jun 23 '16 at 18:31
  • 1
    @Olivetree You want too much. Besides, I can't recommend overloading the symbol. – egreg Jun 23 '16 at 19:31
5

\€ is also acceptable

Then, a simple approach:

\documentclass{article}
\usepackage{eurosym,siunitx}
\def\€#1{\SI{#1}{\mbox{\euro}}}
\begin{document}
\€{9x10,00}
\end{document}

mwe

  • Why does \def work when \newcommand doesn't? Does it parse every character until finding a # or {? (+1 for simplicity, and something new) – Olivetree Jun 24 '16 at 10:00
  • 2
    @Olivetree Yes, \def is not the same beast. Try \def\x2{xxxx} and then \x2, \x22 and \x1 for example... The macro \x2 work but the number is not the argument, , \x22 is not undefined because is \x2 with a 2 pasted, and \x1 is not undefined too, because the macro is really only \x but fail anyway, because doesn't match its definition. – Fran Jun 24 '16 at 15:34
4

If you are using pdftex (or tex) then is three tokens not one. The first character has to be catcode 13 (active) to trigger the UTF-8 interpretation of the following two characters and so it is not possible to define \€ as a TeX command name can only be a single character unless all the characters in the name are catcode 11 (letter).

If you use xetex or luatex then € is a single token and can be made active, or you can define \€.

That said it is possible to do what you want by defining the inputenc definition of € to be a command using siunitx.

  • Won't changing catcode of first character be dangerous? More characters use that. Could you provide a more detailed example on how to make the whole character sequence usable in newcommand? – Olivetree Jun 23 '16 at 18:09
  • @Olivetree you can't change the catcode it has to be 13 and you can't use it in \newcommand. egreg shows how to use an inputenc declaration, as I suggest here. – David Carlisle Jun 23 '16 at 18:49
  • I had misunderstood the beginning of your answear. It's much clearer now, thank you! – Olivetree Jun 23 '16 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.