应用字距调整后无法“调整回原位”

应用字距调整后无法“调整回原位”

通常,当我对一对字符应用字距调整时,我会通过随后添加字距调整的负片来撤消字距调整,即{x}\kern1em\{y}\kern-1em(参见使用 \raisebox 和 \kern 移动组合字符)。

但在这种情况下,我无法撤消字距调整。如果我随后添加字距调整的负数,则下一个字符会被推开,但如果我不添加它,则下一个字符会被拉向前一个字符。

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Times New Roman}

\newcommand{\longa}{\char"0101}
\newcommand{\myacute}{\char"00B4}
\newcommand{\stressedlonga}{\longa\kern-.35em\raisebox{.35ex}{\myacute}\kern.35em}
\newcommand{\newstressedlonga}{\longa\kern-.35em\raisebox{.35ex}{\myacute}}
\begin{document}
\noindent{\stressedlonga}a\\ % characters are too far apart
aa\\ % this is the correct spacing between two characters
{\newstressedlonga}a % characters are too close together
\end{document}

在此处输入图片描述

编辑


egreg 建议我首先尝试一下,即添加组合重音符U+0301而不是全角字符U+00B4。但是,由于我无法理解的原因,一旦我尝试修改 的位置U+0301(我想这样做以匹配U+1E53),重音符就会向右移动,而且我所做的一切都不会让它向后移动。在下面的例子中,我根本没有调整重音符的字距,但它却向右移动。

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Times New Roman}

\newcommand{\longa}{\char"0101}
\newcommand{\combiningacute}{\char"0301}
\newcommand{\stressedlonga}{\longa\raisebox{-.1ex}{\combiningacute}}

\begin{document}
\noindent{\stressedlonga}{\char"1E53}\\
{\longa\combiningacute}{\char"1E53}
\end{document}

在此处输入图片描述

答案1

这个问题相当棘手。你可以避免添加手动字距调整来补偿叠加的重音,但无论如何你都会失去正常的字距调整。

TeX(与其他排版系统一样)会自动在字符对(例如o和 )之间应用字距v;使用 Computer Modern 字体时, 的宽度ov为 10pt,而字符宽度之和为 10.27782pt。

完全普遍地解决这个问题意味着在每个字符之后进行前瞻以查看是否\stressedlonga后面跟着一个字母,并且在构造这个字符之后,进行前瞻以查看后面跟着什么字母,所有这些都是为了应用在简单a排版时所应用的字距。

除了一般问题之外,这里有一个解决方案\stressedlonga,不需要知道字形的宽度。

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Times New Roman}

\newcommand{\longa}{\char"0101}
\newcommand{\myacute}{\char"00B4}
\newcommand{\stressedlonga}{%
  \leavevmode\vbox{\offinterlineskip
    \ialign{##\cr
            \hidewidth\char"00B4\hidewidth\cr
            \noalign{\kern-1ex}
            \char"0101\cr}%
  }%
}


\begin{document}
\noindent
\stressedlonga a\\
aa
\end{document}

在此处输入图片描述

你可以通过增加一些字距来微调重音的位置:如果你改变行

\hidewidth\char"00B4\hidewidth\cr

进入

\hidewidth\kern0.05em\char"00B4\hidewidth\cr

你得到

在此处输入图片描述

当然,总是有可能使用组合字符的;我将使用^^^^输入 U+0301 COMBINING ACUTE ACCENT 的约定:

ā^^^^0301

生产

在此处输入图片描述


一些话\ialign

TeX 中用于对齐的基本函数是\halign,当然在 LaTeX 中也可用,它是一个原始函数。与 LaTeX 用于\tabcolsep添加列间空间一样,\halign使用 的值\tabskip。Plain TeX 和 LaTeX 都定义了一个包装器\halign以确保\tabskip为零:

% latex.ltx, line 494:
\def\ialign{\everycr{}\tabskip\z@skip\halign} % initialized \halign

token 参数\everycr可以包含在比对的每一行之间添加的材料(也包括在第一行之前和最后一行之后),因此将其重置为空。当然,\ialign应该在组中使用。

的语法\halign相当复杂:它后面必须跟有{,并且直到第一个为止的内容都是以- 分隔\cr的列表&模板。例如,当指定c单元格中的一列时tabular,LaTeX 基本上会插入模板\hfil#\hfil,其中#代表单元格的内容。

在我们的例子中,模板是最小的,只是#(必须加倍,因为它出现在定义中)。这意味着我们只有一行;不需要填充,因为我们只有两行,第二行将决定列宽。

比对的第一行包含

\hidewidth\char"00B4\hidewidth\cr

即,相对于列宽居中的尖锐重音符;\hidewidth是一个具有无限可拉伸性的大负跳跃,因此它永远不会影响最宽单元格的计算。\cr行结束。

接下来是

\noalign{\vskip-1ex}

意思是:“行与行之间相距 1ex”,通常是从重音的底部到基线的距离(减去一些间隙)。这个长度应该根据字体进行调整,但很容易检查结果并采取相应的行动。

下一行仅包含“长 a”,对齐结束。

我们将 放置\ialign在 内\vbox,这样对齐中最后一行的基线将成为框的基线。此框是必需的,因为\halign在水平模式下 是非法的。 的宽度\vbox将与其内部 的宽度相同\halign。在 中,\vbox我们设置\offinterlineskip为关闭 TeX 对行间空间的常规计算,因此不会添加任何内容,我们可以使用 来控制行之间的间距\noalign{\vskip...}

首字母\leavevmode是必需的,以确保 TeX 在案例\stressedlonga先出现的情况下开始一个段落。

答案2

添加\showoutput,你会看到

....\kern -3.50006
....\hbox(8.35255+0.0)x3.33008
.....\hbox(6.78711+0.0)x3.33008, shifted -1.56544
......\EU1/TimesNewRoman(0)/m/n/10 ´
....\EU1/TimesNewRoman(0)/m/n/10 a

您将间距缩减为 -3.5pt,但框的宽度只有 3.33pt

正如评论中指出的那样你想要类似的东西

\newcommand{\stressedlonga}{\longa\llap{\raisebox{.35ex}{\myacute}\kern.1em}}

相关内容