Контекст

Контекст

Контекст

В моем документе я прикрепляю подсказку к средней части слова. Чтобы продемонстрировать это поведение, попробуйте навести курсор только на букву 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.

Я ОТРЕДАКТИРОВАЛ, вставив \relaxпосле \kerns, как и предупредил автор.

Я ПЕРЕИЗДАЛ, основываясь на комментариях OP. Теперь, когда я полностью понимаю, что первый аргумент — это \tooltipне просто символ, а, предположительно, слово или несколько слов, я пересмотрел свою стратегию следующим образом: единственный кернинг/перечеркивание, который происходит, — это первая и последняя буквы аргумента. Таким образом, пробелы и явные дефисы в середине аргумента могут использоваться для переноса строки. Единственный случай, который все еще вызывает трудности, — это переносимые слова. Этот метод не делает переносы, но я не совсем уверен, почему.

Ниже приведен вариант (сделанный для компиляции в 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}

введите описание изображения здесь


Оригинальное решение:

Разговор с автором в комментариях приводит к двум моментам, которые следует отметить по поводу этого решения. Во-первых, этот метод сломается, если в первом аргументе будет пробел \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}

Связанный контент