语境
V
在我的文档中,我将工具提示附加到单词的中间部分。为了演示此行为,请尝试将鼠标悬停在单词中的字母上。AVA
下面是我的命令的实现和使用方法\tooltip
。
%% This tooltip command
\newcommand\tooltip[2]{%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#2)>>}%
#1%
\special{pdf:eann}%
}
%% is used like so
A\tooltip{V}{Tooltip text here.}A
%% which expands like so.
A\special{…}V\special{…}A
制作工具提示的细节与问题没有直接关系,但我将其包括在内以供参考。
问题
通过散布来分离单词的各个部分\special{}
,即A\special{}V\special{}A
导致各部分之间的字距不再适用。¹(注意:\special
并不特殊——这种行为也会发生在A{V}A
和中A{}V{}A
,除非使用 XeLaTeX 或 LuaLaTeX。²)
部分解决方案
我能够使用以下命令恢复后两部分的字距调整,该命令改编自这个答案,它用来\futurelet
达到这个目的。
\newcommand\kernright[1]{\def\hltext{#1}\futurelet\hlnext\hldokern}
\def\hldokern{%
\sbox0{\mbox\hltext\mbox\hlnext}\sbox2{\hltext\hlnext}\kern\dimexpr\wd2-\wd0\relax%
}
(尽管这个问题具体涉及不同样式之间的字距调整,但解决方案仍然有效。另一个更通用的问题没有令人满意的解决方案。
这里有三个包装命令\tooltip
。
\newcommand\tooltipA[2]{#1}
\newcommand\tooltipB[2]{\tooltip{#1}{#2}}
\newcommand\tooltipC[2]{\tooltip{#1}{#2}\kernright{#1}}
下面是比较表和相应的渲染图。
 A\tooltipX{V}{}A expands to AV kerned? VA kerned?
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾
A. Normal kerned text AVA yes yes
B. Interrupted text A\special{}V\special{}A no no
C. Partial solution A\special{}V\special{}\kernright{V}A no yes
但是,我还没能想出一种方法来编写一个\tooltipD
可以恢复 A 和 V 之间字距的命令,因为似乎没有一个命令可以执行与 相关的“相反”的操作\futurelet
。
问题
如何恢复 A 和 V 之间的字距?
我希望\kernleft
在命令主体的某处插入一个附加命令\tooltipC
,以产生相当于图像顶部的输出。
平均能量损失
(工具提示应该在 XeLaTeX 中起作用。³)
\documentclass[varwidth=true]{standalone}
\newcommand\tooltip[2]{%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#2)>>}%
#1%
\special{pdf:eann}%
}
\newcommand\kernright[1]{\def\hltext{#1}\futurelet\hlnext\hldokern}
\def\hldokern{%
\sbox0{\mbox\hltext\mbox\hlnext}\sbox2{\hltext\hlnext}\kern\dimexpr\wd2-\wd0\relax%
}
% A-C are from original question; D is adapted from Steven's answer
\newcommand\tooltipA[2]{#1}
\newcommand\tooltipB[2]{\tooltip{#1}{#2}}
\newcommand\tooltipC[2]{\tooltip{#1}{#2}\kernright{#1}}
\newcommand\tooltipD[2]{%
#1%
\setbox0=\hbox{#1}\kern-\wd0%
\tooltip{#1}{#2}%
\kern-\wd0#1%
}
\begin{document}
\tooltip{Foo}{Bar}
A\tooltipA{V}{Tooltip text}A
A\tooltipB{V}{Tooltip text}A
A\tooltipC{V}{Tooltip text}A
A\tooltipD{V}{Tooltip text}A
\end{document}
答案1
是否允许加粗?如果允许,这将恢复字距。我不明白工具提示代码,但试图在此 MWE 中展示我的意思。恢复正确字距的关键是将宏启动\tooltip
为#1
并以 结束#1
。
我已根据 OP 的警告进行了编辑,在 s\relax
后插入。\kern
根据 OP 的评论,我重新编辑了。现在我完全理解了第一个参数\tooltip
不仅仅是一个字符,而且可能是一个单词或几个单词,我修改了我的策略如下:唯一发生的字距调整/重写是在参数的第一个和最后一个字母上。因此,参数中间的空格和显式连字符可用于换行。仍然有困难的一种情况是可连字符的单词。这种方法不能连字符,但我不太清楚为什么。
以下是 OP 在其评论中提供的文件的一个变体(在 PDFLaTeX 中编译),用于测试各种方法 AD 的字距调整,当方法被强调为即将出现换行符时。目前提出的解决方案是方法 D,它可以捕获字距,但不能自动连字。
\documentclass{article}
%\usepackage{fontspec}
\usepackage{xcolor}
%\setmainfont{Minion Pro}
%\setmonofont{Consolas}
\usepackage{stringstrings}
\newcommand\tooltip[2]{%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#2)>>}%
#1%
\special{pdf:eann}%
}
\newcommand\kernright[1]{\def\hltext{#1}\futurelet\hlnext\hldokern}
\def\hldokern{%
\sbox0{\mbox\hltext\mbox\hlnext}\sbox2{\hltext\hlnext}\kern\dimexpr\wd2-\wd0\relax%
}
\newcommand\tooltipA[2]{#1}
\newcommand\tooltipB[2]{\tooltip{#1}{#2}}
\newcommand\tooltipC[2]{\tooltip{#1}{#2}\kernright{#1}}
\newcommand\tooltipD[2]{%
\firstof#1\relax%
\tooltip{#1}{#2}%
\substring[q]{#1}{$}{$}%
\setbox0=\hbox{\thestring}%
\kern-\wd0\relax\thestring%
}
\def\firstof#1#2\relax{#1\setbox0=\hbox{#1}\kern-\wd0\relax}
\begin{document}
\setlength\parindent{0pt}
\newcommand\lotsofxs{\textcolor{gray!20}{xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xx}}
\newcommand\trial[4]{\lotsofxs{} #2\csname tooltip#1\endcsname{#3}{Tooltip text}#4\par}
\newcommand\fourtrials[4]{
{\texttt{#2|#3|#4}\hfill\textbf{#1}}\par\hrule\par
\trial{A}{#2}{#3}{#4}
\trial{B}{#2}{#3}{#4}
\trial{C}{#2}{#3}{#4}
\trial{D}{#2}{#3}{#4}
\bigskip
}
Default behavior: VAVA\tooltipD{V}{text}AVAV\vspace{1em}
%\rule{\textwidth}{2pt}\par
\fourtrials{Unhyphenatable word (only situation with overflow)}{A}{VxxxxxxxxxxV}{A}
\fourtrials{Multiple words}{A}{Vxxxxx xxxxxV}{A}
\fourtrials{Explicit hyphen}{A}{Vxxxxx\-xxxxxV}{A}
\fourtrials{Hyphenatable word}{‘}{Automatically}{.}
\fourtrials{Multiple words}{‘}{Auto matically}{.}
\end{document}
原解决方案:
与评论中的 OP 的对话引出了关于此解决方案的两点。第一点是,如果 的第一个参数中有空格,则此方法将中断\tooltip
。原因是空格具有粘连,而粘连不是固定宽度。因此,不能使用字距调整来撤消空格。
第二点是,单词中间的工具提示会阻止该单词的连字。虽然这不会使该方法“失效”,但它确实允许原本可以连字的长单词在中间有工具提示的情况下不进行连字。因此,可能会出现边距超限,这不是直接因为该方法,而是因为间接阻止了正常的连字。
\documentclass{article}
%% This tooltip command
\newcommand\tooltip[2]{%
#1%
\setbox0=\hbox{#1}\kern-\wd0\relax%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#2)>>}%
\phantom{#1}%
\special{pdf:eann}%
\kern-\wd0\relax#1%
}
\parskip 1ex
\begin{document}
\noindent\rule{\textwidth}{2pt}
The tooltipped word is ``crAVAt,'' with the tooltip on the ``V''.
\noindent$\bullet$ \textbf{As it is supposed to work}
ccvcvf adsakljfd kdfklj sdkljsdf kjsdkj ds fdsfdggfds dd dgfd fsf dsf ddd
crA\tooltip{V}{Tooltip text}At
dfsf sdf s sd fsdf sdfsd sd ds sd frsdr d sfsd fds
ccvcvf adsakljfd kdfklj sdkljsdf kjsdkj ds fdsfdggfds dd dgfd fsf dsf dd %d
crA\tooltip{V}{Tooltip text}At
dfsf sdf s sd fsdf sdfsd sd ds sd frsdr d sfsd fds
\noindent$\bullet$ \textbf{Tooltip prevents hyphenation, which can cause margin overruns}
ccvcvf adsakljfd kdfklj sdkljsdf kjsdkj ds fdsfdggfds dd dgfd fsf ds
crA\tooltip{V}{Tooltip text}Atinated
the prior word is tooltipped.
ccvcvf adsakljfd kdfklj sdkljsdf kjsdkj ds fdsfdggfds dd dgfd fsf ds
crAVAtinated
the prior word is not tooltipped.
\noindent$\bullet$ \textbf{Spaces (glue) in tooltip's argument 1 can cause non-alignment of kern}
Here are spaces in the first argument iddsfxsxddgfdxffdxxfgsfdsfdd
crA\tooltip{V V}{Tooltip text}At
Here the tooltip was on the ``V V'' in the middle of ``crAV VAt.''
\end{document}
答案2
可能我只是在测量了带有和不带有框边界分隔的相邻字符的文本后,重新明确地添加字距。
\documentclass[varwidth=true]{standalone}
\newcommand\tooltip[2]{%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#2)>>}%
#1%
\special{pdf:eann}%
}
\newcommand\tooltipZ[6]{%
#1%
\kerna{#1}{#2}%
\tooltip{#3}{#4}%
\kerna{#5}{#6}%
#6%
}
\newcommand\kerna[2]{%
\sbox0{#1}\sbox2{#2}\sbox4{#1#2}%
\kern\dimexpr\wd4-\wd0-\wd2\relax}
\begin{document}
\tooltip{Foo}{Bar}
AVA
% #1 pre-char
% #2 first active char
% #3 active text
% #4 tooltip
% #5 last active char
% #6 post-char
\tooltipZ{A}{V}
{V}{Tooltip text}
{V}{A}
\end{document}
答案3
我的建议是稍微重新设计一下\tooltip
语法。这种宏的第一个参数是整个单词,但突出显示的文本被包围在第二个括号中,例如:
\tooltip{A{V}Atar}{avatar}
如果没有第二个括号,则整个文本将突出显示:
\tooltip{tipped text}{tip}
这可以简单地实现,无需重叠字母:
\def\tooltip#1{\tooltipA#1{}\end}
\def\tooltipA#1#{\def\tmpa{#1}\tooltipB}
\def\tooltipB#1#2\end#3{\ifx\end#1\end
\tooltipC{}\tmpa{}{#3}\else \tooltipC\tmpa{#1}{#2}{#3}\fi
}
\def\tooltipC#1#2#3#4{% #1=pre-text, #2=tipped text, #3=post-text, #4=tip
#1\kerncorr{#1}{#2}%
\special{pdf:bann<</Type/Annot /Subtype/Widget /FT/Btn /Ff 65536 /H/N /TU(#4)>>}%
#2%
\special{pdf:eann}%
\kerncorr{#2}{#3}#3%
}
\def\kerncorr#1#2{\setbox0=\hbox{#1\kern0pt #2}\setbox2=\hbox{#1#2}%
\kern\wd2 \kern-\wd0
}
如果需要,可以直接设置连字符\-
,例如
\tooltip{A{V}A\-tar}{avatar}