![自动检测最后一段并传递给宏](https://linux22.com/image/387550/%E8%87%AA%E5%8A%A8%E6%A3%80%E6%B5%8B%E6%9C%80%E5%90%8E%E4%B8%80%E6%AE%B5%E5%B9%B6%E4%BC%A0%E9%80%92%E7%BB%99%E5%AE%8F.png)
下面的 MWE 产生了所需的结果:
通过将\ProcessLastPara{}
期望应用于\parshape
给定的(最后的) 段落。
问题:
下面的 MWE 要求我手动识别两个都最后一段的开始和结束,以便它可以传递给\ProcessLastPara{}
宏。
是否可以
\ProcessLastPara{<text>}
通过简单地标识最后一段的开头来实现的效果。也就是说,我是否可以将对的调用更改\SetMyText
为以下形式:\SetMyText{% Other Text... \LastParaBeginsHere Last Para Text% }%
这样就
\LastParaBeginsHere
可以调用\ProcessLastPara{Last Para Text}
。这需要进行一些错误检查以确保这
\LastParaBeginsHere
确实是 定义的最后一段\SetMyText
。是否可以自动检测最后一段的开始和结束位置,这样我就不需要手动调用
\ProcessLastPara{}
和识别最后一段的文本了?
笔记:
- 这需要在文本排版之前在宏中定义的情况才能起作用。
- 的解决方案
\def\LastParaBeginsHere{\LastParShape}
不起作用,因为我需要处理最后一段文本来确定\parshape
要应用的合适内容。也就是说,这是一个两步过程,这里不包含其细节以简化测试用例。
代码:
\documentclass{article}
\usepackage[paperwidth=15cm]{geometry}
\makeatletter
\newcommand{\@MyText}{}
\newcommand{\SetMyText}[1]{\def\@MyText{#1}}%
\newcommand*{\OutputMyText}{\@MyText}%
\makeatother
\newcommand*{\LastParShape}{%
\parshape 5
0.10\hsize 0.80\hsize
0.15\hsize 0.70\hsize
0.20\hsize 0.60\hsize
0.25\hsize 0.50\hsize
0.30\hsize 0.40\hsize
}%
\newcommand*{\ProcessLastPara}[1]{%
\LastParShape
#1}%
\begin{document}
\SetMyText{%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
\ProcessLastPara{%
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.}%
}%
%% ----------------
\OutputMyText%
\end{document}
答案1
\documentclass{article}
\usepackage[paperwidth=15cm]{geometry}
\makeatletter
\newcommand{\@MyText}{}
\newcommand{\SetMyText}[1]{\def\@MyText{#1\LastParShape\par}}%
\newcommand*{\OutputMyText}{\@MyText}%
\makeatother
\newcommand*{\LastParShape}{%
\parshape 5
\dimexpr0.10\hsize-\parindent\relax \dimexpr0.80\hsize+\parindent\relax
0.15\hsize 0.70\hsize
0.20\hsize 0.60\hsize
0.25\hsize 0.50\hsize
0.30\hsize 0.40\hsize
}%
\begin{document}
\SetMyText{%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
}%
%% ----------------
\OutputMyText%
\end{document}
答案2
使用起来非常简单expl3
:收集文本,在 处将其拆分\par
,然后分离最后一段并单独排版。
\documentclass{article}
\usepackage[paperwidth=15cm]{geometry}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\SetMyText}{s+m}
{
\IfBooleanTF{#1}
{
\seq_set_split:NnV \l_peter_mytext_seq { \par } #2
}
{
\seq_set_split:Nnn \l_peter_mytext_seq { \par } { #2 }
}
}
\cs_generate_variant:Nn \seq_set_split:Nnn { NnV }
\seq_new:N \l_peter_mytext_seq
\tl_new:N \l_peter_mytext_tl
\NewDocumentCommand{\OutputMyText}{}
{
\seq_pop_right:NN \l_peter_mytext_seq \l_peter_mytext_tl
\seq_use:Nn \l_peter_mytext_seq { \par } \par
\LastParShape \l_peter_mytext_tl
}
\ExplSyntaxOff
\newcommand*{\LastParShape}{%
\parshape 5
0.10\hsize 0.80\hsize
0.15\hsize 0.70\hsize
0.20\hsize 0.60\hsize
0.25\hsize 0.50\hsize
0.30\hsize 0.40\hsize
}
\begin{document}
\SetMyText{
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
}
\OutputMyText
\end{document}