我正在尝试调试一些代码,当一切都是 LTR 时这些代码可以工作,当一切都是 RTL 时也可以工作,但是当主文档方向与我的某个环境内的方向不同时就会失败。
我已经设法将我的代码简化为相当简单的代码,但我承认,从这个问题上看,我为什么要这样做并不清楚……此外,其行为与我更复杂的现实世界代码略有不同,所以我可能仍然错过了一些东西。
问题
- 在下面的代码中,我用来
\predisplaysize
测量段落最后一行的长度。 - 当您执行此操作时,您需要从显示数学内部抓取
\prevgraf
,以便随后重置它以保持间距。 - 在下面的代码中,
\prevgraf
在每个列表环境的末尾都会重置 4 次。但它的值取决于我是在第一个列表环境之前还是在列表环境的开头更改语言。在下面的 MWE 中,每次连续调用 都会\measureline
给出\prevgraf
1、1、1,然后是 0。
这是为什么?我怎样才能获得一致的行为?
\setlanguage{ukenglish}
我知道这个例子很奇怪,但是为什么根据我之前调用listenva
而不是里面的第一件事会有区别呢listenva
???
(我想要下面 MWE 中第二个示例的行为。即的\prevgraf
四个调用的模式\measureline
应该是:1、0、1、0。注释掉时您可以看到这一点\babelprovide[import, main]{persian}
,确保开始之前的语言listenva
与里面设置的语言相同listenva
)
我注意到的事情
在环境中调用
\@noparlistfalse
before可以确保在第二次调用时为 0。换句话说,如果我注释掉此行,则对 的四次调用每次都是 1 。\endlist
\listenvb
\prevgraf
\prevgraf
\measureline
当主文档语言为 LTR 并且我的环境将语言设置为 RTL 语言时,也会出现同样的问题。
分组也会影响事物:
这有效:
\listenva \begin{listenvb} Test. \end{listenvb} \endlistenva
但这失败了:
\begingroup \selectlanguage{ukenglish} \begin{listenva} \begin{listenvb} Test. \end{listenvb} \end{listenva} \endgroup
平均能量损失
%! TeX Program = lualatex
\documentclass{article}
\pagestyle{empty}
\usepackage[bidi=basic, layout=lists]{babel}
\babelprovide[import, main]{persian}
\babelprovide[import]{ukenglish}
\newdimen\linelen
\newcommand{\measureline}{%
\abovedisplayshortskip -\baselineskip
\abovedisplayskip\abovedisplayshortskip
\belowdisplayshortskip 0pt
\belowdisplayskip\belowdisplayshortskip
$$
\ifdim\predisplaysize>0pt
\global\linelen\dimexpr\predisplaysize-2em
\fi
\global\def\resetspacing{%
\predisplaysize\the\predisplaysize
\prevgraf\the\prevgraf
}%
$$
\resetspacing
\ifdim\linelen>0pt
\vskip-\baselineskip
\fi
}
\newcommand{\nolistspaces}{%
\leftmargin 0pt
\rightmargin 0pt
\itemindent 0pt
\partopsep 0pt
\parsep 0pt
\topsep 0pt
}
\newenvironment{listenva}{%
\selectlanguage{ukenglish}%
\list{}{\nolistspaces}%
\item\relax
}{%
\measureline
\strut\hskip\linelen+++%
\csname @noparlistfalse\endcsname
\endlist
}
\newenvironment{listenvb}{%
\list{}{\nolistspaces}%
\item\relax
}{%
\measureline
\csname @noparlistfalse\endcsname
\endlist
}
\begin{document}
\begin{listenva}
\begin{listenvb}
Test.
\end{listenvb}
\end{listenva}
\selectlanguage{ukenglish}
\begin{listenva}
\begin{listenvb}
Test.
\end{listenvb}
\end{listenva}
\end{document}
我得到的输出是错误的
期望输出
答案1
考虑以下
\showboxdepth\maxdimen\showboxbreadth\maxdimen
\tracingonline1\tracingoutput1
\everypar{\setbox0=\lastbox}
{%\textdirection=0
$$
$$\par}
\bye
输出结果
\vbox(667.20255+0.0)x469.75499, direction TLT
.\vbox(0.0+0.0)x469.75499, glue set 14.0fil, direction TLT
..\glue -22.5
..\hbox(8.5+0.0)x469.75499, glue set 469.755fil, direction TLT
...\vbox(8.5+0.0)x0.0, direction TLT
...\glue 0.0 plus 1.0fil
..\glue 0.0 plus 1.0fil minus 1.0fil
.\vbox(643.20255+0.0)x234.8775, glue set 626.20251fill, direction TLT
..\glue(\topskip) 10.0
..\hbox(0.0+0.0)x0.0, shifted 234.8775, direction TLT
..\penalty 0
..\glue(\belowdisplayshortskip) 7.0 plus 3.0 minus 4.0
..\glue 0.0 plus 1.0fill
.\glue(\baselineskip) 17.55556
.\hbox(6.44444+0.0)x469.75499, glue set 232.37749fil, direction TLT
..\glue 0.0 plus 1.0fil minus 1.0fil
..\tenrm 1
..\glue 0.0 plus 1.0fil minus 1.0fil
如果我取消注释,\textdirection=0
输出是
\vbox(667.20255+0.0)x469.75499, direction TLT
.\vbox(0.0+0.0)x469.75499, glue set 14.0fil, direction TLT
..\glue -22.5
..\hbox(8.5+0.0)x469.75499, glue set 469.755fil, direction TLT
...\vbox(8.5+0.0)x0.0, direction TLT
...\glue 0.0 plus 1.0fil
..\glue 0.0 plus 1.0fil minus 1.0fil
.\vbox(643.20255+0.0)x469.75499, glue set 614.20251fill, direction TLT
..\glue(\topskip) 10.0
..\hbox(0.0+0.0)x469.75499, glue set 469.755fil, direction TLT
...\localpar
....\localinterlinepenalty=0
....\localbrokenpenalty=0
....\localleftbox=null
....\localrightbox=null
...\begindir TLT
...\penalty 10000
...\enddir TLT
...\glue(\parfillskip) 0.0 plus 1.0fil
...\glue(\rightskip) 0.0
..\penalty 10000
..\glue(\abovedisplayshortskip) 0.0 plus 3.0
..\glue(\baselineskip) 12.0
..\hbox(0.0+0.0)x0.0, shifted 234.8775, direction TLT
..\penalty 0
..\glue(\belowdisplayshortskip) 7.0 plus 3.0 minus 4.0
..\glue 0.0 plus 1.0fill
.\glue(\baselineskip) 17.55556
.\hbox(6.44444+0.0)x469.75499, glue set 232.37749fil, direction TLT
..\glue 0.0 plus 1.0fil minus 1.0fil
..\tenrm 1
..\glue 0.0 plus 1.0fil minus 1.0fil
看起来,当您\textdir
在组中明确推送目录节点(使用)时,LuaTeX 不会丢弃显示前的空行(可能由于惩罚周围的目录节点,它不会将其视为空行)。不确定这是否应被视为错误。
我不熟悉 babel 的代码,但我的猜测是 babel 在不需要时不会插入 dir 节点,因此当你将其放在\selectlanguage{ukenglish}
顶级分组级别时,babel 不会在你的环境组内注入更多 dir 节点。
如果您愿意使用一些 lua,您可能无需使用显示技巧来获取最后一行的长度:
\documentclass{article}
\pagestyle{empty}
\usepackage[bidi=basic, layout=lists]{babel}
\babelprovide[import, main]{persian}
\babelprovide[import]{ukenglish}
\newdimen\linelen
\directlua{
local disabled = true
local function lastline_length(head,c)
if disabled then
return head
end
local last_line = node.tail(head)
local parfill_node
for n in node.traverse_id(node.id('glue'),last_line.list) do
if n.subtype == 15 then parfill_node = n end
end
local length, _, _ = node.rangedimensions(last_line,last_line.head,parfill_node)
tex.setdimen('global', 'linelen',length)
return head
end
local getlastlinelength = luatexbase.new_luafunction"getlastlinelength"
lua.get_functions_table()[getlastlinelength] = function() disabled = false end
token.set_lua("getlastlinelength", getlastlinelength, "protected")
local dontgetlastlinelength = luatexbase.new_luafunction"dontgetlastlinelength"
lua.get_functions_table()[dontgetlastlinelength] = function() disabled = true end
token.set_lua("dontgetlastlinelength", dontgetlastlinelength, "protected")
luatexbase.add_to_callback('post_linebreak_filter',lastline_length,'lastline')
}
\newcommand{\nolistspaces}{%
\leftmargin 0pt
\rightmargin 0pt
\itemindent 0pt
\partopsep 0pt
\parsep 0pt
\topsep 0pt
}
\newenvironment{listenva}{%
\selectlanguage{ukenglish}%
\list{}{\nolistspaces}%
\item\relax
}{%
\ifdim\linelen>0pt
\vskip-\baselineskip
\fi
\strut\hskip\linelen+++%
\csname @noparlistfalse\endcsname
\endlist
}
\newenvironment{listenvb}{%
\global\linelen=0pt
\getlastlinelength
\list{}{\nolistspaces}%
\item\relax
}{%
\csname @noparlistfalse\endcsname
\endlist
\dontgetlastlinelength
}
\begin{document}
\begin{listenva}
\begin{listenvb}
Test.
\end{listenvb}
\end{listenva}
\selectlanguage{ukenglish}
\begin{listenva}
\begin{listenvb}
Test.
\end{listenvb}
\end{listenva}
\end{document}