# Conversion pt to mm or cm

Is there any way how to convert pt to mm or cm in plain TeX?

-
Does this help? tex.stackexchange.com/questions/8260/… –  Torbjørn T. Dec 6 '11 at 17:08
Sorry, the above was was LaTeX, not sure if any of it works in plain. –  Torbjørn T. Dec 6 '11 at 17:14
@TorbjørnT. Well, the accepted answer there only requires a few basic LaTeX macros that are easy enough to copy from latex.ltx. –  Joseph Wright Dec 6 '11 at 17:15
@TorbjørnT. It is not difficult to modify Philippe Goutet's solution to use eTeX only. –  Leo Liu Dec 6 '11 at 17:16
@Peter: Are we allowed to use the e-TeX extensions or does it have to be TeX82? –  Joseph Wright Dec 6 '11 at 17:16

To convert from a dimension given in points, save the dimension in a counter first, then do the conversion to what you need. When TeX saves the dimension in a counter it converts to sp units.

\catcode@=11
\@tempdimb25.4mm
\@tempcnta=\@tempdimb
\the\@tempcnta
\divide\@tempcnta by65536\par
\the\@tempcnta pt
\bye


Conversion from any unit to a point is a bit more involved:

\catcode@=11
\newdimen\@tempdimb
\newcount\@tempcnta
\def\topoint#1#2{%
\@tempdimb=#1
\@tempcnta=\@tempdimb
\multiply\@tempcnta by10
\multiply\@tempcnta by72 \divide\@tempcnta by2540
\expandafter\def\expandafter#2\expandafter{\the\@tempcnta}}

\topoint{25.4mm}{\test}

\test pt
\bye

-

Expandable solution without eTeX, using Heiko's bigintcalc package. Really, this is a mess, and you should use one of the solutions which make use of the eTeX extensions.

\input bigintcalc.sty
\catcode@=11

% Step 1: expand the number.
\def\pttocm#1{\romannumeral\expandafter\pttocm@i\romannumeral-0#1pt;;;;}
\def\pttocm@i#1{\pttocm@clean\ifcat\relax#1\the\fi#1}
\def\pttocm@clean{\expandafter\pttocm@clean@\romannumeral-0}
\def\pttocm@clean@#1{%
\ifcase\ifnum#1<"2B 1\else\ifnum#1>"39 1\else 2\fi\fi
\or\expandafter\pttocm@clean@end
\or\expandafter\pttocm@clean@do\fi #1}
\def\pttocm@clean@do#1#2;#3;{\pttocm@clean#2;#3#1;}

% Step 2: convert the decimal number to an integer/10^n
\def\pttocm@clean@end#1;#2;{\pttocm@clean@end@#2.;#2;.;!}
\def\pttocm@clean@end@#1.#2;#3.#4;#5!{\pttocm@decimal#4.;;#1#4}
\def\pttocm@decimal#1#2;{\ifx.#1\pttocm@decimal@\fi\pttocm@decimal#2;0}

% Step 3: convert from pt to nm (25400000nm=7227pt)
\def\pttocm@decimal@#1;0#2;#3;{\fi
\expandafter\expandafter\expandafter\pttocm@result
\bigintcalcDiv{\bigintcalcMul{25400000}{#3}}{7227#2}.;}

% Step 4: check the sign
\def\pttocm@result#1{%
\ifx-#1\expandafter\pttocm@result@neg
\else\expandafter\pttocm@result@pos\fi#1}
\def\pttocm@result@neg-{\expandafter\pttocm@rmstop
\expandafter-\romannumeral\pttocm@result@pos}
\chardef\pttocm@rmstop=0

% Step 5: shift the period 5 steps to the left, by reversing twice.
\def\pttocm@result@pos#1;{%
\pttocm@reverse 00000#1%
{?\pttocm@result@shift;}?;%
{?\pttocm@result@print;}?;}
\def\pttocm@reverse#1#2;{%
\pttocm@gobble#1%
\pttocm@reverse#2;#1}
\def\pttocm@gobble#1{}
\def\pttocm@result@shift#1;#2;#3;#4.#5#6#7#8#9%
{\pttocm@reverse #4#5#6#7#8#9.}
\def\pttocm@result@print#1;#2;#3;#4;{\pttocm@trimzeros{#4}}

% Step 6: remove spurious zeros.
\def\pttocm@trimzeros#1{\pttocm@trim@#1;\pttocm@trim@ 0;\pttocm@trim@@}
\def\pttocm@trim@#10;#2{#2#1;}
\def\pttocm@trim@@#1;#2;{\pttocm@trim@@@#1}
\def\pttocm@trim@@@#1{%
\ifx0#1\else\expandafter\pttocm@trim@end\expandafter#1\fi
\pttocm@trim@@@}
\def\pttocm@trim@end#1#2{%
\ifx.#1\expandafter\pttocm@rmstop\expandafter0%
\else\expandafter\pttocm@rmstop\fi #1}
\catcode@=12

\pttocm{-12.1232pt}

\pttocm{283000000000}

\def\foo{23}
\pttocm{12\foo.1\foo2pt}

\newdimen\testdimen
\testdimen=1cm
\pttocm{\testdimen}

\testdimen=-1mm
\pttocm{\testdimen}

\bye

-

With help of eTeX's \scantokens, \strip@pt can be also:

\def\strip#1.#2pt{#1\ifnum#2>0.#2\fi}
\def\convertto#1#2{%
\expandafter\expandafter\expandafter\strip
\expandafter\expandafter\scantokens
\expandafter{\the\dimexpr#2*65536/\number\dimexpr1#1\relax\relax\endinput}}

\convertto{pt}{1pc}

\bye

-

Here is a combination of Yiannis' question from Stripping the pt from a dimension and Philippe Goutet's answer from What are the various units (ex, in, pt, etc.) expressed in mm?:

\catcode@=11
\begingroup
\catcode P=12  % digits and punct. catcode
\catcode T=12  % digits and punct. catcode
\lowercase{%
\def\x{\def\rem@pt##1.##2PT{##1\ifnum##2>\z@.##2\fi}}}
\expandafter\endgroup\x%
\def\strip@pt{\expandafter\rem@pt\the}
\def\convertto#1#2{\strip@pt\dimexpr #2*65536/\number\dimexpr 1#1\relax\relax}
\catcode@=12
\convertto{mm}{10pt}
\bye


which requires e-TeX extensions.

-
And what about something without e-TeX extensions? –  Peter Dec 6 '11 at 17:32
You should terminate both \dimexpr with a \relax. Otherwise any dimen expression afterwards, like '* 10' will be taken as part of the inner \dimexpr. The \relax is removed by \dimexpr so you don't have to worry about expandable contexts. –  Martin Scharrer Dec 6 '11 at 17:52
@Peter: \convertto{mm}{\the\hsize} will work just fine. The catcode changes are only valid during the definition of the macro, not during the execution. –  Martin Scharrer Dec 6 '11 at 17:53
@MarcoDaniel: Why do you need Windows? Why do you need Linux? Why do you need Peugeot? Why do you need... >:-/ –  morbusg Dec 6 '11 at 18:16
@Stephen: I only know one distribution which doesn't come with e-TeX, that's the commercial Scientific Workbench. Are there more? The majority of users should have e-TeX. –  Martin Scharrer Dec 6 '11 at 20:52