编辑:我添加了 luatex 解决方案作为我的问题的答案。
我有一个\vbox
计划在其中排版长篇材料(长诗)的宏,其排版方式略有不同。有一个特殊的突出显示宏,它在某些特殊节(以 结尾\par
)的末尾放置 3 个红色星号。但是,如果特殊节(每个节的行数可以不同)的结尾位于诗歌顶部某个数字(假设为 100)的倍数处,那么我们会做一些不同的事情(例如添加额外的换行符或其他标记,例如彩色规则),而不是放置这些星号。
我设想的方法是,如果我能找到并将前一段最后一行的行号传递给打印特殊标记的宏,那么这种方法就可以奏效。我还没有遇到任何宏来知道即将排版的文本中的行号。从我对 tex 的一点了解来看,鉴于 tex 引擎在处理段落结束时将段落的行放在垂直列表中,似乎有办法在下一段的开头知道这一点?理想情况下,我想要纯 tex 解决方案。如果在纯 tex 中无法实现这一点,那么基于换行符过滤器的 luatex 解决方案会很棒(从名称来看,假设它不会\vbox
再次重新排版整个内容?)
推论 1:我猜在纯文本中,在段落排版时无法获取段落内行的行号,但是使用 luatex 的换行符过滤器可以吗?如果在 luatex 中可以,那么对于 luatex 解决方案来说,最好有一个可以在任何行上运行的宏,而不仅仅是知道上一个段落最后一行的行号。
% Macro that returns line number from top of vbox
\currentlineno
% Macro that consumes this line number
\myspecialasterisk{\currentlineno} % I can write this, am looking for the definition of \currentlineno
答案1
我并不是说这是您问题的完整解决方案,但您可以先尝试以下代码:
\newcount\globlines
\hsize=10cm
\def\text{fghs sdsdvjd gdj dhad dhd fda dfgdfd dhd dfshk sdhsds
fghs sdsdvjd gdj dhad dhd fda dfgdfd dhd dfshk sdhsds
fghs sdsdvjd gdj dhad dhd fda dfgdfd dhd dfshk sdhsds}
\def\par{\ifhmode\endgraf \global\advance\globlines by\prevgraf \fi}
\def\showlines{\vskip-\baselineskip \llap{\the\globlines\qquad}}
\text \par \text \par
\showlines
\text \par \text \par \text\text \par
\showlines
\bye
答案2
这是我的 luatex 解决方案,它似乎在我所有的测试中都有效。
% Post line break filter to find number of lines from a startpoint
\directlua{
% Global linecount, usage:
% Set linecount to a start value at whatever place you want to start counting lines from (like beginning of \vbox):
% \directlua{linecount=0}
% Get value within luatexcode (linecount valid only after \par, gets updated upon every new \par, till then it holds previous value)
% \directlua{tex.sprint(linecount)}
linecount=0 % global variable (change name if you think there can be conflict with other lualatex packages)
function my_post_lb_filter(head,groupcode)
local HLIST = node.id("hlist") % node.id for a line of text in vertical list
for n in node.traverse(head) do % For every subnode within node head
if n.id==HLIST then % If n is a line, increment linecount
linecount=linecount+1
end
end
return head
end
luatexbase.add_to_callback('post_linebreak_filter', my_post_lb_filter, 'Increment a count at eol to track number of lines')
}
% Set start value to 0 at beginning
\directlua{linecount=0}
% Required macro that works when used right after \par
\newcommand{\currentlineno}{\directlua{tex.sprint(linecount)}}
注意:如果您是 luatex 专家,请留下代码审查意见。