Switching decimal mark between comma and dot

You might know that in large part of continental Europe, decimal mark is comma instead of dot. I am writing a really huge document and I would like to switch between them easily from one point, e.g.

\newif\comma
\commatrue

\ifcomma{
???
}

\pi = 3???14


I am aware that all decimal mark dots should be replaced by something else, but what? I am opening contest for a most elegant solution for the problem.

• Does this need to be a plainTeX solution? The siunitx already offers a much better alternative to type-setting numbers. – Qrrbrbirlbel Sep 18 '13 at 12:55
• Do you want the input source to switch to using comma (because someone else wrote it perhaps) or do you want the input to keep using . but the output use a comma or both input and output to change or... – David Carlisle Sep 18 '13 at 12:58
• Perhaps take a look at for example tex.stackexchange.com/questions/18673/…. – Joseph Wright Sep 18 '13 at 13:26
• Does not have to be plain tex. I just didn't found any other suitable keyword - e.g. there is no latex keyword. – Pygmalion Sep 18 '13 at 14:16
• siunitx seems like a fine solution, but that package loads 10 different other packages... I worry that this could largely decrease the speed of compiling my 200 page document! – Pygmalion Sep 18 '13 at 14:27

The following example sets the numbers in math mode. That allows an easy "redefinition" of the comma or dot to produce a dot or comma.

Syntax:

• \num{...} takes a number with dot or comma and outputs the number according to switch \ifnumcomma.
• If \numcommatrue if active, then \num outputs a comma, with \numcommafalse, the output is a dot.

The definition can be used for both plain TeX and LaTeX. The example contains a testing part for plain TeX:

\mathchardef\NumMathCodeDot=\mathcode\. %
\mathchardef\NumMathCodeComma=315 % \mathord, not \mathpunct

\newif\ifnumcomma

\def\num#1{%
\leavevmode
\begingroup
\ifnumcomma
\mathcode\.=\NumMathCodeComma
\mathcode\,=\NumMathCodeComma
\else
\mathcode\.=\NumMathCodeDot
\mathcode\,=\NumMathCodeDot
\fi
\ifmmode
#1%
\else
\mathsurround=0pt %
$#1$%
\fi
\endgroup
}

% Testing (plain TeX)

\numcommatrue
\num{3.14} + \num{1,23}

\numcommafalse
\num{3.14} + \num{1,23}

\bye


Remarks:

• The font for the number is taken from math mode.
• If siunitx is available, use it, because it is much more powerful and configurable. Then \num can be left in the code, but the definition then comes from siunitx. And \num is configured there.
• You might want to name the main user macro something else than \num since this name is already widely employed by users of the siunitx package. – Mico Sep 18 '13 at 15:49
• @Mico: That was the reason for the name. If the user loads siunitx (why it is not available for plain TeX?), then he does not need the code of this answer, because siunitx is much more powerful. – Heiko Oberdiek Sep 18 '13 at 15:51
• OK, you may want to flag this deliberate parallelism explicitly, e.g., by indicating that this command shouldn't be used if the siunitx package is loaded. Regarding the non-availability of siunitx for PlainTeX, I suspect that Joseph Wright can/should give the authoritative answer. :-) I suspect, though, that it might have something to do with much of the code in siunitx being written in LaTeX3... – Mico Sep 18 '13 at 16:03
• I'd say this is the most elegant solution regarding my original request. Therefore I will accept it, despite the fact I will actually use siunitx. I found it so powerful, I will risk even longer compilation of 200 page document. – Pygmalion Sep 18 '13 at 16:54

Decimal numbers in TeX can be input either with a period or a comma:

\hsize=10,5cm


is understood as well as

\hsize=10.5cm


However, this is about decimal numbers passed to TeX when required by its syntax rules. Printing numbers is a different matter, because TeX will print whatever you decide to.

So, if you define

\def\PI{3.14159}


and type \PI in your document, TeX will dutifully output

3.14159

In order to ensure uniformity across your document, you have to input your numbers in a different way:

\newif\ifcomma % starts as false
\def\cp{% comma or period
\ifcomma{,}\else.\fi
}
\def\PI{3\cp14159}

The number $\PI$ is an approximation to $\pi$.

\commatrue

The number $\PI$ is an approximation to $\pi$.

\bye


If you're using LaTeX, there are a few options available; the best is using siunitx and its \num command that will typeset its argument according to what options you have selected.

Use siunitx:

\documentclass{article}
\usepackage[output-decimal-marker={.}]{siunitx}
\begin{document}
you can even use comma \num{123,45} or dot \num{123.45}
\end{document}


just change {.} to {,}. You might also want to use group-separator={.} when using output-decimal-marker={,}`. The default group-separator is a thin whitespace.