OpTeX 具有宏\begmulti
和\endmulti
将文本分成多列,但由于它变成了内部垂直模式,该\mark
命令不再具有任何效果。
比较
\headline={\botmark}
hello \mark{lorem ipsum}
\bye
和
\headline={\botmark}
\begmulti 2
hello \mark{lorem ipsum}
\endmulti
\bye
在这种模式下排版文本时,如何使用mark命令记录应该打印在标题中的数据?
答案1
有一个汉斯·哈根 (Hans Hagen) 的文章这解释了如何从内部列表迁移插入内容。
那里提供的代码可以轻松地适应与 OpTeX 一起使用,并且也可以与标记一起使用(没有彻底测试这一点)。
\newattribute\insattr
\directlua{
local hlist = node.id('hlist')
local vlist = node.id('vlist')
local ins = node.id('ins')
local mark = node.id('mark')
local has_attribute = node.has_attribute
local set_attribute = node.set_attribute
local ins_attribute = registernumber('insattr')
local function locate(head,first,last)
local current = head
while current do
local id = current.id
if id == vlist or id == hlist then
current.list, first, last = locate(current.list,first,last)
current = current.next
elseif id == ins or id == mark then
local insert = current
head, current = node.remove(head,current)
insert.next = nil
if first then
insert.prev, last.next = last, insert
else
insert.prev, first = nil, insert
end
last = insert
else
current = current.next
end
end
return head, first, last
end
local function migrate_inserts(where)
local current = tex.lists.contrib_head
while current do
local id = current.id
if id == vlist or id == hlist and not has_attribute(current,ins_attribute) then
set_attribute(current,ins_attribute,1)
local h, first, last = current.list, nil, nil
while h do
local id = h.id
if id == vlist or id == hlist then
h, first, last = locate(h,first,last)
end
h = h.next
end
if first then
local n = current.next
if n then
last.next, n.prev = n, last
end
current.next, first.prev = first, current
current = last
end
end
current = current.next
end
end
callback.add_to_callback('buildpage_filter',migrate_inserts,'migrate_inserts')
}
\headline={\botmark\hfil}
\begmulti 2
hello\mark{lorem ipsum}\fnote{Test} \lipsum[1-8]
\endmulti
\bye
页面顶部
页面底部
答案2
您可以使用OpTeX 技巧 0111(尽管列不平衡):
\fontfam[lm]
\newcount\numcolumn
\newdimen\xvsize
\def\twocol{\par\penalty0 \setbox0=\vbox\bgroup \hsize=.48\hsize \hbadness=5000 }
\def\endtwocol{\egroup
\_setxhsize \global\xvsize=\vsize % save the global values of \hsize, \vsize
\begingroup
\maxdeadcycles=1000 \vbadness=5000
\numcolumn=0
\headline={} \footline={} % internal \output routine without\head/foot lines
\output={\incr\numcolumn
\global\setbox\numexpr10000+\numcolumn=\_completepage % no \shipout, only save box
\ifodd\numcolumn\else \global\vsize=\xvsize \fi % correct \vsize for next page
\ifnum\outputpenalty>-20000 \else\dosupereject\fi
}
\ifdim\pagetotal>0pt % if the current page is non empty , we move it to \box10000
\numcolumn=-1
\tmpdim=\dimexpr\pagegoal-\pagetotal-\bigskipamount\relax
\vsize=\dimexpr\pagetotal+\prevdepth\relax
\vfil\supereject
\global\vsize=\tmpdim
\fi
\unvbox0 % now, we break \box0 to columns using internal output routine
\vfil\supereject
\endgroup
\vsize=\xvsize
\ifvoid10000 \else \unvbox10000 \bigskip \fi % print the original current page content
\fornumstep 2: 1..\numcolumn \do { % print columns
\line{\box\numexpr10000+##1\hfil \box\numexpr10001+##1}\vfil\break
}
}
%% TEST:
\headline={\botmark}
\twocol % two column mode starts
hello \mark{lorem ipsum}
\lorem[1-10]
\endtwocol % two column mode ends
\bye
答案3
抱歉,我不知道如何有效地将有关\mark
s 的信息从列材料传播到页面材料。但是,如果您知道要在包含单个\begmulti
...的所有页面的标题中包含什么内容\endmulti
,那么您可以使用声明宏为第一个这样的页面、第二页等提供标题\mpage
。可以按如下方式定义和使用宏:
\fontfam[lm]
\newcount\mpagenum
\def\mpage#1 #2{\sdef{mpage:#1}{#2}}
\addto\_printcolumns{\incr\mpagenum \cs{mpage:\the\mpagenum}}
\headline={\botmark\hfil}
\bgroup
\mpage 1 {\mark{first}}
\mpage 2 {\mark{second}}
\begmulti 2
\lorem[1-10]
\endmulti
\egroup
\bye
在用数字表示的页面上添加\mpage number {material}
垂直材料。如果数字=1,则它是材料开始的页面\begmulti
,数字=2 表示下一页,等等。声明集\mpage
应该与\begmulti
...放在一组中\endmulti
,因为我们想将它们独立地设置为每个多列排版。