我一直在使用以下技巧来获取段落的内容。它在大多数情况下都有效,但对于内部扩展的宏(例如\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}