コンテクスト

コンテクスト

コンテクスト

私のドキュメントでは、単語の中央部分にツールヒントを添付しています。この動作を確認するには、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つまり部分間のカーニングが適用されなくなります。¹(注:は特別なことではありません。XeLaTeX または LuaLaTeX を使用しない限り、\specialこの動作は および でも発生しますA{V}AA{}V{}A²

部分的な解決策

次のコマンドを使用して、後半の2つの部分のカーニングを復元することができました。この答え、これ\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%
}

(この質問は異なるスタイル間のカーニングに特化していますが、解決策は有効です。より一般的な質問満足のいく解決策はありません。

のラッパー コマンドを 3 つ示します\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 でコンパイルするように作成) です。これは、メソッドが差し迫った改行で強調されている場合のさまざまなメソッド (A ~ D) のカーニングをテストするためのものです。現在提案されている解決策はメソッド 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 と会話した結果、この解決策について指摘すべき点が 2 つあることがわかりました。1 つは、スペースが の最初の引数にある場合、このメソッドが機能しなくなること\tooltipです。その理由は、スペースにはグルーがあり、グルーの幅は固定されていないためです。したがって、カーニングを使用してスペースを元に戻すことはできません。

2 つ目のポイントは、単語の真ん中にツールチップがあると、その単語のハイフネーションが妨げられることです。これによってこの方法が「破綻」するわけではありませんが、ツールチップが真ん中にあると、本来はハイフネーションされるはずの長い単語がハイフネーションされなくなります。したがって、この方法の直接的な原因ではなく、間接的に通常のハイフネーションが妨げられることで、余白オーバーランが発生する可能性があります。

\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。このようなマクロの最初のパラメータは単語全体ですが、強調表示されたテキストは 2 番目の中括弧のペアで囲まれます。例:

\tooltip{A{V}Atar}{avatar}

2 番目の中括弧のペアがない場合、テキスト全体が強調表示されます。

\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}

関連情報