我知道可以将 TikZ 节点放置在相对于页面指定的位置,如下所示在 TikZ 中相对于页面的定位。
我还知道可以获得相对于边距的节点,例如将 tikz 节点对齐到页面底部(不是纸张;包括边距)。
但是,我想将 tikz 节点放置在页面底部或页边距之外,而是放置在使用时文本块实际填充的最低位置raggedbottom
(因此据我所知,从页边距计算并不是很有帮助)。更准确地说,我如何使用 为 tikz 提供当前页面中最后一行排版基线的 y 坐标raggedbottom
?由于我想用 来做的事情,用 手动指定最后一行tikzmark
并不是一个可行的选择(据我所知),所以我想指定的是最后一行的坐标,无论排版时它是什么。
为了获得 MWE,我提供以下内容,这些内容可能很方便,但实际上并没有尝试解决问题,因为我对此感到困惑:
\documentclass{article}
\usepackage{tikz}
\usepackage[paperheight=8cm,paperwidth=12cm]{geometry}
\usepackage[defaultlines=4,all]{nowidow}
\usepackage{blindtext}
\raggedbottom
\begin{document}
\thispagestyle{empty}
\begin{tikzpicture}[remember picture,overlay]
\node[anchor=south] at (current page.south) {I am south-bound...};
\draw[thick] (current page.south west) rectangle (current page.north east);
\end{tikzpicture}
\blindtext
\end{document}
更新:我最初试图让问题更抽象,但正如评论中所建议的那样,也许更多的背景信息可能会有所帮助。我试图完善 Gonzalo Medina 的解决方案用波浪线标记(突出显示)某个段落(\item{…}),以便稍后注意到raggedbottom
上下文。在横线通过分页符绘制的情况下,第一页中该部分的 y 底部坐标计算为y of current page.center -0.5\textheight
,因此如果页面较短,则raggedbottom
线会延伸得太远。以下代码略微改编自 Gonzalo Medina 的答案,说明了这个问题:
\documentclass{article}
\usepackage{refcount}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc}
\usepackage{lipsum}
\usepackage[defaultlines=6,all]{nowidow}
\raggedbottom
\newcounter{tmp}
\newcommand\tikzmark[1]{%
\tikz[overlay,remember picture] \node (#1) {};}
\newcommand\Startsquiggly{%
\stepcounter{tmp}%
\tikzmark{a}\label{a\thetmp}%
\ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp} \else
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
( $ (\x3,\y1) + (.55\textwidth,0) $ ) -- ( $ (\x3,\y3) + (0.55\textwidth,-0.5\textheight) $ );
\end{tikzpicture}%
\fi%
}
\newcommand\Endsquiggly{%
\tikzmark{b}\label{b\thetmp}
\ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp}
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
( $ (\x3,\y1) + (.55\textwidth,0) $ ) -- ( $ (\x3,\y2) + (.55\textwidth,0) $ );
\end{tikzpicture}%
\else
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
( $ (\x3,\y3) + (.55\textwidth,.5\textheight) $ ) -- ( $ (\x3,\y2) + (.55\textwidth,0) $ );
\end{tikzpicture}%
\fi
}
\newcommand\Squ[1]{\Startsquiggly#1\Endsquiggly}
\begin{document}
\begin{itemize}
\item \lipsum*[1]
\item \Startsquiggly\lipsum*[1]\Endsquiggly
\item \lipsum*[1]
\item \Startsquiggly\lipsum*[1]\Endsquiggly
\end{itemize}
\end{document}
过度拉伸的线条如下所示:
欢迎提出解决最初一般问题的想法,或适合具体情况的替代方法。
答案1
这是一份非常初步的答案,有许多打印件。实际上,它只是对我们的聊天。这其实不是我的答案,所有棘手的问题都被 Heiko Oberdiek 在他的惊人的答案。基本思路是利用 lineno 包,它不会在空行上放置行号。Heiko 能够在最后一行上放置一个 tikz 节点。这为我们提供了最后一行的垂直位置。其余部分是简单的模数异常,因为似乎违反了因果关系的 TeX 输出程序。
\documentclass{article}
\usepackage{refcount}
\usepackage{tikz,tikzpagenodes}
\usetikzlibrary{decorations.pathmorphing,calc}
\usepackage{lipsum}
\usepackage[defaultlines=6,all]{nowidow}
\raggedbottom
\usepackage{atbegshi}
\usepackage[pagewise]{lineno}
\newcommand{\Later}{}
\makeatletter
\newcount\AbsolutePageNumber % zero-based
\AbsolutePageNumber=\z@
\newcommand*{\UnknownLineNumber}{??}
\let\FirstLineNumber\UnknownLineNumber
\let\LastLineNumber\UnknownLineNumber
\newcommand*{\GetLineNumbers}{%
\begingroup
\let\nextLN\relax
\def\pageLN##1##2##3{%
\ifnum##1=\AbsolutePageNumber
\xdef\FirstLineNumber{\the\numexpr##3+1}%
\global\let\LastLineNumber\@LastLineNumber
\fi
\ifnum##1>\AbsolutePageNumber
\let\nextLN\relax
\fi
}%
\let\firstLN\@gobble
\def\lastLN##1{%
\def\@LastLineNumber{\the\numexpr##1+1}%
}%
\LN@Pfirst
\endgroup
}
\AtBeginShipout{%
\GetLineNumbers
\AtBeginShipoutAddToBox{%
\ifx\FirstLineNumber\UnknownLineNumber
\else
% \fbox{%
% \the\numexpr\LastLineNumber + 1 - \FirstLineNumber\relax
% ~(\FirstLineNumber--\LastLineNumber)%
% }%
\fi
\expandafter\ifx\csname Anchor\LastLineNumber\endcsname\relax
\else
% \tikz[overlay,remember picture]{%
% \draw[thick,blue,latex-](ln\LastLineNumber)--++(-2cm,0);%
% }%
\fi
}%
\global\advance\AbsolutePageNumber\@ne
}
\renewcommand\thelinenumber{%
%\arabic{linenumber}%
\GetLineNumbers
\ifx\LastLineNumber\UnknownLineNumber
\else
\ifnum\LastLineNumber=\numexpr\FirstLineNumber+\value{linenumber}-1\relax
\tikz[overlay,remember picture]{%
\node(ln\LastLineNumber){\strut};%
}%
\typeout{done\space with\space ln\LastLineNumber}
\Later
\renewcommand{\Later}{}
\global\expandafter\let\csname Anchor\LastLineNumber\endcsname\@empty
\fi
\fi
}
\makeatother
\newcounter{tmp}
\newcommand\tikzmark[1]{%
\tikz[overlay,remember picture] \node (#1) {};}
\newcommand\Startsquiggly{%
\stepcounter{tmp}%
\typeout{executing\space Startsquiggly\space\thetmp}
\tikzmark{a}\label{a\thetmp}%
\ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp} \else
\typeout{\getpagerefnumber{a\thetmp},\getpagerefnumber{b\thetmp}}
\GetLineNumbers
\xdef\NoWay{0}
% here we define a command that will be executed at page shipout
\renewcommand{\Later}{\typeout{executing\space Later\space \thetmp\space on \space page\space\thepage}
\ifnum\NoWay=0
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
([xshift=3mm]current page text area.east |- a.north)
--([xshift=3mm]current page text area.east |- ln\LastLineNumber);
\end{tikzpicture}
\fi
\xdef\NoWay{1}
}
% \begin{tikzpicture}[overlay, remember picture]
% \draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
% let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
% ( $ (\x3,\y1) + (.55\textwidth,0) $ ) -- ( $ (\x3,\y3) + (0.55\textwidth,-0.5\textheight) $ );
% \end{tikzpicture}%
\fi%
}
\newcommand\Endsquiggly{%
\tikzmark{b}\label{b\thetmp}
\ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp}
\typeout{endcase1:\getpagerefnumber{a\thetmp},\getpagerefnumber{b\thetmp}}
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
([xshift=3mm]current page text area.east |- a.north)
--([xshift=3mm]current page text area.east |- b.south);
% let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
% ( $ (\x3,\y1) + (.55\textwidth,0) $ ) -- ( $ (\x3,\y2) + (.55\textwidth,0) $ );
\end{tikzpicture}%
\else
\typeout{endcase2:\getpagerefnumber{a\thetmp},\getpagerefnumber{b\thetmp}}
\begin{tikzpicture}[overlay, remember picture]
\draw [decoration={coil,aspect=0},decorate,ultra thick,gray]
([xshift=3mm]current page text area.north east)
--([xshift=3mm]current page text area.east |- b.south);
% let \p1 = (a.north), \p2 = (b), \p3 = (current page.center) in
% ( $ (\x3,\y3) + (.55\textwidth,.5\textheight) $ ) -- ( $ (\x3,\y2) + (.55\textwidth,0) $ );
\end{tikzpicture}%
\fi
}
\newcommand\Squ[1]{\Startsquiggly#1\Endsquiggly}
\begin{document}
\linenumbers
\begin{itemize}
\item \lipsum*[1]
\item \Startsquiggly\lipsum*[1]\Endsquiggly
\item \lipsum*[1]
\item \Startsquiggly\lipsum*[1]\Endsquiggly
\end{itemize}
\end{document}
请注意,我使用了 tikzpagenodes 包来绘制波浪线。因此,线条略有偏移,但您可以通过操作来重新调整水平位置[xshift=3mm]
。我很乐意帮助您进行风格改进。