1
2
3
4
5
6
7
8
9
10
11
12
13
14\startluacode
15
16
17
18
19local nodecodes = nodes.nodecodes
20local kerncodes = nodes.kerncodes
21
22local glyph_code = nodecodes.glyph
23local disc_code = nodecodes.disc
24local kern_code = nodecodes.kern
25local hlist_code = nodecodes.hlist
26
27local fontkern_code = kerncodes.fontkern
28
29local function set_catchword(t)
30 local nextpage = tex.lists.contribute_head or tex.lists.contrib_head
31 if not nextpage then
32 return
33 end
34 local firstline = nil
35 for n in nodes.traverse_id(hlist_code,nextpage) do
36 firstline = n
37 break
38 end
39 if not firstline then
40 return
41 end
42 local list = firstline.list
43 if not list then
44 return
45 end
46 local first = nil
47 local last = nil
48 for n, id, subtype in nodes.traverse(list) do
49 if id == glyph_code or id == disc_code or (id == kern_code and subtype == fontkern_code) then
50 if not first then
51 first = n
52 end
53 last = n
54 elseif first then
55 break
56 end
57 end
58 if not first then
59 return
60 end
61 local page = tex.getbox(t.box)
62 local head = nodes.copy_list(first,last.next)
63 head = nodes.insertbefore(head,head,nodes.pool.glue(1,1,1))
64 local line = nodes.hpack(head,page.width,"exactly")
65 if CONTEXTLMTXMODE > 0 then
66 line.yoffset = -t.voffset
67 line.xoffset = t.hoffset
68 else
69 line.shift = t.hoffset
70 line = nodes.insertbefore(line,line,nodes.pool.kern(t.voffset-line.height))
71 line = nodes.vpack(line)
72 end
73 line.height = 0
74 line.depth = 0
75 nodes.insertafter(page.list,nodes.tail(page.list),line)
76 logs.report("catchword","appending %a on page %i",nodes.toutf(head),tex.getcount("realpageno"))
77end
78
79interfaces.implement {
80 name = "set_catchword",
81 actions = set_catchword,
82 arguments = {
83 {
84 { "box", "integer" },
85 { "hoffset", "dimension" },
86 { "voffset", "dimension" },
87 },
88 },
89}
90
91\stopluacode
92
93\unprotect
94
95\installcorenamespace {catchword}
96
97\installsimplecommandhandler \??catchword {catchword}
98
99\setupcatchword
100 [\c!state=\v!stop,
101 \c!hoffset=\zeropoint,
102 \c!voffset=\lineheight]
103
104\def\page_check_catchword_yes#1
105 {\clf_set_catchword
106 box #1
107 hoffset \catchwordparameter\c!hoffset
108 voffset \catchwordparameter\c!voffset
109 \relax}
110
111\let\page_check_catchword_nop\gobbleoneargument
112
113\appendtoks
114 \doifelse{\catchwordparameter\c!state}\v!start
115 {\let\page_check_catchword\page_check_catchword_yes}
116 {\let\page_check_catchword\page_check_catchword_nop}
117\to \everysetupcatchword
118
119\appendtoks
120 \page_check_catchword\b_page_postprocessor
121\to \t_page_postprocessors_page
122
123\protect
124
125\continueifinputfile{mcatchword.mkiv}
126
127\setupcatchword
128 [state=start,
129 hoffset=.75em,
130 voffset=1cm]
131
132\starttext
133
134 \dorecurse{100}{\input ward }
135
136\stoptext
137 |