Приложение

Приложение

Представьте, что я хочу нарисовать заполненную фигуру позади чего-то, уже набранного на странице. Обычный подход заключается в определении \tikzmarkкоманды, которая просто запоминает координату, используя remember pictureи overlayопции, а затем использовать эту координату для рисования tikz-вещей с использованием прозрачности.

Например:

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}
\noindent\tikzmark{A}\lipsum[11]

\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow, opacity=.3] (A) circle(2em);
\end{tikzpicture}
\end{document}

Что производит:

Результат

Но теперь предположим, что я хочутвердыйжелтый. Очевидная идея — использовать pgfonlayerи рисовать его на фоне. Однако, концепция фона/переднего плана, по-видимому, существует только внутри сред tikz. Поскольку основной текст на странице уже был набран, он находится за фоном tikz:

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}

\noindent\tikzmark{A}\lipsum[11]

\begin{tikzpicture}[remember picture, overlay]
\begin{pgfonlayer}{background}
  \fill[yellow] (A) circle(2em);
\end{pgfonlayer}
\end{tikzpicture}
\end{document}

Плохой

Можно ли это сделать?

решение1

Спасибо Эндрю Стейси за то, что указал мне нановый улучшенныйtikzmkark. Я не знал об этом. Эта версия \tikzmarkпозволяет использовать определенные координатыдоточка его определения. Использование \tikzmark{foo}новой координаты с именем (pic cs:foo)доступно и может быть использовано в любом месте страницы.

Используя новый \tikzmark, взятый из преамбулыhttps://tex.stackexchange.com/a/50054/12571Эту проблему можно решить следующим образом:

\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

С желаемым результатом:

Хороший

Приложение

\tikzmarkДля полноты изложения ниже приводится код всего документа, включая преамбулу, в которой появляется новое :

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}
\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

ПРИМЕЧАНИЕ: Любой, кто склонен голосовать за этот ответ, должен голосовать заhttps://tex.stackexchange.com/a/50054/12571вместо :-)


Обновлять

Как отметила Ульрике Фишер в своем комментарии, размещение , tikzpictureкоторое рисует фон слишком близко к оформленному абзацу, может иметь побочные эффекты для предыдущего абзаца:

\begin{document}
\lipsum[5] % <------ Added a previous paragraph
\medskip
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

Плохой :-(

Однако, если слишком сильно отделить « » tikzpictureот « », \tikzmarkмы рискуем оказаться на разных страницах, и, таким образом, фон появится не на той странице.

Лучшим решением будет использовать какое-либо решение, которое «сохраняет» требуемую картинку и «активирует» ее вывод в качестве фона в то же время, когда мы размещаем \tikzmark, как, например, решение, предложенное Ульрике в комментарии.

Я рассмотрел другой вариант, а именно использование замечательногофоновый пакеткГонсало Медина(спасибо Эндрю за предложение в чате!). Используя этот пакет, мы устанавливаем фоновое изображение в любом месте документа и «активируем» его \BgThispageодновременно с размещением \tikzmark. При использовании этого подхода нет необходимости вновый улучшенныйtikzmarkи вместо этогостарый минималистичныйtikzmarkможет быть использован.

Важно также задать соответствующие значения параметрам placementи scale, чтобы получить чертеж в соответствующих координатах. Есть MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage[pages=some]{background}
\usepackage{lipsum}
\def\tikzmark#1{\tikz[remember picture, overlay]\coordinate(#1);}

\begin{document}
\backgroundsetup{scale=1,placement=bottom,contents={%
\noindent\begin{tikzpicture}[remember picture,overlay]
  \fill[yellow] (A) circle(2em);
\end{tikzpicture}%
}}

\lipsum[5]
\medskip
\noindent\tikzmark{A}\BgThispage\lipsum[11]
\end{document}

И после трёх (почему три?) компиляций я получаю:

Хороший!

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