这是问题的延续在多页边距中绘制 tikz 线
John Kormylo 提供的代码允许在代码中定义的环境所包围的文本部分前面绘制边距装饰。它使用 everypage 包,似乎运行良好。此外,环境是可破坏的,这非常有趣,因为它可以与提供可破坏框的包嵌套。例如,装饰可以扩展到多个页面,同时可以包括可破坏框(定理、段落、引文……)。
正如我在评论中提到的那样,我想使用几种不同类型的装饰来实现不同的目的。我尝试复制代码,但即使更改所有名称(包括计数器和函数 chekmarkpage),它也不起作用。事实上,它同时绘制两种装饰。此外,一些环境被忽略了……
这是我正在使用的代码。如果有人能帮助我让这些功能正常工作,我将不胜感激 :)。
\documentclass[a4paper,12pt]{book}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
\usepackage{showframe}
\usepackage{everypage}
\makeatletter
\newcommand{\checkmarkpageredenv}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
\edef\markid{\csname save@pt@#1\endcsname}%
\edef\markpage{\csname save@pg@\markid\endcsname}%
\ifnum\thepage<\markpage\relax #2%
\else
\ifnum\thepage=\markpage\relax #3%
\else #4%
\fi
\fi}%
}
\makeatother
\newcounter{redenvid}
\newcounter{redenvdone}
\newenvironment{redenv}{\par\tikzmark{begin\theredenvid}\ignorespaces}%
{\par\tikzmark{end\theredenvid}\stepcounter{redenvid}\ignorespaces}
\newcommand{\drawredenv}{\checkmarkpageredenv{begin\theredenvdone}{}%
{\begin{tikzpicture}[remember picture,overlay]
\path ({pic cs:begin\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(A);
\checkmarkpageredenv{end\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:end\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
\end{tikzpicture}}%
{\begin{tikzpicture}[remember picture,overlay]
\coordinate (A) at (current page text area.north west);
\checkmarkpageredenv{end\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:end\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
\end{tikzpicture}}%
\checkmarkpageredenv{end\theredenvdone}{}%
{\stepcounter{redenvdone}\drawredenv}%
{}% this should not happen
}
\AddEverypageHook{\drawredenv}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\newcommand{\checkmarkpageblueenv}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
\edef\markid{\csname save@pt@#1\endcsname}%
\edef\markpage{\csname save@pg@\markid\endcsname}%
\ifnum\thepage<\markpage\relax #2%
\else
\ifnum\thepage=\markpage\relax #3%
\else #4%
\fi
\fi}%
}
\makeatother
\newcounter{blueenvid}
\newcounter{blueenvdone}
\newenvironment{blueenv}{\par\tikzmark{begin\theblueenvid}\ignorespaces}%
{\par\tikzmark{end\theblueenvid}\stepcounter{blueenvid}\ignorespaces}
\newcommand{\drawblueenv}{\checkmarkpageblueenv{begin\theblueenvdone}{}%
{\begin{tikzpicture}[remember picture,overlay]
\path ({pic cs:begin\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(C);
\checkmarkpageblueenv{end\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:end\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
\end{tikzpicture}}%
{\begin{tikzpicture}[remember picture,overlay]
\coordinate (C) at (current page text area.north west);
\checkmarkpageblueenv{end\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:end\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
\end{tikzpicture}}%
\checkmarkpageblueenv{end\theblueenvdone}{}%
{\stepcounter{blueenvdone}\drawblueenv}%
{}% this should not happen
}
\AddEverypageHook{\drawblueenv}
\begin{document}
\newpage
\thispagestyle{empty}
Next line begins the rule for BLUE ENV:
\begin{blueenv}
\lipsum[2]
\end{blueenv}
Line above ends the rule for BLUE ENV.
Two on one page for RED ENV:
\begin{redenv}
\lipsum[3]
\end{redenv}
One on three pages for BLUE ENV:
\begin{blueenv}
\lipsum[4-12]
\end{blueenv}
That's all, folks.
\end{document}
答案1
请注意,你只需要一个\checkmarkpage
因为 tikzmark 名称作为参数传递。
您可以查看 aux 文件,特别是其中\savepointas
的条目,以了解发生了什么。
\documentclass[a4paper,12pt]{book}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
\usepackage{showframe}
\usepackage{everypage}
% This macro checks to see if a given tikzmark is on this page, then selects from three possible responses
\makeatletter
\newcommand{\checkmarkpage}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
\edef\markid{\csname save@pt@#1\endcsname}%
\edef\markpage{\csname save@pg@\markid\endcsname}%
\ifnum\thepage<\markpage\relax #2%
\else
\ifnum\thepage=\markpage\relax #3%
\else #4%
\fi
\fi}%
}
\makeatother
\newcounter{redenvid}
\newcounter{redenvdone}
\newenvironment{redenv}{\par\tikzmark{beginred\theredenvid}\ignorespaces}%
{\par\tikzmark{endred\theredenvid}\stepcounter{redenvid}\ignorespaces}
\newcommand{\drawredenv}{\checkmarkpage{beginred\theredenvdone}{}%
{\begin{tikzpicture}[remember picture,overlay]
\path ({pic cs:beginred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(A);
\checkmarkpage{endred\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:endred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
\end{tikzpicture}}%
{\begin{tikzpicture}[remember picture,overlay]
\coordinate (A) at (current page text area.north west);
\checkmarkpage{endred\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:endred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
\end{tikzpicture}}%
\checkmarkpage{endred\theredenvdone}{}%
{\stepcounter{redenvdone}\drawredenv}%
{}% this should not happen
}
\AddEverypageHook{\drawredenv}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcounter{blueenvid}
\newcounter{blueenvdone}
\newenvironment{blueenv}{\par\tikzmark{beginblue\theblueenvid}\ignorespaces}%
{\par\tikzmark{endblue\theblueenvid}\stepcounter{blueenvid}\ignorespaces}
\newcommand{\drawblueenv}{\checkmarkpage{beginblue\theblueenvdone}{}%
{\begin{tikzpicture}[remember picture,overlay]
\path ({pic cs:beginblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(C);
\checkmarkpage{endblue\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:endblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
\end{tikzpicture}}%
{\begin{tikzpicture}[remember picture,overlay]
\coordinate (C) at (current page text area.north west);
\checkmarkpage{endblue\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:endblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
\end{tikzpicture}}%
\checkmarkpage{endblue\theblueenvdone}{}%
{\stepcounter{blueenvdone}\drawblueenv}%
{}% this should not happen
}
\AddEverypageHook{\drawblueenv}
\begin{document}
\newpage
\thispagestyle{empty}
Next line begins the rule for BLUE ENV:
\begin{blueenv}
\lipsum[2]
\end{blueenv}
Line above ends the rule for BLUE ENV.
Two on one page for RED ENV:
\begin{redenv}
\lipsum[3]
\end{redenv}
One on three pages for BLUE ENV:
\begin{blueenv}
\lipsum[4-12]
\end{blueenv}
That's all, folks.
\end{document}
我认为最好在每一页末尾只显示一个 tikzpicture。这样pgfid
每次运行都能提供一致的 s。
\documentclass[a4paper,12pt]{book}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
\usepackage{showframe}
\usepackage{everypage}
% This macro checks to see if a given tikzmark is on this page, then selects from three possible responses
\makeatletter
\newcommand{\checkmarkpage}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
\edef\markid{\csname save@pt@#1\endcsname}%
\edef\markpage{\csname save@pg@\markid\endcsname}%
\ifnum\thepage<\markpage\relax #2%
\else
\ifnum\thepage=\markpage\relax #3%
\else #4%
\fi
\fi}%
}
\makeatother
\newcounter{redenvid}
\newcounter{redenvdone}
\newenvironment{redenv}{\par\tikzmark{beginred\theredenvid}\ignorespaces}%
{\par\tikzmark{endred\theredenvid}\stepcounter{redenvid}\ignorespaces}
\newcommand{\drawredenv}{\checkmarkpage{beginred\theredenvdone}{}%
{\path ({pic cs:beginred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(A);
\checkmarkpage{endred\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:endred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
}%
{\coordinate (A) at (current page text area.north west);
\checkmarkpage{endred\theredenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(B);}%
{\path ({pic cs:endred\theredenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(B);}%
{}% this should not happen
\fill[red] ($(A) + (-.1cm,0pt)$) rectangle ($(B) + (-.9cm,0pt)$);
}%
\checkmarkpage{endred\theredenvdone}{}%
{\stepcounter{redenvdone}\drawredenv}%
{}% this should not happen
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcounter{blueenvid}
\newcounter{blueenvdone}
\newenvironment{blueenv}{\par\tikzmark{beginblue\theblueenvid}\ignorespaces}%
{\par\tikzmark{endblue\theblueenvid}\stepcounter{blueenvid}\ignorespaces}
\newcommand{\drawblueenv}{\checkmarkpage{beginblue\theblueenvdone}{}%
{\path ({pic cs:beginblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(C);
\checkmarkpage{endblue\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:endblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
}%
{\coordinate (C) at (current page text area.north west);
\checkmarkpage{endblue\theblueenvdone}%
{\path (current page text area.south west) ++(0pt,-\dp\strutbox)
coordinate(D);}%
{\path ({pic cs:endblue\theblueenvdone}-| current page text area.west)
++(0pt,\ht\strutbox) coordinate(D);}%
{}% this should not happen
\fill[blue] ($(C) + (-1.0cm,0pt)$) rectangle ($(D) + (-1.8cm,0pt)$);
}%
\checkmarkpage{endblue\theblueenvdone}{}%
{\stepcounter{blueenvdone}\drawblueenv}%
{}% this should not happen
}
\AddEverypageHook{\begin{tikzpicture}[remember picture,overlay]
\drawredenv
\drawblueenv
\end{tikzpicture}}
\begin{document}
\newpage
\thispagestyle{empty}
Next line begins the rule for BLUE ENV:
\begin{blueenv}
\lipsum[2]
\end{blueenv}
Line above ends the rule for BLUE ENV.
Two on one page for RED ENV:
\begin{redenv}
\lipsum[3]
\end{redenv}
One on three pages for BLUE ENV:
\begin{blueenv}
\lipsum[4-12]
\end{blueenv}
That's all, folks.
\end{document}