LuaTeX 节点在左边距中 insert_before

LuaTeX 节点在左边距中 insert_before

在玩弄了答案之后这里,我注意到 insert_after 和 insert_before 之间存在一些差异。node.insert_after 将内容添加到右边距,而 node.insert_before 似乎不会添加到左边距。似乎它们都像内容从左边距开始放置一样增长。问题是如何将 hlist n 的内容扩展到左边距(使用 luatex 节点库)而不是将主框推到右边距。

左边距不存在:

左边距不存在

右边空白处有:

右边距为 A

在下面的代码中,我注释了 3 个不同的插入配方。逐个取消注释以查看效果。有趣的是,Append-2 配方(insert_before)没有产生任何结果,即使它在 luatex 手册中的定义看起来像 Append-1 配方(insert_after)


\documentclass{article}
\usepackage{lua-visual-debug}

\directlua{
%
function my_post_lb_filter(h,c)
local cntr=0

for n in node.traverse(h) do
% pull out the boxes and add A
if n.id==0 then
local  newn= node.new(node.id("glyph"))
newn.font=font.current()
newn.char=65 % this is a single character box, for A

% Append-1 works fine, A goes in margin:
% node.insert_after(n.list,node.tail(n.list),newn)

% Append-2 produces no result:
% node.insert_before(n.list,n.head,newn)

% Append-3 instead of putting A in margin makes text violate right margin
% n.head,n=node.insert_before(n.list,n.head,newn)

end
%
end
return h
end
luatexbase.add_to_callback('post_linebreak_filter', my_post_lb_filter, 'add A at eol')
}



\begin{document}

Vivamus pharetra posuere sapien. Nam consectetuer. 
Sed aliquam, nunc eget euismod ullamcorper, lectus nunc 
ullamcorper orci, fermentum bibendum enim nibh eget ipsum. 
Donec porttitor ligula eu 
dolor. Maecenas 
vitae nulla consequat libero cursus venenatis.

\end{document}


答案1

insert_before和都insert_after将新的头节点作为第一个返回值返回。从技术上讲,此返回值仅在头节点发生变化时才有意义。(如果头节点没有变化,则不必更改其他节点中对头节点的引用。如果头节点发生变化,则必须更改。)鉴于头节点是标记列表的第一个节点,并且 insert_after 在另一个节点后插入一个节点,insert_after 在大多数情况下不会改变头部。(有一个例外:如果列表为空,则node.insert_after更改头部)另一方面,如果node.insert_before用于在头节点之前插入某些内容,则新节点将始终成为新头,因此头会发生变化。因此,如果您可能会改变头部,请在使用这些函数时仔细考虑,或者遵循基本规则:

insert_before永远不要忽略/的返回值insert_after

因此,虽然您的 Append-1 似乎工作正常,但最好将其更改为

n.head = node.insert_after(n.list, node.tail(n.list), newn)

这可以避免处理 Append-2 所遇到的问题。

TeX 总是从左侧开始放置节点。(除非使用从右到左的框方向,否则一切都从右侧开始)如果您希望某些东西在左侧重叠,则不能只在开头添加东西,而必须添加(负)粘连和/或字距来移动它(类似于您在“正常”TeX 中执行的操作)。实际上,在右边距添加东西时做同样的事情通常是有意义的,以避免有人试图重新打包您的框时出现问题。在末尾添加东西时,必须在新节点之后添加调整(首先添加新材料,然后返回以隐藏其宽度而不影响其位置)。在开头添加东西时,调整会添加到新节点之前(这里我们想要影响新节点的位置):

\documentclass{article}
\usepackage{lua-visual-debug}

\directlua{
%
function my_post_lb_filter(h,c)
  local cntr=0

  for n in node.traverse(h) do
    % pull out the boxes and add A
    if n.id==0 then
        local newn= node.new("glyph")
        newn.font=font.current()
        newn.char=65 % this is a single character box, for A
        local newk = node.new("kern")
        newk.kern = -newn.width % A kern which "hides" the width of newn

        % n.head = node.insert_after(n.list,node.tail(n.list),newn)
        % n.head = node.insert_after(n.list,newn,newk)

        n.head=node.insert_before(n.list,n.head,newn)
        n.head=node.insert_before(n.list,newn,newk)
    end
    %
  end
  return h
end
luatexbase.add_to_callback('post_linebreak_filter', my_post_lb_filter, 'add A at eol')
}



\begin{document}

Vivamus pharetra posuere sapien. Nam consectetuer. 
Sed aliquam, nunc eget euismod ullamcorper, lectus nunc 
ullamcorper orci, fermentum bibendum enim nibh eget ipsum. 
Donec porttitor ligula eu 
dolor. Maecenas 
vitae nulla consequat libero cursus venenatis.

\end{document}

在此处输入图片描述

相关内容