
학습을 위해 나는 다음의 여백 메모에 LuaTeX 코드를 사용하고 이해하려고 합니다.여기LuaLaTeX에서.
그래서 저는 다음과 같은 최소한의 설정을 했습니다.
\documentclass{article}
\usepackage{luatexbase}
\directlua{
local HLIST = node.id("hlist")
local RULE = node.id("rule")
local GLUE = node.id("glue")
local KERN = node.id("kern")
local WHAT = node.id("whatsit")
local COL = node.subtype("pdf_colorstack")
mark_lines = function (head)
for mark in node.traverse_id(WHAT, head) do
local attr = node.has_attribute(mark, 100)
if attr then
local item = mark.next
while item do
if item.id == HLIST then
node.set_attribute(item, 100, attr)
item = nil
else
item = item.next
end
end
head = node.remove(head, mark)
end
end
return head
end
process_marginalia = function (head)
local remainingheight, first, item = 0, true, node.slide(head)
while item do
if node.has_field(item, "kern") then
if not first then
remainingheight = remainingheight + item.kern
end
elseif node.has_field(item, "spec") then
if not first then
remainingheight = remainingheight + item.spec.width
end
elseif node.has_field(item, "height") then
if first then
first = false
else
remainingheight = remainingheight + item.depth
end
local attr = node.has_attribute(item, 100)
if attr then
local note = node.copy(tex.box[attr])
local upward = note.depth - node.tail(note.list).depth
if upward > remainingheight then
upward = remainingheight - upward
else
upward = 0
end
local kern = node.new(KERN, 1)
kern.kern = upward - note.height - item.depth
node.insert_before(note.list, note.list, kern)
note.list = kern
note.height, note.depth = 0, 0
node.insert_after(head, item, note)
note.shift = tex.hsize + tex.sp("1em")
first = true
remainingheight = upward
else
remainingheight = remainingheight + item.height
end
end
item = item.prev
end
end
luatexbase.add_to_callback("post_linebreak_filter", mark_lines, "mark_lines")
}
\newcount\notecount
\def\note#1{%
\advance\notecount 1%
\expandafter\newbox\csname marginnote_\the\notecount\endcsname%
\expandafter\setbox\csname marginnote_\the\notecount\endcsname=\vtop{\hsize=4cm\rightskip=0pt plus 1fil\noindent\it #1}%
\bgroup\attribute100=\expandafter\the\csname marginnote_\the\notecount\endcsname\vadjust pre {\pdfliteral{}}\egroup%
}
\begin{document}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\note{Please do not fill this with too much text}
\output{\directlua{process_marginalia(tex.box[255].list)}\shipout\box255}
\end{document}
그러나 LuaLaTeX는 항상 해당 줄에서 오류를 발생시킵니다 \setbox
(LuaTeX는 수정된 버전에서도 마찬가지입니다):
! Missing number, treated as zero.
<to be read again>
\marginnote_1
l.85 ...{Please do not fill this with too much text}
?
왜 이런 문제가 발생하고 어떻게 해결하는지 완전히 이해하지 못합니다. 그래서 내 질문은: 왜 TeX는 그것을 좋아하지 않습니까 \setbox
?
답변1
바로 '공간실종증후군'이다.
\def\note#1{%
\advance\notecount 1
\expandafter\newbox\csname marginnote_\the\notecount\endcsname%
\expandafter\setbox\csname marginnote_\the\notecount\endcsname=\vtop{\hsize=4cm\rightskip=0pt plus 1fil\noindent\it #1}%
\bgroup\attribute100=\expandafter\the\csname marginnote_\the\notecount\endcsname\vadjust pre {\pdfliteral{}}\egroup%
}
%
당신 은 1
.
또한 당신은 필요합니다 \usepackage{luatex85}
. 이 수정 후에 나는 얻었습니다.
무슨 일이야? 상수 뒤 의 누락된 공간은 1
다음 토큰의 확장을 트리거합니다.\expandafter
\csname
하므로이전의값이 \notecount
사용됩니다.
박스 레지스터는 실제로 정수이기 때문에 "누락된 숫자"가 발생합니다. 매크로가 할당 \marginnote_0
되고 \setbox
대신 \marginnote_1
.
보다\newcommand 또는 이와 유사한 줄 끝에 퍼센트 문자를 추가하는 것이 언제 해로울 수 있습니까?자세한 내용은.