LuaTeX : 조판 출력에 영향을주지 않고 수학 경계 표시 (양식 및 공백 모두)
이전 질문에 대한 답변에서 볼 수 있듯이 수학 경계 노드는 수학 경계를 표시하는 신뢰할 수있는 방법이 아닙니다. 경계를 표시하는 데 사용할 수있는 두 가지 가능한 해결 방법이 있습니다. 1) 수학 목록 주위에 사용자 정의 whatsit 노드 추가, 2) 수학 목록 내의 노드에 대한 "math"속성 정의 및 설정. 이러한 경계 표시는 TeX가 줄을 끊은 후 노드 목록을 처리하는 데 여러 가지 방법으로 유용 할 수 있습니다. a) 텍스트 추출을 시도하는 동안 <beginmath> <endmath> 유형 구분 기호 추가 b) 텍스트 및 수학의 선택적 색상 지정, c) 등. a) 방정식의 대체 / 텍스트 설명을 제공하기 위해 beginmath whatsit 값에 추가 된 "대체 텍스트"와 함께 사용할 수도 있습니다.
접근 방식 1)과 관련하여 LuaTeX 문서는 "LuaTEX 엔진은 내용을 보지 않고 단순히 이러한 내용을 넘어 설 것입니다."라고 말합니다. 링크를 A를 : whatsits이 linebreaking, 출력을 pagebreaking, microtypography에 영향을 미칠 수 있음을 시사 게시물이 비록 포스트 쇼 페이지 파괴에 영향을 것을, 그리고 링크를 게시 (도 텍에 linebreaking에 영향을 줄 수 있습니다) 그 쇼에 영향을 microtypography은.
접근 방식 2)가 모든 수학 목록 내용을 반복해야하므로 1) mlist_to_hlist 필터를 사용하여 호출하면 속도가 느려집니다. ( 더 많은 구분자가 있지만 구분 기호 $<tex_equation>$
앞뒤에 속성을 설정 및 설정 해제하도록 안전하게 재정의 할 수있는 경우가 아니면 $
...). 그렇다면 문제는 어떻게 접근 방식 1)을 사용하여 수학 경계를 표시하여 마이크로 타이포그래피, 줄 바꿈 및 페이지 나누기에 실제로 영향을 미치지 않는지에 대한 것입니다. 아니면 접근법 2)가 유일한 안전한 방법입니까?
인라인 수학에 대한 첫 번째 시도는 전문가 리뷰 및 디스플레이 수학 (정렬 등 환경)에 대한 확장을 찾고 있습니다.
암호:
% >>> lualatex mathmode.tex
\documentclass{article}
\usepackage[callback={}]{nodetree}
\begin{document}
\directlua{
local function mathboundary(h,d,p)
local beginmath = node.new("whatsit","user_defined")
beginmath.type = string.byte("s")
beginmath.value = "beginmath"
beginmath.attr = h.attr
beginmath.user_id = luatexbase.new_whatsit'beginmath'
local endmath = node.new("whatsit","user_defined")
endmath.type = string.byte("s")
endmath.value = "endmath"
endmath.attr = h.attr
endmath.user_id = luatexbase.new_whatsit'endmath'
h = node.insert_after(h,node.tail(h),endmath)
h = node.insert_before(h,h,beginmath)
return node.mlist_to_hlist(h,d,p)
end
luatexbase.add_to_callback('mlist_to_hlist', mathboundary, 'Mark math')
}
\setbox0=\vbox{{\noindent Hello\\ $x=a+b^2$}}
\directlua{
local nodetree = require('nodetree')
nodetree.print(tex.box[0])
}
\box0
\end{document}
콘솔 ( WHATSIT subtype: user_defined
) :
└─VLIST width: 345pt, depth: 0.83pt, height: 18.94pt
╚═head:
├─HLIST subtype: line, width: 345pt, depth: 0.11pt, height: 6.94pt
│ ╚═head:
│ ├─LOCAL_PAR
│ ├─GLYPH subtype: 256, char: H, width: 7.5pt, height: 6.83pt
│ ├─GLYPH subtype: 256, char: e, width: 4.44pt, height: 4.48pt, depth: 0.11pt
│ ├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
│ ├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
│ ├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
│ ├─PENALTY penalty: 10000
│ ├─GLUE stretch: +1fil
│ ├─PENALTY penalty: -10000
│ └─GLUE subtype: rightskip
├─PENALTY subtype: linebreakpenalty, penalty: 300
├─GLUE subtype: baselineskip, width: 3.75pt
└─HLIST subtype: line, width: 345pt, depth: 0.83pt, height: 8.14pt
╚═head:
├─WHATSIT subtype: user_defined, user_id: 1, type: 115, value: beginmath
├─GLYPH subtype: 256, char: x, width: 5.72pt, height: 4.31pt
├─GLUE subtype: thickmuskip, width: 2.78pt, stretch: 2.78pt
├─GLYPH subtype: 256, char: =, width: 7.78pt, height: 3.67pt, depth: -1.33pt
├─PENALTY subtype: noadpenalty, penalty: 500
├─GLUE subtype: thickmuskip, width: 2.78pt, stretch: 2.78pt
├─GLYPH subtype: 256, char: a, width: 5.29pt, height: 4.31pt
├─GLUE subtype: medmuskip, width: 2.22pt, stretch: 1.11pt, shrink: 2.22pt
├─GLYPH subtype: 256, char: +, width: 7.78pt, height: 5.83pt, depth: 0.83pt
├─PENALTY subtype: noadpenalty, penalty: 700
├─GLUE subtype: medmuskip, width: 2.22pt, stretch: 1.11pt, shrink: 2.22pt
├─GLYPH subtype: 256, char: b, width: 4.29pt, height: 6.94pt
├─HLIST subtype: sup, width: 4.49pt, height: 4.51pt, shift: -3.63pt
│ ╚═head:
│ └─GLYPH char: 2, width: 3.99pt, height: 4.51pt
├─WHATSIT subtype: user_defined, user_id: 2, type: 115, value: endmath
├─MATH subtype: endmath
├─PENALTY subtype: linepenalty, penalty: 10000
├─GLUE subtype: parfillskip, stretch: +1fil
└─GLUE subtype: rightskip
답변
줄 바꿈 후 노드 목록을 볼 때 경계 노드는 신뢰할 수있는 솔루션이 아닙니다. 여기에는 최소한 두 가지 이유가 있습니다.
모든 노드는 버릴 수 있거나 버릴 수 없습니다. 경계 노드를 버릴 수있는 경우 math-on / math-off 노드에서와 동일한 문제가 발생합니다. 라인의 시작 부분에서 사라집니다. 따라서 원하는 노드는 버릴 수 없지만 라인 시작 부분의 버릴 수있는 노드에 대한 규칙을 기억하십시오. 줄 바꿈 후에는 버릴 수없는 첫 번째 노드를 만날 때까지 버릴 수있는 모든 노드가 삭제됩니다. 특히 이것은 새로운 폐기 불가능 경계 노드가 잠재적으로 다음 폐기 가능한 경계 노드의 제거를 억제하여 출력에 영향을 미친다는 것을 의미합니다. (여기에 삭제 불가능한 노드를 추가하는 다른 이유, 예를 들어 whatsit가 항상 줄 바꿈에 영향을 주지만 이것이 설명하기 가장 쉬운 이유입니다)
줄 바꿈이 나오면 수학은 포함하지만 수학 경계는 포함하지 않는 hlist를 가질 수 있습니다. 다소 극단적 인 예는 다음과 같습니다.
\documentclass{article} \begin{document} \showoutput \setbox0\vbox{ \hsize=1cm \noindent Hi $1+2+3+4$ } \setbox1\vsplit0 to\baselineskip \setbox2\vsplit0 to\baselineskip \showbox0 \showbox1 \showbox2 \end{document}
여기서 상자 1은 수학 공식의 중간 부분 만 포함하므로 어떤 종류의 경계 노드도 포함 할 이유가 없습니다. 그래도 여전히 수학입니다.
(실제로 발생할 가능성이 더 높은 이것의 변형은 페이지를 가로 지르는 수학 공식입니다. 두 번째 페이지에는 수학이 시작되지 않기 때문에 시작 수학 노드가 없습니다.)
그래서 이것에 대해 무엇을 할 수 있습니까? 두 가지 옵션이 있습니다.
- 접근 방식 1)은 안정적으로 작동하지 않지만 2)를 구현하고 속성을 추가 할 수 있습니다. 기본적으로
post_mlist_to_hlist_filter
¹ 의 노드 목록을 반복 하여 추가하면 인라인 및 디스플레이 수학이 모두 다룹니다. - 줄 바꿈 전에 원하는 작업을 수행 하고 기존 수학 경계 노드를 사용하십시오. 대부분의 경우, 어쨌든 줄 바꿈하기 전에 몇 가지 작업을 수행하기를 원하므로 이는 매우 자연스러운 일입니다.
특정 사용 사례에 따라 솔루션 중 하나가 매우 자연스러운 경우가 많습니다. 예를 들어 텍스트 추출은 거의 항상 pre-linebreak (또는 pre-shaping) 텍스트를 기반으로해야하므로 2에 적합하지만, 수학 노드에 다른 색상을 추가하는 것은 사실상 어쨌든 속성을 추가하는 것을 의미하므로 자연스럽게 1에 적합합니다. .
¹ : 현대 LuaLaTeX 버전에서는 mlist_to_hlist
거의 직접 대신 설정할 수 없습니다 안 pre_mlist_to_hlist_filter
또는 post_mlist_to_hlist_filter
사용되어야한다. 기본적으로와 동일한 인터페이스를 mlist_to_hlist
가지고 있지만 node.mlist_to_hlist
직접 호출 할 필요가 없으며 코드는 이러한 콜백을 사용하는 다른 패키지와 호환됩니다. 예를 들어 질문의 코드는
luatexbase.add_to_callback('mlist_to_hlist', mathboundary, 'Mark math')
와
luatexbase.add_to_callback('pre_mlist_to_hlist_filter', mathboundary, 'Mark math')
및 교체
return node.mlist_to_hlist(h,d,p)
그냥
return h