我正在编写(贡献)一个 LuaLaTeX 包,其中使用 Lua 函数生成插入 LaTeX 文档中的图像。
我们需要的信息之一是当前页码,以确定我们是在奇数页还是偶数页(我知道这不是那么简单,而且我知道一些超出范围的策略\thepage
)。当我们仍在 LaTeX 部分时,我们设置了一个 Lua 变量,到目前为止,这效果很好。
然而,现在事实证明,我们创建的图像序列可能分布在几页上,我们确实想反映这一点,因为我们的图像在奇数页和偶数页上的表现可能有所不同。
基本上,我们有一系列
tex.print('\\includegraphics{something}\\par')
语句,在一个 Lua 函数内循环执行。
现在的问题是:有没有办法直接检测两个这样的图形之间的页面变化或者在这样的循环内重复检索当前页面?
我发现的所有用于确定当前奇数或偶数状态的解决方案都在 LaTeX 本身中。我知道如何使用\directlua
来检索用于 LaTeX 的值,但有没有办法做相反的事情 - 从 LUa 中检索 LaTeX 值?
编辑:回应 TeXnician 的评论和回答:当我修改示例代码以产生段落重复时,页码计数器似乎不会更新在一个 Lua 块内:
\documentclass{article}
\newcommand\printluapage{%
\directlua{for i = 1, 60 do tex.print(tex.count['c@page'])
tex.print([[\par]]) end}
}
\begin{document}
\printluapage
New command
\printluapage
New command
\printluapage
\end{document}
仅当每次调用时才会更新页码\printluapage
。
答案1
您几乎永远无法从主文档中准确引用页面计数器,只有在输出例程中才能准确知道要输出的页面。Luatex 不会改变 TeX 页面输出方式的基本模型,因此 luatex 中也是如此。
在你的 lua 循环中你可以使用
mcount=mycount+1
tex.print('\\includegraphics{something}\\label{graphic-' .. mycount .. '}\\par')
然后每个图像都会有一个\label
与之关联的,下次运行时您可以选择\pageref{graphic-5}
(从 Lua 或 TeX)它会告诉您第 5 个图形最终出现在哪一页。
完整示例:
\documentclass{article}
\directlua{j=0}
\newcommand\printluapage{%
\directlua{
for i = 1, 60 do
j=j+1
tex.print('\string\\pageref{foo' .. j .. '}\string\\label{foo' .. j .. '}')
tex.print([[\par]]) end}%
}
\begin{document}
\printluapage
New command
\printluapage
New command
\printluapage
\end{document}
答案2
这是一个非常基本的解决方案,它仅读取 Lua 中 LaTeX 计数器页面的值(打印是为了测试,但 tex.count 语句也可以在其他地方使用)。
\documentclass{article}
\newcommand\printluapage{%
\directlua{tex.print(tex.count['c@page'])}
}
\begin{document}
\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage\printluapage\clearpage
\end{document}
答案3
这里有两个复杂因素。
首先,每次调用都会\directlua
立即运行,因此如果你想要 TeX 的常规处理,你需要将控制权交给 TeX(并使用协程或其他方法)。因此,当你有
\directlua{for i = 1, 60 do tex.print(tex.count['c@page'])
tex.print([[\par]]) end}
}
就像问题中提到的那样,这只是将 60 个实例42
(或页码)放在\par
TeX 的输入堆栈上,以便 TeX 在整个调用完成后接下来读取\directlua
。(这不会导致 TeX\par
立即处理每个和其余的排版,即使在循环结束之前也是如此。)您的确切问题已在以下问题中讨论并提供了解决方案:在 LuaTeX 中并发交叉执行 Lua 和 TeX。
其次,TeX 只是将项目附加到其垂直列表中,直到不可避免地出现分页符(例如,没有办法将迄今为止收集的所有材料放在一页上),因此添加材料时页面计数器的值不一定是它最终所在的页面(例如,它可能最终位于下一页)。页码只有在箱子运出时才最终确定。有一些技巧可以处理这个事实(例如,让您的 Lua 代码在运出期间运行?),但我不知道这些技巧;也许其他人会回答。:-)
您可以使用类似\pagetotal
(或来自 Lua 的tex.pagetotal
)的数量来获得一些近似结果,这些结果显示了已添加到当前页面的材料数量。这需要注意:上面的第一点是关于让 TeX 完成其工作(将您的 Lua 代码拆分到不同的调用中\directlua
),此外,您可能需要处理可收缩和可拉伸胶水,并考虑它们。
答案4
交错的问题是部分地在 ConTeXt 中已解决。您可以从 Lua 中访问页码,并且它会在某个时候更新,但 David 在他的评论持续存在。
\starttext
\startluacode
for i = 1, 60 do
context(context.currentpage)
context.par()
end
\stopluacode
\stoptext