有没有办法标记所有已自动换行的行(即 LuaTeX 决定需要换行的地方)?类似\localrightbox
但仅在某些文本已换行到下一行的行末有效?在下面的 MWE 中,钩形箭头不应从第一段的最后一行开始出现(因为第一段在该行结束,因为第二段只需要一行,并且第三段在每一行的末尾都有硬换行符)。
\documentclass[12pt]{report}
\usepackage{fullpage}
\usepackage{latexsym}
\newenvironment{speech}%
{%begin
\Large
\setlength{\parindent}{-1cm}
\setlength{\leftmargin}{1cm}
\localrightbox{$\hookleftarrow$}
}
{%end
}
\begin{document}
\begin{speech}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed faucibus, sem vel suscipit eleifend, ipsum dolor tempus nunc, ut iaculis nibh arcu vitae tortor.
Pellentesque a efficitur lectus, eget sagittis lorem.
Fusce vestibulum feugiat nibh, pulvinar convallis eros sagittis ac.
Pellentesque aliquam arcu a augue malesuada, sit amet eleifend orci vulputate.
Sed nibh dolor, commodo vel risus quis, elementum consequat dui.
Pellentesque eu neque eleifend, tincidunt mauris id, ultricies odio.
Aenean ac nisi congue, mollis leo a, cursus dolor.
Aenean non justo felis.\\
Cras interdum quam eu metus imperdiet ultricies.\\
Fusce finibus pellentesque volutpat.\\
Praesent id lacus eget dui ullamcorper finibus nec nec urna.\\
Quisque vel vestibulum quam.\\
Lorem ipsum dolor sit amet, consectetur adipiscing elit.\\
Mauris vel nisl eros.\\
\end{speech}
\end{document}
答案1
我想到了一个与 相关的解决方案post_linebreak_filter
。代码循环遍历段落中的所有行,除了最后一行,因为最后一行不能被中断(否则它就不是最后一行)。对于每一行,我都会迭代该行内的所有惩罚。如果存在子类型为 0(用户惩罚)的惩罚,则表示用户手动插入了惩罚,就像 的情况一样\\
。那么我们只需要检查惩罚的值是否为-10000
,因此是强制换行。如果不是这种情况,则意味着没有强制换行,TeX 自己断了行。因此我们可以在行尾插入箭头。
\documentclass[12pt]{report}
\usepackage{fullpage}
\usepackage{amssymb}
\newenvironment{speech}%
{%begin
\Large
\setlength{\parindent}{-1cm}%
\setlength{\leftmargin}{1cm}%
\directlua{luatexbase.add_to_callback("post_linebreak_filter",
mark_small_glue_lines, "speech")}%
}
{%
\par % trigger the last post_linebreak_filter before disabling it
\directlua{luatexbase.remove_from_callback("post_linebreak_filter", "speech")}%
}
\newbox\hookleftarrowbox
\setbox\hookleftarrowbox=\hbox{$\hookleftarrow$}
\directlua{
mark_small_glue_lines = function(head)
local last_line = nil
for line in node.traverse_id(node.id("hlist"), head) do
if last_line then
local has_userpenalty = false
for pen in node.traverse_id(node.id("penalty"), last_line.list) do
if not has_userpenalty then
has_userpenalty = (pen.subtype == 0 and pen.penalty == -10000)
else
break
end
end
if not has_userpenalty then
node.insert_after(last_line.list, node.tail(last_line.list),
node.copy(tex.box.hookleftarrowbox))
end
end
last_line = line
end
return head
end
}
\begin{document}
\begin{speech}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed faucibus, sem vel suscipit eleifend, ipsum dolor tempus nunc, ut iaculis nibh
arcu vitae tortor.
Pellentesque a efficitur lectus, eget sagittis lorem.
Fusce vestibulum feugiat nibh, pulvinar convallis eros sagittis ac.
Pellentesque aliquam arcu a augue malesuada, sit amet eleifend orci vulputate.
Sed nibh dolor, commodo vel risus quis, elementum consequat dui.
Pellentesque eu neque eleifend, tincidunt mauris id, ultricies odio.
Aenean ac nisi congue, mollis leo a, cursus dolor.
Aenean non justo felis.\\
Cras interdum quam eu metus imperdiet ultricies.\\
Fusce finibus pellentesque volutpat.\\
Praesent id lacus eget dui ullamcorper finibus nec nec urna.\\
Quisque vel vestibulum quam.\\
Lorem ipsum dolor sit amet, consectetur adipiscing elit.\\
Mauris vel nisl eros.
\end{speech}
\end{document}