有没有什么方法可以转换pt
成mm
或cm
纯 TeX?
答案1
要从以点为单位给出的尺寸进行转换,请先将尺寸保存在计数器中,然后转换为所需的尺寸。当 TeX 将尺寸保存在计数器中时,它会转换为sp
单位。
\catcode`@=11
\@tempdimb25.4mm
\@tempcnta=\@tempdimb
\the\@tempcnta
\divide\@tempcnta by65536\par
\the\@tempcnta pt
\bye
从任何单位到点的转换都稍微复杂一些:
\catcode`@=11
\newdimen\@tempdimb
\newcount\@tempcnta
\def\topoint#1#2{%
\@tempdimb=#1
\@tempcnta=\@tempdimb
\multiply\@tempcnta by10
\divide\@tempcnta by18647 \advance\@tempcnta by1
\multiply\@tempcnta by72 \divide\@tempcnta by2540
\expandafter\def\expandafter#2\expandafter{\the\@tempcnta}}
\topoint{25.4mm}{\test}
\test pt
\bye
答案2
无需 eTeX 即可使用 Heikobigintcalc
软件包的可扩展解决方案。这确实很乱,您应该使用利用 eTeX 扩展的解决方案之一。
\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
答案3
借助 eTeX 的\scantokens
,\strip@pt
还可以:
\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
答案4
以下是 Yiannis 的问题从维度中剥离 pt以及 Philippe Goutet 的回答以 mm 表示的各种单位 (ex、em、in、pt、bp、dd、pc) 是什么?:
\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
这需要 e-TeX 扩展。