我试图更好地理解要做什么atbegshi
(lineno
或完成什么)。在下面的例子中,我将当前行号添加到 shipout,并努力完全理解发生了什么。
\documentclass{article}
\usepackage{lipsum}
\usepackage{atbegshi}
\usepackage[pagewise]{lineno}
\usepackage{tikz} % only for illustration
\begin{document}
\linenumbers
\AtBeginShipout{\AtBeginShipoutAddToBox{\fbox{\arabic{linenumber}}
\tikz[overlay,remember picture]{\draw[thick,blue,latex-](lastline)--++(-2cm,0);}}}
\renewcommand\thelinenumber{\arabic{linenumber}%
\tikz[overlay,remember picture]{\node(lastline){\strut};}}
\begin{itemize}
\item \lipsum*[1]
\item \lipsum*[2]
\item \lipsum*[3]
\item \lipsum*[4]
\item \lipsum*[5]
\item \lipsum*[6]
\item \lipsum*[7]
\item \lipsum*[8]
\item \lipsum*[9]
\item \lipsum*[10]
\item \lipsum*[11]
\item \lipsum*[12]
\item \lipsum*[13]
\end{itemize}
\lipsum[1-10]
\end{document}
在第一页上,我得到的结果为 44,这大了 1,而在第二页上我得到的结果为 87,这是正确的。我大概明白了为什么会发生这种情况:在第一种情况下,TeX 稍后决定将最后一行移到下一页,但在第二种情况下,没有必要这样做。现在我想知道是否有办法解决这个问题。(尽管有这个pagewise
选项,但行数仍在不断增加,这也有点令人惊讶,如果有人知道一个优雅的修复方法,我会很想了解,因为目前我只能想到一个丑陋的修复方法。)
此外,我用 Ti 定义节点钾Z. 我知道这是不好的做法,所以我继续覆盖这些节点,并希望使用 标记最后一行(数字)\AtBeginShipout
。但是,我得到了一个疯狂的模式,最后一行或第一行都被标记了。最有可能的原因与上述相同,并且一旦问题的第一部分得到解决,问题可能就消失了。
这有什么好处呢?除了其他好处之外,人们最终可能会回答这个问题,但我确实希望通过这种方式来访问由文本填充的区域。
答案1
当异步输出例程被调用时,您将获得处于活动状态的行号。因此,如果在 shipout 例程中询问计数器的值 ( ),则计数器的值linenumber
不可靠。\AtBeginShipout
由于选项pagewise
,包lineno
必须知道每页和每列有多少行。它使用与页面引用相同的技巧。数据存储在文件中.aux
并在下一次 LaTeX 运行中读取。
包lineno
维护着文件中数据的链表.aux
。每列都有一个条目,头部是\LN@Pfirst
。下面示例的数据有两列:
\LN@Pfirst -> \nextLN \LN@P0C1
\LN@P0C1 -> \lastLN {44}\firstLN {0}\pageLN {0}{1}{0}\nextLN \LN@P0C2
\LN@P0C2 -> \lastLN {88}\firstLN {45}\pageLN {0}{2}{0}\nextLN \LN@P1C1
\LN@P1C1 -> \lastLN {132}\firstLN {89}\pageLN {1}{1}{89}\nextLN \LN@P1C2
- 宏名由从零开始的页码和从一开始的列号组成(
\LN@P3C2
是第 4 页和第 2 列的宏)。 \lastLN
是该列最后一个从零开始的行号。\firstLN
是该列的第一个从零开始的行号。\pageLN
存储三个数据,即从零开始的页号、从一开始的列号和页面第一行的从零开始的行号。\nextLN
是指向下一列的指针。
下面的例子使用这些数据来修复问题的例子。它也支持多列。
\documentclass[twocolumn]{article}
\usepackage[columnsep=1cm]{geometry}
\usepackage{microtype}
\usepackage{lipsum}
\usepackage{atbegshi}
\usepackage[pagewise]{lineno}
\usepackage{tikz} % only for illustration
\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};%
}%
\global\expandafter\let\csname Anchor\LastLineNumber\endcsname\@empty
\fi
\fi
}
\makeatother
\begin{document}
\linenumbers
\begin{itemize}
\item \lipsum*[3]
\item \lipsum*[4]
\item \lipsum*[5]
\item \lipsum*[6]
\item \lipsum*[7]
\item \lipsum*[8]
\item \lipsum*[9]
\item \lipsum*[10]
\item \lipsum*[11]
\item \lipsum*[12]
\item \lipsum*[13]
\item \lipsum*[14]
\end{itemize}
\lipsum[1-10]
\end{document}
TikZ 部分比较棘手:只有知道行号(第二次运行)时,才能设置页面最后一行的标签。全局宏会记住节点实际上放在页面上,以避免箭头被绘制到未知节点。
使用包的内部宏lineno
。使用的版本是:
Package: lineno 2005/11/02 line numbers on paragraphs v4.41
生成的四页文档的前两页: