テキストの背景にTikzハイライトを描く

テキストの背景にTikzハイライトを描く

私は最近紹介されましたLaTeX でのクールなテキスト強調表示Tikz のハイライトと下線用。

私は Antal の回答を自分のニーズに合わせて変更できましたが、次のことは達成できないようです。現在のように、ハイライトをテキストの上にではなく、テキストの背景に描画したいのです。

私が言いたいことをよりわかりやすく説明するために、MWE を用意しました。

\documentclass{minimal}
\usepackage{soul}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathmorphing}

\makeatletter

\newcommand{\defhighlighter}[3][]{%
  \tikzset{every highlighter/.style={color=#2, fill opacity=#3, #1}}%
}

\defhighlighter{yellow}{.5}

\newcommand{\highlight@DoHighlight}{
  \fill [ decoration = {random steps, amplitude=1pt, segment length=15pt}
        , outer sep = -15pt, inner sep = 0pt, decorate
        , every highlighter, this highlighter ]
        ($(begin highlight)+(0,8pt)$) rectangle ($(end highlight)+(0,-3pt)$) ;
}

\newcommand{\highlight@BeginHighlight}{
  \coordinate (begin highlight) at (0,0) ;
}

\newcommand{\highlight@EndHighlight}{
  \coordinate (end highlight) at (0,0) ;
}

\newdimen\highlight@previous
\newdimen\highlight@current

\DeclareRobustCommand*\highlight[1][]{%
  \tikzset{this highlighter/.style={#1}}%
  \SOUL@setup
  %
  \def\SOUL@preamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@BeginHighlight
      \highlight@EndHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@postamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@EndHighlight
      \highlight@DoHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@everyhyphen{%
    \discretionary{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everyexhyphen##1{%
    \SOUL@setkern\SOUL@hyphkern
    \hbox{##1}%
    \discretionary{%
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everysyllable{%
    \begin{tikzpicture}[overlay, remember picture]
      \path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
        \global\highlight@previous=\y0
        \global\highlight@current =\y1
      \endpgfextra (0,0) ;
      \ifdim\highlight@current < \highlight@previous
        \highlight@DoHighlight
        \highlight@BeginHighlight
      \fi
    \end{tikzpicture}%
    \the\SOUL@syllable
    \tikz[overlay, remember picture] \highlight@EndHighlight ;%
  }%
  \SOUL@
}
\makeatother

\begin{document}
\highlight[yellow]{The highlight is drawn over the text}

\bigskip
\begin{tikzpicture}
\node[fill=yellow!50]{the highlight is drawn below text};
\end{tikzpicture}
\end{document}

Tikz ノードの標準的な塗りつぶしのように、ハイライトをテキストの下に移動することは可能ですか?

答え1

この解決策では、OPの解決策をそのままにして、の形で別のレイヤーを追加します\Ohighlight

\newsavebox\tmpbox
\usepackage{tabto}
\newcommand\Ohighlight[2][]{%
  \tabto*{0in}\edef\tmpx{\TabPrevPos}\tabto*{\tmpx}%    SAVES THE CURRENT x POSITION
  \savebox\tmpbox{%                            SETS THE TEXT, STARTING AT x, IN A SAVED MINIPAGE
  \begin{minipage}[b]{\textwidth}
    \tabto*{\tmpx}#2\strut%
  \end{minipage}}%
  {\color{\highlightcolor!0}\highlight[#1]{#2}}%         STEP #1, BELOW
  \vspace*{\dimexpr-\dp\tmpbox-\ht\tmpbox+\dp\strutbox}% STEP #2, BELOW
  \tabto*{\tmpx}#2\unskip\ %                             STEP #3, BELOW
}

これは次のことを達成しようとします:

\highlight1)テキストをハイライトと同じ色(つまり非表示)にして、元の ing を実行します。

2) 元の位置(パッケージを介して水平方向)に戻り、測定されたtabto垂直方向に戻ります。\vspaceminipage

3) 前のハイライトの上にテキストを平文で再入力し、ページの位置を正しい位置に維持します。

このソリューションは、 の出力とクリアテキストの間にカーニングの違いが見つかったため、編集されました\highlight。 プレは\highlight、二重に打たれたテキストの問題を回避するために、空白の色で実行されるようになりました。

この方法は、ページ境界を越えては機能しません。MWE では、段落境界を越えて機能しますが、ページに挿入された接着剤が\raggedbottom使用されない限り、それが台無しになる可能性があると思います。

いくつかのカーニングの問題が指摘され、コードを編集することになったという事実は、場合によっては改行が\highlight平文のテキストと異なる可能性を残しており、これは明らかにこの方法の失敗を表しています。この問題は末尾の空白スペースに関連しているように思われたため、\unskip\平文の最終テキストに を追加すると (手順 3)、カーニングの問題は解決したようですが、別の形で問題が再発しないとは言えません。

カーニングの問題をチェックしたい場合は、この行{\color{\highlightcolor!0}\highlight[#1]{#2}}%を に編集します{\color{red}\highlight[#1]{#2}}%。これにより、テキストが二重に強調表示されます。一致しない場合は、そこに表示されます。

\documentclass{minimal}
\usepackage{soul}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathmorphing}

\makeatletter

\newcommand{\defhighlighter}[3][]{%
  \tikzset{every highlighter/.style={color=#2, fill opacity=#3, #1}}%
}

\def\highlightcolor{yellow}
\defhighlighter{\highlightcolor}{.5}

\newcommand{\highlight@DoHighlight}{
  \fill [ decoration = {random steps, amplitude=1pt, segment length=15pt}
        , outer sep = -15pt, inner sep = 0pt, decorate
        , every highlighter, this highlighter ]
        ($(begin highlight)+(0,8pt)$) rectangle ($(end highlight)+(0,-3pt)$) ;
}

\newcommand{\highlight@BeginHighlight}{
  \coordinate (begin highlight) at (0,0) ;
}

\newcommand{\highlight@EndHighlight}{
  \coordinate (end highlight) at (0,0) ;
}

\newdimen\highlight@previous
\newdimen\highlight@current

\DeclareRobustCommand*\highlight[1][]{%
  \tikzset{this highlighter/.style={#1}}%
  \SOUL@setup
  %
  \def\SOUL@preamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@BeginHighlight
      \highlight@EndHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@postamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@EndHighlight
      \highlight@DoHighlight
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@everyhyphen{%
    \discretionary{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everyexhyphen##1{%
    \SOUL@setkern\SOUL@hyphkern
    \hbox{##1}%
    \discretionary{%
      \tikz[overlay, remember picture] \highlight@EndHighlight ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everysyllable{%
    \begin{tikzpicture}[overlay, remember picture]
      \path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
        \global\highlight@previous=\y0
        \global\highlight@current =\y1
      \endpgfextra (0,0) ;
      \ifdim\highlight@current < \highlight@previous
        \highlight@DoHighlight
        \highlight@BeginHighlight
      \fi
    \end{tikzpicture}%
    \the\SOUL@syllable
    \tikz[overlay, remember picture] \highlight@EndHighlight ;%
  }%
  \SOUL@
}
\makeatother

\newsavebox\tmpbox
\usepackage{tabto}
\newcommand\Ohighlight[2][]{%
  \tabto*{0in}\edef\tmpx{\TabPrevPos}\tabto*{\tmpx}%
  \savebox\tmpbox{%
  \begin{minipage}[b]{\textwidth}
    \tabto*{\tmpx}#2\strut%
  \end{minipage}}%
  {\color{\highlightcolor!0}\highlight[#1]{#2}}%
  \vspace*{\dimexpr-\dp\tmpbox-\ht\tmpbox+\dp\strutbox}%
  \tabto*{\tmpx}#2\unskip\ %
}
\textwidth=5in

\begin{document}
\highlight{The original highlight is drawn over the text.
The original definition works over... 

Multi paragraphs, so my fix should try to as well.}

\bigskip
\begin{tikzpicture}
\node[fill=yellow!50]{with tikz, the highlight is drawn below text but not fancy};
\end{tikzpicture}

Now here is my fix. \Ohighlight{The highlight is drawn under the text}
Does it work multiline?
\Ohighlight[yellow]{The highlight is drawn under the text The highlight is drawn under the text The highlight is drawn under the text The highlight is drawn under the text

A new paragraph}
And more...
\Ohighlight{short}

\end{document}

ここに画像の説明を入力してください

下の画像はズーム表示です。

ここに画像の説明を入力してください

関連情報