我希望能够将分数表达式传递给s*[<number>]
。\DeclareFontShape
最终目标是指示 LaTeX2e 的新字体选择方案 (NFSS) 执行更准确的计算。可以做到吗?
\documentclass{article}
\usepackage{fontspec}
\setmainfont{texgyretermes-regular.otf}[
Scale=1.10502958579881657 % 747/676
]
\setsansfont{texgyreheros-regular.otf}[
Scale=1.00685871056241427 % 734/729
]
\begin{document}
\fontsize{10.5bp}{15.75bp}\selectfont
By NFSS: \the\numexpr\fontdimen6\font\relax\par
What I want: \the\numexpr\dimexpr10.5bp*747/676\relax\relax\par
\sffamily
By NFSS: \the\numexpr\fontdimen6\font\relax\par
What I want: \the\numexpr\dimexpr10.5bp*734/729\relax\relax
\end{document}
背景信息对于那些不熟悉 TeX 二进制算法的人来说。在下面的例子中,我尝试将原始维度放大 1.2
。当1.2\mydimen
遇到时,TeX 首先将浮点数转换1.2
为其内部整数表示:Round(1.2*65536) = Round(78643.2) = 78643
。然后将舍入后的结果乘以1,000,000sp
产生Floor(78643*1,000,000/2^16) = Floor(1199996.9482421875) = 1,199,996sp
。
但是如果我们将 重写 1.2
为 6/5
,然后使用原语\multiply
和\divide
,或者使用 eTeX 的表达式扩展,我们可以得到更准确的结果。
\documentclass{article}
\newdimen\mydimen
\newcommand*\onemillionsp{15.2587890625pt\relax}
\begin{document}
\mydimen\onemillionsp
\verb|\mydimen|: \the\numexpr\mydimen\relax\par
\mydimen1.2\mydimen
\verb|1.2\mydimen|: \the\numexpr\mydimen\relax\par
\smallskip
Use \verb|\multiply| and \verb|\divide| primitives:\par
\mydimen\onemillionsp
\multiply\mydimen by 6\divide\mydimen by 5\relax
\verb|\mydimen * 6 / 5|: \the\numexpr\mydimen\relax\par
\smallskip
Use eTeX's extension:\par
\mydimen\onemillionsp
\verb|\<expression>|: \the\numexpr\mydimen*6/5\relax
\end{document}
答案1
NFSS 毕竟是可以入侵的,如果 LaTeX3 团队有人感兴趣的话,可以试试这个增强版:)
。
我的新实现\empty@sfcnt
与十进制表达式兼容。但是,分数表达式语法需要 eTeX 的\dimexpr
。
\documentclass{article}
\makeatletter
% Look ahead for either a decimal or a fraction
% and extract all stuff after the first slash:
\def\detect@decimal@or@frac#1/#2\detect@decimal@or@frac{%
\edef\@tempa{#2}%
}
% Hack into NFSS:
\def\empty@sfcnt#1{%
\@tempdimb \f@size\p@
\ifx\optional@arg\@empty
\else
% The following line was the original:
% \@tempdimb \optional@arg\@tempdimb
% Replaced with my new implementation:
\expandafter\detect@decimal@or@frac
\optional@arg/0\detect@decimal@or@frac
\def\@tempb{0}%
\ifx\@tempa\@tempb
% A decimal or an integer is passed here
\@tempdimb \optional@arg\@tempdimb
\else
% A fraction is passed here
\@tempdimb \dimexpr\@tempdimb*\optional@arg\relax
\fi
% End of new implementation
#1{Font\space shape\space `\curr@fontshape'\space
will\space be\MessageBreak
scaled\space to\space size\space \the\@tempdimb}%
\fi
\edef\external@font{\mandatory@arg\space at\the\@tempdimb}}
\makeatother
\usepackage{fontspec}
\newcommand\test[1]{%
\begingroup
\texttt{\string\fontspec\{texgyretermes-regular.otf\}[Scale=\{#1\}]}:\\
\fontspec{texgyretermes-regular.otf}[Scale={#1}]%
\the\fontdimen6\font\par
\medskip
\endgroup
}
\setlength\parindent{0pt}
\begin{document}
\test{1}
\test{1.2}
\test{6/5}
\test{1,4}
\test{14/10}
\test{1.105029585798816568}% 747/676
\test{747/676}
\end{document}