我已经在网上查找了好几个小时了。基本上,我需要做这样的事情,我可以在 LaTeX 中使用这个graphicx
包来完成:
\scalebox{.7}[1.0]{NARROW}
但!我需要使用清楚的\setbox
TeX(准确地说是带有 PDF 的 XeTeX),最好不使用任何软件包。最简单、最直接的方法是什么?它与和有关吗
\wd
?我只能尝试:
\def\narrow#1{
\setbox0\hbox{#1}
\multiply\wd0 by 0.7
\box0
}
但这显然不起作用,它出错了
You can't use `\wd' after \multiply.
答案1
dgoodmaniii 的回答已经向您展示了您的代码为何不起作用,以及如何使其起作用。但是 TeX 本身不知道如何“缩放”事物。您只能更改框的尺寸,但框内的字符保持不变。要获得相同的缩放比例,\scalebox
您需要特定于驱动程序的代码,而这些代码在不同的引擎之间会有所不同。
由于您使用 XeTeX,以下是\scalebox
我从和中偷来的代码。 中的代码包含 warpper 宏,它使用和。 这两个宏放置了将执行缩放的 s (不是因为我的懒惰, 的第二个参数不再是可选的):graphics.sty
dvipdfmx.def
graphics.sty
\scalebox
\Gscale@start
\Gscale@end
\special
\scalebox
\catcode`\@=11
\long\def\scalebox#1#2#3{%
\leavevmode
\def\Gscale@x{#1}\def\Gscale@y{#2}%
\setbox\z@\hbox{{#3}}%
\setbox\tw@\hbox{\Gscale@start\rlap{\copy\z@}\Gscale@end}%
\ifdim#2\p@<\z@
\ht\tw@-#2\dp\z@
\dp\tw@-#2\ht\z@
\else
\ht\tw@#2\ht\z@
\dp\tw@#2\dp\z@
\fi
\ifdim#1\p@<\z@
\hbox to-#1\wd\z@{\kern-#1\wd\z@\box\tw@\hss}%
\else
\hbox to#1\wd\z@{\box\tw@\kern#1\wd\z@\hss}%
\fi}
\def\GPT@space{ }
\def\Gscale@start{%
\special{pdf:btrans}%
\special{x:scale \Gscale@x\GPT@space\Gscale@y}}
\def\Gscale@end{\special{pdf:etrans}}
\catcode`\@=12
\scalebox{0.7}{1.0}{NARROW}\par
\scalebox{1.0}{1.0}{NARROW}\par
\scalebox{1.3}{1.0}{NARROW}\par
\bye
当然,仅加载graphicx.tex
就容易得多(并且独立于引擎):
\input graphicx.tex
\scalebox{0.7}[1.0]{NARROW}\par
\scalebox{1.0}{NARROW}\par
\scalebox{1.3}[1.0]{NARROW}\par
\bye
答案2
它不起作用,因为它\wd
基本上是一个运算符;你给它你想要的宽度的框。另外请记住,它\multiply
不适用于浮点数,只适用于整数;所以如果你想乘以 0.7 之类的数字,你必须乘以 7,然后除以 10。
假设全长为\hsize
,并且您想要一个 0.7 倍的盒子\hsize
:
\hbox to\hsize{This box will be the full width}
\newbox\mybox
\setbox\mybox\hbox to\hsize{\hfil}
\newdimen\mywidth\mywidth=\wd\mybox
\multiply\mywidth by7
\divide\mywidth by10
\hbox to\mywidth{This box will be the right width}
\bye
第一行纯粹是为了演示目的,显示行的全长。然后我们声明一个新的框,,并通过为其分配一个与该宽度相同的空值\mybox
来确保其宽度也等于。然后我们声明一个新的,,并将其设置为等于的宽度。然后我们将其乘以 7 并除以 10,这相当于乘以 0.7。最后,我们在框中放入一些文本,如您所见,它的宽度为原始框的 70%。\hsize
\hbox
dimen
\mywidth
\mybox
\mywidth
\mywidth
当然,您可以将其包装在宏中:
\hbox to\hsize{This box will be the full width}
\newbox\mybox
\newdimen\mywidth
\def\width#1#2#3#4{%
\setbox\mybox\hbox to#1{\hfil}
\mywidth=\wd\mybox
\multiply\mywidth by#2
\divide\mywidth by#3
\hbox to\mywidth{#4}
}%
\width{\hsize}{7}{10}{This box will be the short width}
\width{\hsize}{8}{10}{This box will be the short width}
\width{\hsize}{4}{10}{This box will be the short width}
\bye
这将产生以下内容:
如果需要文本换行,请将 换行到#4
中\hbox
,\vbox
然后更改\hsize
其中的 :
\newbox\mybox
\newdimen\mywidth
\def\width#1#2#3#4{%
\setbox\mybox\hbox to#1{\hfil}
\mywidth=\wd\mybox
\multiply\mywidth by#2
\divide\mywidth by#3
\hbox to\mywidth{%
\hfil%
\vbox{%
\hsize=\mywidth
#4
}%
\hfil%
}
}%
希望可以满足您的需要。
答案3
我尽可能简化了@phelype-oleinik 的例子,得出了以下结论:
\def\narrow#1{%
% Enter horizonal mode to make sure we don't bork up the start of the
% paragraph.
\leavevmode%
% Set the scale factors.
\def\ScaleX{0.7}%
\def\ScaleY{1.0}%
% Set box zero to the box with the text as is, without scaling, to get
% the width of this box. Not sure if that can be done without \setbox.
\setbox 0 \hbox{#1}%
\def\NewWidth{\ScaleX \wd 0}%
% The next box will overfull, but that's okay, as long as it's within
% the new width.
\hfuzz = \NewWidth%
% Create a horizontal box with the new width containing the scaled
% text.
\hbox to \NewWidth {%
\special{pdf:btrans}%
% x:scale requires that the two numbers are separated by a space.
\special{x:scale \ScaleX\space\ScaleY}%
#1%
\special{pdf:etrans}%
}%
}
这对我来说很有效,但如果您发现任何潜在问题,请告诉我。