如何在 OpTeX 的多列环境中使用 \mark?

如何在 OpTeX 的多列环境中使用 \mark?

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

抱歉,我不知道如何有效地将有关\marks 的信息从列材料传播到页面材料。但是,如果您知道要在包含单个\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,因为我们想将它们独立地设置为每个多列排版。

相关内容