LuaTeX 노드 라이브러리 : 수동으로 만든 노드 목록에서 수직 글루 / 커닝이 작동하지 않습니다. 무엇이 누락 되었습니까?

Nov 17 2020

이것은 LuaTeX 노드 라이브러리 / 노드 목록 질문입니다.

다음 코드에서 수동으로 만들어진 노드 목록을 조판하려고합니다. 줄 바꿈을 추가하기 위해 페널티 노드를 추가하면 잘 작동합니다 (예 : 해당 지점에서 줄 바꿈). 그러나 줄 바꿈 후에 수직 접착제 / 커닝을 추가하면 실제로 수직 공간이 추가되지 않습니다. 내가 어디로 잘못 가고 있습니까? 줄 바꿈 루틴에 수직 공간을 추가하려면 어떤 노드가 필요합니까? LaTeX의 매크로 \vspace{25pt}또는 \\[25pt].

사이드 노트 루아 질문 : 1) require루아 파일을로드하는 방법은 괜찮습니까? 내 말은, local변수 이름이 내가로드하는 다른 lua 파일 require, 예를 들어 variable 과 충돌하면 local head어떻게 될까요? 2) 함수를 전역으로 만드는 대신 linebreak.동일한 이름을 가진 함수를 가진 다른 lua 파일과 이름 충돌을 피하기 위해 접두사 와 같은 것으로 호출하는 방법이 있습니까?

업데이트 : 위의 "Sidenote"질문은 이제 여기 에서 별도의 질문으로 논의됩니다. 이 질문은 관련이 없으므로이 질문을 읽는 동안 위의 "Sidenote lua 질문"을 무시하십시오.

스크린 샷 (첫 줄 뒤에 추가로 25pt 또는 50pt 세로 공간이 필요합니다) :

linebreak.tex :

>>> lualatex linebreak.tex
\documentclass{article}
\directlua{require"linebreak.lua"}
\begin{document}
\raggedright
\directlua{
    initialize()
    addchars('H')
    addchars('e')
    addchars('l')
    addchars('l')
    addchars('o')
    addchars(' ')
    addchars('W')
    addchars('o')
    addchars('r')
    addchars('l')
    addchars('d')
    addpenalty(1,-10000) % Add line break, works fine!
    addglue(1,25*65536) % XXX: Add vertical glue, doesn't work!
    addkern(1,25*65536) % XXX: Add vertical kern, doesn't work!
    addchars(' ')
    addchars('H')
    addchars('e')
    addchars('y')
    writeparagraph()
}
\end{document}

linebreak.lua :

local glyph_id = node.id("glyph")
local glue_id  = node.id("glue")
local kern_id  = node.id("kern")
local penalty_id = node.id("penalty")
local current_font = font.current()
local font_parameters = font.getfont(current_font).parameters
local n, head, last

function addchars(c)
  for s in string.utfvalues(c) do
    local char = unicode.utf8.char(s)
    if unicode.utf8.match(char,"%s") then
      -- its a space
      n = node.new(glue_id)
      n.width   = font_parameters.space
      n.shrink  = font_parameters.space_shrink
      n.stretch = font_parameters.space_stretch
    else -- a glyph
      n = node.new(glyph_id)
      n.font = current_font
      n.subtype = 1
      n.char = s
      n.lang = tex.language
      n.uchyph = 1
      n.left = tex.lefthyphenmin
      n.right = tex.righthyphenmin
    end
    last.next = n
    last = n
  end
  return last
end

function addpenalty(s,p)
    n = node.new(penalty_id)
    n.subtype = s or 0
    n.penalty = p or 0
    last.next = n
    last = n
    return n
end

function addkern(s,p)
    n = node.new(kern_id)
    n.subtype = s or 0
    n.kern = p or 0
    last.next = n
    last = n
    return n
end

function addglue(s,a,b,c,d,e)
    n = node.new(glue_id)
    n.subtype = s
    n.width = a or 0
    n.stretch = b or 0
    n.shrink = c or 0
    n.stretch_order = d or 0
    n.shrink_order = e or 0
    last.next = n
    last = n
    return n
end

function initialize()
    -- add parindent glue in the beginning, create head node
    head = node.new("glue")
    head.width = tex.parindent
    last = head
end

function writeparagraph()
    -- append a penalty and parfillskip glue at the end of list
    addpenalty(0,10000)
    addglue(15,0,tex.parfillskip.stretch,tex.parfillskip.stretch_order)
    -- create prev pointers
    node.slide(head)
    -- hyphenate
    lang.hyphenate(head)
    -- take care of fonts, kerning, ligature, etc
    head = nodes.simple_font_handler(head)
    -- call tex linebreaking, write to pdf
    tex.write(tex.linebreak(head))
    -- initize pointers
    head = nil
    last = nil
end

답변

reportaman Nov 17 2020 at 10:59

내 질문 에 대한 David Carlisle의 의견에 따라 수직 접착제가있는 조정 노드를 추가했습니다. 이제 원하는대로 출력됩니다. 다음은 스크린 샷과 코드입니다.

수정 된 linebreak.tex :

\documentclass{article}
\directlua{require"linebreak.lua"}
\begin{document}
\raggedright
\directlua{
    initialize()
    addchars('H')
    addchars('e')
    addchars('l')
    addchars('l')
    addchars('o')
    addchars(' ')
    addchars('W')
    addchars('o')
    addchars('r')
    addchars('l')
    addchars('d')
    addpenalty(1,-10000) % Add line break
    vspace(25*65536) % Add vspace
    addchars('H')
    addchars('e')
    addchars('y')
    writeparagraph()
}
\end{document}

수정 된 linebreak.lua :

local glyph_id = node.id("glyph")
local glue_id  = node.id("glue")
local kern_id  = node.id("kern")
local penalty_id = node.id("penalty")
local adjust_id  = node.id("adjust")
local current_font = font.current()
local font_parameters = font.getfont(current_font).parameters
local n, head, last

function addchars(c)
  for s in string.utfvalues(c) do
    local char = unicode.utf8.char(s)
    if unicode.utf8.match(char,"%s") then
      -- its a space
      n = node.new(glue_id)
      n.width   = font_parameters.space
      n.shrink  = font_parameters.space_shrink
      n.stretch = font_parameters.space_stretch
    else -- a glyph
      n = node.new(glyph_id)
      n.font = current_font
      n.subtype = 1
      n.char = s
      n.lang = tex.language
      n.uchyph = 1
      n.left = tex.lefthyphenmin
      n.right = tex.righthyphenmin
    end
    last.next = n
    last = n
  end
  return last
end

function addpenalty(s,p)
    n = node.new(penalty_id)
    n.subtype = s or 0
    n.penalty = p or 0
    last.next = n
    last = n
    return n
end

function addkern(s,p)
    n = node.new(kern_id)
    n.subtype = s or 0
    n.kern = p or 0
    last.next = n
    last = n
    return n
end

function addadjust(s,h)
    n = node.new(adjust_id)
    n.subtype = s or 0
    n.head = h
    last.next = n
    last = n
    return n
end

function vspace(s)
    g1 = node.new(glue_id)
    g1.width = s
    g1.subtype = 0
    addadjust(1,g1)
end

function addglue(s,a,b,c,d,e)
    n = node.new(glue_id)
    n.subtype = s
    n.width = a or 0
    n.stretch = b or 0
    n.shrink = c or 0
    n.stretch_order = d or 0
    n.shrink_order = e or 0
    last.next = n
    last = n
    return n
end

function initialize()
    -- add parindent glue in the beginning, create head node
    head = node.new("glue")
    head.width = tex.parindent
    last = head
end

function writeparagraph()
    -- append a penalty and the parfillskip glue at the end of list
    addpenalty(0,10000)
    addglue(15,0,tex.parfillskip.stretch,tex.parfillskip.stretch_order)
    -- create prev pointers
    node.slide(head)
    -- hyphenate
    lang.hyphenate(head)
    -- take care of fonts, kerning, ligature, etc
    head = nodes.simple_font_handler(head)
    -- call linebreaking
    tex.write(tex.linebreak(head))
    -- initize pointers
    head = nil
    last = nil
end