如何获取段落内容

如何获取段落内容

我一直在使用以下技巧来获取段落的内容。它在大多数情况下都有效,但对于内部扩展的宏(例如\lipsum\end{document}或)无效。有办法解决这个问题吗?\end{minipage}\par

\documentclass{article}
\usepackage{lipsum}

\newcounter{count}

\def\mypar#1\par{\stepcounter{count}\thecount(#1)\addtocounter{count}{-1}\par}


\begin{document}
\everypar{\mypar}
This is a test.

\lipsum[1]
This is a new paragraph.

\end{document}

结果

这也表明当在内部扩展时(递归),另一个\mypar会被执行。\lipsum\mypar


如果我将应用程序转换为宏而不是环境,则无法检测环境结束的问题就不再存在。换句话说,我可以忍受它。

我相信我可以通过将其展开在 a 中并使用它增加计数器来检测\par宏内部是否存在。如果我将输入数据存储为标记列表,则可以添加标记而不展开它们。因此,只需一次添加一个标记,直到展开 a 即可。\savebox\everypar\par

当然,这只在宏\par结尾有一个单数时才有效。像以\item一个\par开头的宏不能与 一起使用\parshape(除非修改)。

答案1

你想使用\lipsum*那个没有问题\par

\documentclass{article}
\usepackage{lipsum}

\newcounter{count}

\def\mypar#1\par{\stepcounter{count}\thecount(#1\unskip\unskip)\addtocounter{count}{-1}\par}


\begin{document}
\everypar{\mypar}

This is a test.

\lipsum*[1]

This is a new paragraph.

\end{document}

在此处输入图片描述

如果您希望观看\mypar决赛,\par\lipsum您就没那么幸运了。

答案2

我没有尝试解析源代码,而是决定将每个段落放入单独的框中。此外,我将问题简化为环境 (\BODY}) 的内容,而不是整个文档。

通过\pagebreak在每个段落末尾添加一个,我可以强制\vsplit每次删除 1 个段落并存储高度。我使用正常惩罚和这些高度重复该过程。

\documentclass{article}
\usepackage{environ}
\usepackage{lipsum}

\newsavebox{\mybox}
\newcounter{total}
\newcounter{count}
\renewcommand{\thecount}{\Roman{count}}

\NewEnviron{test}{%
  \let\oldpar=\par
  \def\par{\oldpar\pagebreak}%
  \everypar{\stepcounter{total}}%
  \setbox\mybox=\vbox{\BODY}%
  \let\par=\oldpar
  \everypar{\relax}
  \loop\ifnum\value{count}<\value{total}\relax
    \stepcounter{count}%
    \dimen0=\ht\mybox
    \setbox0=\vsplit\mybox to \dimen0
    \advance\dimen0 by -\ht\mybox
    \expandafter\xdef\csname testht\thecount\endcsname{\the\dimen0}%
  \repeat
  \global\setbox\mybox=\vbox{\BODY}%
}

\begin{document}
\parindent=0pt
\begin{test}
This is a test.

\lipsum[1]
This is a new paragraph.
\end{test}
\setcounter{count}{0}%
\loop\ifnum\value{count}<\value{total}\relax
  \stepcounter{count}%
  \arabic{count}\par
  \dimen0=\csname testht\thecount\endcsname\relax
  \setbox0=\vsplit\mybox to \dimen0
  \usebox0
\repeat
\end{document}

演示

相关内容