atbegshi 与 lineno:检索给定页面的行数

atbegshi 与 lineno:检索给定页面的行数

我试图更好地理解要做什么atbegshilineno或完成什么)。在下面的例子中,我将当前行号添加到 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

生成的四页文档的前两页:

第 1 页:89 (1-89) 第 2 页:88 (90-177)

相关内容