strc-reg.mkiv /size: 40 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-reg,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Registers,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Structure Macros / Registers}
15
16\registerctxluafile{strc-reg}{}
17
18\unprotect
19
20\startcontextdefinitioncode
21
22% todo: tag:: becomes rendering
23% todo: language, character, linked, location
24% todo: fonts etc at sublevels (already defined)
25
26% \starttext
27% \placeregister[index]
28% \chapter{a} \index{93} \index{456} \index{***} \index{*} \index{@}
29% test \index{aa} test \startregister[index][x]{bb} test \page test \page test \page test \stopregister[index][x]
30% test \index{aa} test \setregisterentry[index][label=x,entries=bb] test \page test \page test \page test \finishregisterentry[index][label=x]
31% test \index{aa} test \setregisterentry[index][label=y] test \page test \page test \page test \finishregisterentry[index][label=y,entries=yy]
32% \stoptext
33
34%  \index                {entry}
35%  \index[key]           {entry}
36%  \index[pageclass::]   {entry}
37%  \index[pageclass::key]{entry}
38%  \index                {textclass::entry}
39%  \index[key]           {textclass::entry}
40%  \index[pageclass::]   {textclass::entry}
41%  \index[pageclass::key]{textclass::entry}
42
43% tzt variant with n entries, parameters and userdata (altnum)
44
45\installcorenamespace{register}
46
47\installcommandhandler\??register {register} \??register
48
49\let\strc_registers_setup_saved\setupregister
50
51\unexpanded\overloaded\def\setupregister % maybe we should drop the plural form
52  {\dotripleempty\strc_registers_setup}
53
54\def\strc_registers_setup[#1][#2][#3]%
55  {\ifthirdargument
56     \def\strc_registers_setup_step##1{\strc_registers_setup_saved[#1:##1][#3]}%
57     \processcommalist[#2]\strc_registers_setup_step
58   \else\ifsecondargument
59     \strc_registers_setup_saved[#1][#2]%
60   \else
61     \strc_registers_setup_saved[#1]%
62   \fi\fi}
63
64\unexpanded\def\setupregisters
65  {\dosingleempty\strc_registers_setup_root}
66
67\def\strc_registers_setup_root[#1]%
68  {\strc_registers_setup_saved[#1]\relax}
69
70\setupregister
71  [\c!n=2,
72   \c!balance=\v!yes,  % \v!no komt niet zo vaak voor
73   \c!align=\v!flushleft,
74   \c!tolerance=\v!stretch,
75   \c!before=\blank,
76  %\c!after=,
77  %\c!symbol=,
78   \c!compress=\v!no,
79   \c!interaction=\v!pagenumber,
80   \c!alternative=\v!a,
81   \c!distance=\emwidth,
82   \c!style=\v!bold,
83   \c!pagestyle=\v!slanted,
84   \c!indicator=\v!yes,
85   \c!criterium=\v!all,
86   \c!check=\v!yes, % check for weird see usage
87  %\c!command=,
88   \c!referencing=\v!on,
89   \c!location=\v!middle,
90  %\c!maxwidth=,
91   \c!number=\v!no,
92   \c!unknownreference=\v!empty,
93   \c!prefix=\v!both,
94  %\c!expansion=,
95  %\c!xmlsetup=,
96   \c!pagenumber=\v!yes,
97   \c!pageprefixconnector=\endash,
98   \c!pagesegments=2:2,
99   \c!file=\jobname,
100  %\c!deeptextcommand=, % undefined by default !
101   \c!method=, % no default as we have them in the module, maybe some day in lang-*
102   \c!numberorder=\v!numbers, % \v!characters
103   \s!language=\currentmainlanguage]%
104
105% yes or no shared ?
106
107\setupregister
108  [\c!label=,
109   \c!entries=,
110   \c!alternative=]
111
112\definemixedcolumns
113  [\v!register]
114  [\c!n=\registerparameter\c!n,
115   \c!balance=\registerparameter\c!balance,
116   \c!align=\registerparameter\c!align,
117   \c!tolerance=\registerparameter\c!tolerance]
118
119%D \starttyping
120%D \setupregister[index][1][textcolor=darkred]
121%D \setupregister[index][2][textcolor=darkgreen,textstyle=bold]
122%D
123%D \placeregister[index][n=1] \blank[3*big]
124%D
125%D test \index{test+one} test \index{test+two} more \index{more}
126%D \stoptyping
127
128\newconditional\c_strc_registers_defining
129\setnewconstant\c_strc_registers_maxlevel \plusfive
130
131\ifdefined\Word \else \unexpanded\def\Word#1{#1} \fi
132
133\appendtoks
134    \ifconditional\c_strc_registers_defining \else % todo: dosingle ...
135      \settrue\c_strc_registers_defining
136      \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop
137      \clf_defineregister{\currentregister}{\registerparameter\c!referencemethod}%
138      \normalexpanded{\presetheadtext[\currentregister=\Word{\currentregister}]}%
139      \setuevalue{\currentregister}{\dodoubleempty\strc_registers_insert_entry[\currentregister]}%
140      \setuevalue{\e!see\currentregister}{\dodoubleempty\strc_registers_insert_see[\currentregister]}%
141      %setuevalue{\e!coupled\currentregister}{\dolinkedregister{\currentregister}}%
142      % historic ballast
143      \setuevalue{\e!place\currentregister}{\placeregister[\currentregister]}%
144      \setuevalue{\e!complete\currentregister}{\completeregister[\currentregister]}%
145      \setuevalue{\e!setup\currentregister\e!endsetup}{\setupregister[\currentregister]}%
146      \dorecurse\c_strc_registers_maxlevel{% weird, expanded should not be needed
147        \normalexpanded{\defineregister[\currentregister:\recurselevel][\currentregister]}%
148       %\defineregister[\currentregister:\recurselevel][\currentregister]%
149        \letregisterparameter{\c!entries:\recurselevel}\empty % needed as we use detokenize (ok, we can
150        \letregisterparameter{\c!keys   :\recurselevel}\empty % avoid it, but it's faster too)
151      }%
152      %
153      \setfalse\c_strc_registers_defining
154    \fi
155\to \everydefineregister
156
157\appendtoks
158    \clf_setregistermethod{\currentregister}{\registerparameter\c!referencemethod}%
159\to \everysetupregister
160
161%D Registering:
162
163\glet\currentregistername  \empty
164\glet\currentregisternumber\!!zerocount
165
166\def\strc_registers_register_page_entry
167  {\iftrialtypesetting
168     \expandafter\gobblethreearguments
169   \else
170     \expandafter\strc_registers_register_page_entry_indeed
171   \fi}
172
173\def\strc_registers_register_page_expand_xml_entries
174  {\xmlstartraw
175     \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
176     \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
177     \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
178   \xmlstopraw
179   \glet\currentregistercoding\s!xml}
180
181\def\strc_registers_register_page_expand_yes_entries
182  {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
183   \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
184   \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
185   \glet\currentregistercoding\s!tex}
186
187\def\strc_registers_register_page_expand_nop_entries
188  {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
189   \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
190   \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
191   \glet\currentregistercoding\s!tex}
192
193\def\strc_registers_register_page_expand_xml
194  {\xmlstartraw
195     \xdef\currentregisterentries{\registerparameter\c!entries}%
196   \xmlstopraw
197   \glet\currentregistercoding\s!xml}
198
199\def\strc_registers_register_page_expand_yes
200  {\xdef\currentregisterentries{\registerparameter\c!entries}%
201   \glet\currentregistercoding\s!tex}
202
203\def\strc_registers_register_page_expand_nop
204  {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
205   \glet\currentregistercoding\s!tex}
206
207\def\strc_registers_register_page_expand_xml_keys
208  {\xmlstartraw
209     \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
210     \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
211     \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}%
212   \xmlstopraw}
213
214\def\strc_registers_register_page_expand_yes_keys
215  {\xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
216   \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
217   \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}}
218
219\def\strc_registers_register_page_entry_indeed#1#2#3% register data userdata
220  {\begingroup
221   \edef\currentregister{#1}%
222   %\setupcurrentregister[\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]%
223   \setupcurrentregister[#2]%
224   \edef\currentregisterlabel    {\registerparameter\c!label}%
225   \edef\currentregisterexpansion{\registerparameter\c!expansion}%
226   \edef\currentregisterownnumber{\registerparameter\c!ownnumber}%
227   \xdef\currentregisterkeys     {\registerparameter\c!keys}%
228   \xdef\currentregisterentries  {\registerparameter\c!entries}%
229   \xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}%
230   \ifx\currentregisterentries\empty
231     \ifx\currentregisterexpansion\s!xml
232       \strc_registers_register_page_expand_xml_entries
233     \else\ifx\currentregisterexpansion\v!yes
234       \strc_registers_register_page_expand_yes_entries
235     \else
236       \strc_registers_register_page_expand_nop_entries
237     \fi\fi
238   \else
239     \ifx\currentregisterexpansion\s!xml
240       \strc_registers_register_page_expand_xml
241     \else\ifx\currentregisterexpansion\v!yes
242       \strc_registers_register_page_expand_yes
243     \else
244       \strc_registers_register_page_expand_nop
245     \fi\fi
246   \fi
247   \ifx\currentregisterkeys\empty
248     \ifx\currentregistercoding\s!xml
249       \strc_registers_register_page_expand_xml_keys
250     \else
251       \strc_registers_register_page_expand_yes_keys
252     \fi
253   \fi
254   \setnextinternalreference
255   % we could consider storing register entries in a list which we
256   % could then sort
257   \glet\currentregistername\currentregister
258   \xdef\currentregisternumber{\clf_storeregister % 'own' should not be in metadata
259        metadata {%
260            name     {\currentregister}%
261            coding   {\currentregistercoding}%
262        \ifx\currentregisterownnumber\v!yes
263            own      {\registerparameter\c!alternative}% can be used instead of pagenumber
264        \fi
265        \ifx\currentreferencecoding\s!xml
266            xmlroot  {\xmldocument} % only useful when text
267        \fi
268        \ifx\currentregisterxmlsetup\empty \else
269            xmlsetup {\currentregisterxmlsetup}%
270        \fi
271        }%
272        references {%
273        \ifx\currentregisterlabel\empty \else
274            label    {\currentregisterlabel}%
275        \fi
276%             view     {\interactionparameter\c!focus}%
277        }%
278        entries {%
279            % we need a special one for xml, this is just a single one
280            \ifx\currentregisterentries\empty
281                entries {
282                    {\currentregisterentriesa}%
283                    {\currentregisterentriesb}%
284                    {\currentregisterentriesc}%
285                }
286            \else
287                entry {\currentregisterentries}%
288            \fi
289            \ifx\currentregisterkeys\empty
290                keys {
291                    {\currentregisterkeysa}%
292                    {\currentregisterkeysb}%
293                    {\currentregisterkeysc}%
294                }
295            \else
296                key {\currentregisterkeys}%
297            \fi
298        }%
299        userdata {\detokenize\expandafter{\normalexpanded{#3}}}
300   }%
301   \clf_setinternalreference
302      internal \locationcount
303      view     {\interactionparameter\c!focus}%
304   \relax % this will change
305   \ifx\currentregisterownnumber\v!yes
306     \glet\currentregistersynchronize\relax
307   \else
308     \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
309   \fi
310   \currentregistersynchronize % here?
311   % needs thinking ... bla\index{bla}. will break before the . but adding a
312   % penalty is also no solution
313   \dostarttagged\t!registerlocation\currentregister
314   \c_attr_destination\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
315   \dotagregisterlocation
316   \dostoptagged
317   \endgroup}
318
319\unexpanded\def\dosetfastregisterentry#1#2#3#4#5% register entry key processor processor
320  {\begingroup
321   \edef\currentregister{#1}%
322   \setnextinternalreference
323   \glet\currentregistername\currentregister
324   \xdef\currentregisternumber{\clf_storeregister
325     {%
326        metadata {%
327          name {\currentregister}%
328        }
329        entries {%
330          entry {#2}%
331          key   {#3}%
332        }%
333        processors {%
334          entry {#4}%
335          page  {#5}%
336        }%
337     }%
338   }%
339   % overlap with the above
340 % \clf_setinternalreference
341 %    internal \locationcount
342 %    view     {\interactionparameter\c!focus}%
343   \relax % this will change
344   \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}%
345   \currentregistersynchronize % here?
346   \dostarttagged\t!registerlocation\currentregister
347   \c_attr_destination\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
348   \dotagregisterlocation
349   \dostoptagged
350   \endgroup}
351
352\let\dotagregisterlocation\relax % experiment
353
354\unexpanded\def\strc_registers_insert_entry[#1][#2]%
355  {\def\currentregister{#1}%
356   \edef\p_ownnumber{\registerparameter\c!ownnumber}%
357   \ifx\p_ownnumber\v!yes
358     \expandafter\strc_registers_insert_entry_yes
359   \else
360     \expandafter\strc_registers_insert_entry_nop
361   \fi{#2}}
362
363% \def\strc_registers_insert_entry_nop#1#2%
364%   {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
365%
366% \def\strc_registers_insert_entry_yes#1#2#3%
367%   {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
368%
369% less tokens passed (nicer for tracing) .. could become installable
370
371\def\strc_registers_insert_entry_nop
372  {\ifvmode
373     \expandafter\strc_registers_insert_entry_nop_par
374   \else
375     \expandafter\strc_registers_insert_entry_nop_txt
376   \fi}
377
378\def\strc_registers_insert_entry_yes
379  {\ifvmode
380     \expandafter\strc_registers_insert_entry_yes_par
381   \else
382     \expandafter\strc_registers_insert_entry_yes_txt
383   \fi}
384
385\def\strc_registers_insert_entry_nop_par#1#2%
386  {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}}
387
388\def\strc_registers_insert_entry_yes_par#1#2#3%
389  {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}}
390
391\def\strc_registers_insert_entry_nop_txt#1#2%
392  {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}
393
394\def\strc_registers_insert_entry_yes_txt#1#2#3%
395  {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}
396
397\unexpanded\def\startregister{\doquadrupleempty\strc_registers_start_entry}
398\unexpanded\def\stopregister {\dodoubleargument\strc_registers_stop_entry}
399
400% a synonym, so that we can nest with overlap without syntax check problems
401
402\let\openregisterrange \startregister
403\let\closeregisterrange\stopregister
404
405\def\strc_registers_start_entry[#1][#2][#3][#4]#5%
406  {\iffourthargument
407     % #1=register #2=tag #3=own #4=sortkey #5=entry
408     \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!alternative=#3,\c!keys={#4},\c!entries={#5}}{}}%
409   \else
410     % #1=register #2=tag #3=sortkey #5=entry
411     \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!keys={#3},\c!entries={#5}}{}}%
412   \fi}
413
414\def\strc_registers_stop_entry[#1][#2]%
415  {\normalexpanded{\ctxlatecommand{extendregister("#1","#2")}}}
416
417\def\setregisterentry   {\dotripleempty\strc_registers_set_entry}
418\def\finishregisterentry{\dotripleempty\strc_registers_finish_entry}
419
420% not yet document, not sure if this will stay:
421
422\def\strc_registers_set_entry   [#1][#2][#3]{\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}}
423\def\strc_registers_finish_entry[#1][#2][#3]{\strc_registers_finish_entry_indeed{#1}{#2}{#3}}
424
425\def\strc_registers_finish_entry_indeed#1#2#3% register data userdata
426  {\begingroup
427   \edef\currentregister{#1}%
428  %\setupcurrentregister[\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% todo: fast setter
429   \resetregisterparameter\c!entries
430   \resetregisterparameter\c!label
431   \resetregisterparameter\c!keys
432   \resetregisterparameter\c!alternative
433   \setupcurrentregister[#2]%
434   \edef\currentregisterlabel    {\registerparameter\c!label}%
435   \edef\currentregisterexpansion{\registerparameter\c!expansion}%
436   \edef\currentregisterownnumber{\registerparameter\c!ownnumber}%
437   \xdef\currentregisterkeys     {\registerparameter\c!keys}%
438   \ifx\currentregisterexpansion\s!xml
439     \xmlstartraw
440       \xdef\currentregisterentries{\registerparameter\c!entries}%
441     \xmlstopraw
442     \glet\currentregistercoding\s!xml
443   \else
444     \ifx\currentregisterexpansion\v!yes
445       \xdef\currentregisterentries{\registerparameter\c!entries}%
446     \else
447       \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
448     \fi
449     \glet\currentregistercoding\s!tex
450   \fi
451   % I hate this kind of mess ... but it's a user request.
452   \ifx\currentregisterentries\empty
453       \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
454            metadata = {
455            \ifx\currentregisterownnumber\v!yes
456                own = "\registerparameter\c!alternative", % can be used instead of pagenumber
457            \fi
458            },
459            userdata = \!!bs\detokenize{#3}\!!es
460         })%
461       }}%
462   \else
463       \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
464            metadata = {
465              % catcodes = \the\catcodetable,
466                coding   = "\currentregistercoding",
467            \ifx\currentregisterownnumber\v!yes
468                own      = "\registerparameter\c!alternative", % can be used instead of pagenumber
469            \fi
470            },
471            entries = {
472                % we need a special one for xml, this is just a single one
473                \!!bs\currentregisterentries\!!es,
474                \!!bs\currentregisterkeys\!!es
475            },
476            userdata = \!!bs\detokenize{#3}\!!es
477         })
478       }}%
479   \fi
480   \endgroup}
481
482% The following variants are meant for (for instance xml). There is some
483% overlap with previously defined macros.
484%
485% \starttext
486%     \setstructurepageregister[index][entries=alpha]a
487%     \setstructurepageregister[index][entries=gamma]g
488%     \setstructurepageregister[index][entries=beta]b
489%     \setstructurepageregister[index][entries:1=alpha,keys:1=z]a
490%     \setstructurepageregister[index][entries:1=gamma,keys:1=x]g
491%     \setstructurepageregister[index][entries:1=beta, keys:1=y]b
492%     \index{alpha}a
493%     \index{gamma}g
494%     \index{beta}b
495%     \placeregister[index][n=1]
496% \stoptext
497
498% some overlap with previous
499
500\unexpanded\def\setstructurepageregister
501  {\dotripleempty\strc_registers_set}
502
503\def\strc_registers_set[#1][#2][#3]% [register][settings][userdata]
504  {\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}}
505
506\unexpanded\def\startstructurepageregister{\doquadrupleempty\strc_registers_start}
507\unexpanded\def\stopstructurepageregister {\dodoubleargument\strc_registers_stop}
508
509\let\openstructurepageregisterrange \startstructurepageregister
510\let\closestructurepageregisterrange\stopstructurepageregister
511
512\def\strc_registers_start[#1][#2][#3][#4]% [register][tag][settings][userdata]
513  {\doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,#3}{#4}}}
514
515\def\strc_registers_stop[#1][#2]%
516  {\normalexpanded{\ctxlatecommand{structures.registers.extend("#1","#2")}}}
517
518% So far.
519
520\unexpanded\def\strc_registers_insert_see[#1][#2]#3#4%
521  {\doflushatpar{\strc_registers_insert_see_indeed{#1}{#2}{#3}{#4}}}
522
523\def\strc_registers_insert_see_indeed#1#2#3#4% register key entry seeword
524  {\begingroup
525   \edef\currentregister{#1}%
526   \edef\currentregisterexpansion{\registerparameter\c!expansion}%
527   \ifx\currentregisterexpansion\s!xml
528     \xmlstartraw
529       \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
530       \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
531     \xmlstopraw
532     \glet\currentregistercoding\s!xml
533   \else
534     \ifx\currentregisterexpansion\v!yes
535       \xdef\currentregisterentries{#3}% not ok yet
536       \xdef\currentregisterseeword{#4}% not ok yet
537     \else
538       \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
539       \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
540     \fi
541     \glet\currentregistercoding\s!tex
542   \fi
543   \setnextinternalreference
544   % we could consider storing register entries in list
545   \edef\temp{\clf_storeregister{% \temp grabs the nofentries
546     metadata {%
547         kind {see}%
548         name {\currentregister}%
549     }%
550     references {%
551%         view  {\interactionparameter\c!focus}%
552     }%
553     entries {%
554         % we need a special one for xml, this is just a single one
555         entry {\currentregisterentries}%
556         key   {#2}%
557     }%
558     seeword {%
559         text  {\currentregisterseeword}%
560     }%
561   }}%
562   \clf_setinternalreference
563      internal \locationcount
564      view     {\interactionparameter\c!focus}%
565   \relax % this will change
566   \dostarttagged\t!registerlocation\currentregister
567   \c_attr_destination\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup
568   \dotagregisterlocation
569   \dostoptagged
570   \endgroup}
571
572%D Rendering:
573
574% todo: c!language ipv s!language
575
576\let\utilityregisterlength\!!zerocount
577
578\def\determineregistercharacteristics
579  {\dodoubleempty\strc_registers_determine_characteristics}
580
581\def\strc_registers_determine_characteristics[#1][#2]%
582  {\begingroup
583   \setupregister[#1][#2]%
584   \edef\currentregister{\firstinset{#1}}%
585   \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\clf_analyzeregister
586     {\currentregister}%
587     {%
588        language    {\registerparameter\s!language}%
589        method      {\registerparameter\c!method}%
590        numberorder {\registerparameter\c!numberorder}%
591        compress    {\registerparameter\c!compress}%
592        criterium   {\registerparameter\c!criterium}%
593        pagenumber  \ifx\registerpageseparatorsymbol\empty false\else true\fi
594     }%
595   }}%
596   \ifcase\utilityregisterlength\relax
597     \resetsystemmode\v!register
598   \else
599     \setsystemmode  \v!register
600   \fi}
601
602\newtoks\everyplaceregister
603
604\appendtoks
605    \dontcomplain
606\to \everyplaceregister
607
608\newconditional\c_strc_registers_text_interaction
609
610\unexpanded\def\placeregister
611  {\dodoubleempty\strc_registers_place}
612
613\def\strc_registers_place[#1][#2]%
614  {\iffirstargument
615     \begingroup
616    %\forgetall
617     \setupregister[#1][#2]% can be a list
618     \edef\currentregister{\firstinset{#1}}%
619     \the\everyplaceregister
620     \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone
621       \startmixedcolumns[\currentregister]%
622         \strc_registers_place_indeed{#1}%
623       \stopmixedcolumns
624     \else
625       \strc_registers_place_indeed{#1}%
626     \fi
627     \endgroup
628   \fi}
629
630\def\strc_registers_place_indeed#1%
631  {\doifelse{\registerparameter\c!interaction}\v!text
632     \settrue\setfalse\c_strc_registers_text_interaction
633   \clf_processregister
634     {#1}%
635     {%
636        language      {\registerparameter\s!language}%
637        method        {\registerparameter\c!method}%
638        numberorder   {\registerparameter\c!numberorder}%
639        check         {\registerparameter\c!check}%
640        compress      {\registerparameter\c!compress}%
641        criterium     {\registerparameter\c!criterium}%
642        pagemethod    {\registerparameter\c!pagemethod}%
643        pagenumber    \ifx\registerpageseparatorsymbol\empty false\else true\fi
644     }{%
645        separatorset  {\registerparameter\c!pageprefixseparatorset}%
646        conversionset {\registerparameter\c!pageprefixconversionset}%
647        starter       {\registerparameter\c!pageprefixstarter}%
648        stopper       {\registerparameter\c!pageprefixstopper}%
649        set           {\registerparameter\c!pageprefixset}%
650        segments      {\registerparameter\c!pageprefixsegments}%
651        connector     {\registerparameter\c!pageprefixconnector}%
652     }{%
653        prefix        {\registerparameter\c!pageprefix}%
654        separatorset  {\registerparameter\c!pageseparatorset}%
655        conversionset {\registerparameter\c!pageconversionset}%
656        starter       {\registerparameter\c!pagestarter}%
657        stopper       {\registerparameter\c!pagestopper}%
658        segments      {\registerparameter\c!pagesegments}%
659     }%
660   \relax}
661
662\def\strc_registers_limited_entry#1%
663  {\limitatetext{#1}\currentregistermaxwidth\unknown}%
664
665\appendtoks
666    \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}%
667    \ifx\currentregistermaxwidth\empty
668      \let\limitedregisterentry\firstofoneargument
669    \else
670      \let\limitedregisterentry\strc_registers_limited_entry
671    \fi
672\to \everyplaceregister
673
674\unexpanded\def\completeregister
675  {\dodoubleempty\strc_registers_complete}
676
677\def\strc_registers_complete[#1][#2]%
678  {\iffirstargument
679     \begingroup
680     \edef\currentregister{\firstinset{#1}}%
681     \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\currentregister}},reference=\currentregister]}%
682     \placeregister[#1][#2]%
683     \page[\v!yes]%
684     \stopnamedsection
685     \endgroup
686   \fi}
687
688% test case for collapsing (experimental, for Steffen Wolfrum)
689%
690% \starttext
691% \placeregister[index][compress=no]  \blank[2*big]
692% \placeregister[index][compress=yes] \blank[2*big]
693% \placeregister[index][compress=all] \page
694% \dorecurse{10}{test 1:!\index{test} test \page}
695% \dorecurse{5} {test 2:\recurselevel      \page}
696% \dorecurse{10}{test 3:!\index{test} test \page}
697% \dorecurse{5} {test 4:\recurselevel      \page}
698% \dorecurse{1} {test 5:!\index{test} test \page}
699% \dorecurse{5} {test 6:\recurselevel      \page}
700% \dorecurse{10}{test 7:!\index{test} test \page}
701% \dorecurse{5} {test 8:\recurselevel      \page}
702% oeps \index{oeps}
703% xxxx \index{xxxx}
704% todo \index{todo}
705% \stoptext
706
707%D Character rendering (sections):
708
709\installcorenamespace{registerindicator}
710
711\def\defaultregistercharacter#1%
712  {\edef\currentregistercharacter{#1}%
713   \ifx\currentregistercharacter\empty
714     % skip
715   \else\ifx\currentregistercharacter\s!unknown
716     % skip
717   \else
718     \edef\p_indicator{\registerparameter\c!indicator}%
719     \ifx\p_indicator\v!yes
720       \strc_registers_place_character_yes
721     \else
722       \strc_registers_place_character_nop
723     \fi
724   \fi\fi}
725
726\def\strc_registers_place_character_yes
727  {\expandnamespaceparameter\??registerindicator\registerparameter\c!alternative\v!a{\currentregistercharacter}}
728
729\def\strc_registers_place_character_nop
730  {\registerparameter\c!before
731   \goodbreak}
732
733% a = <before> <goodbreak> <character> <par> <after> <nobreak>
734
735\def\strc_registers_indicator_a#1#2%
736  {\registerparameter\c!before
737   % bugged, why does leftskip gets set: \vskip\lineheight\goodbreak\vskip-\lineheight
738   \typo_injectors_check_register
739   \begingroup
740   \useregisterstyleandcolor\c!style\c!color
741   \dontleavehmode
742   \typo_injectors_mark_register
743   \strut
744   \iflocation
745     \dosetdirectpagereference{\currentregister:\v!section:#1}%
746   \fi
747   \registerparameter\c!command{#2}%
748   \endgroup
749   \blank[\v!samepage]%
750   \registerparameter\c!after
751   \par
752   \nobreak}
753
754% b = <goodbreak> <before> <character> <after> <nobreak>
755
756\def\strc_registers_indicator_b#1#2%
757  {\registerparameter\c!before
758   \typo_injectors_check_register
759   \begingroup
760   \useregisterstyleandcolor\c!style\c!color
761   \dontleavehmode
762   \typo_injectors_mark_register
763   \strut
764   \iflocation
765     \dosetdirectpagereference{\currentregister:\v!section:#1}%
766   \fi
767   \registerparameter\c!command{#2}%
768   \endgroup
769   \registerparameter\c!after
770   \nobreak}
771
772\setvalue{\??registerindicator a}#1{\strc_registers_indicator_a{#1}{#1}}
773\setvalue{\??registerindicator A}#1{\strc_registers_indicator_a{#1}{\WORD{#1}}}
774\setvalue{\??registerindicator b}#1{\strc_registers_indicator_b{#1}{#1}}
775\setvalue{\??registerindicator B}#1{\strc_registers_indicator_b{#1}{\WORD{#1}}}
776
777%D The following macros are the interface to the rendering. These are
778%D generated by \LUA. This might change.
779
780% \showinjector
781% \setinjector[register][2][\column]
782%
783% \starttext
784%     first  \index{first}
785%     second \index{second}
786%     third  \index{third}
787%     fourth \index{fourth}
788%     \placeregister[index]
789% \stoptext
790
791\doinstallinjector\s!register
792
793%D Beware, we get funny side effects when a dangling \index precedes an
794%D placeindex as then flushing takes place inside the index. Took me hours
795%D to notice that.
796
797\newconstant   \c_strc_registers_page_state % 0=nothing  1=page  2=see
798\newdimen      \d_strc_registers_distance
799
800\unexpanded\def\startregisteroutput
801  {\endgraf
802   \begingroup
803   \d_strc_registers_distance\registerparameter\c!distance\relax
804   \dostarttaggedchained\t!register\currentregister\??register
805   \forgeteverypar
806   \forgetparindent
807   \forgetparskip}
808
809\unexpanded\def\stopregisteroutput
810  {\endgraf
811   \dostoptagged
812   \endgroup}
813
814\newdimen\d_strc_registers_hangindent
815\newcount\c_strc_registers_hangafter
816
817\unexpanded\def\usenestedregisterstyleandcolor#1#2% will change
818  {\useregisterstyleandcolor#1#2%
819   % how about style
820   \ifconditional\c_strc_registers_text_interaction
821     \ifx\currentcolorparameter\empty \else
822       \resetinteractionparameter\c!color
823       \resetinteractionparameter\c!contrastcolor
824     \fi
825   \fi}
826
827\unexpanded\def\startregisterentries#1% depth
828  {\endgraf
829   \begingroup
830   \scratchcounter\ifnum#1>\c_strc_registers_maxlevel\c_strc_registers_maxlevel\else#1\fi\relax
831   \dostarttagged\t!registerentries\empty
832   \let\savedcurrentregister\currentregister
833   \edef\currentregister{\currentregister:\number\scratchcounter}%
834   \usenestedregisterstyleandcolor\c!textstyle\c!textcolor
835   \ifnum\scratchcounter>\plusone
836     \advance\leftskip\d_strc_registers_distance\relax
837   \fi
838   \d_strc_registers_hangindent\registerparameter\c!distance\relax
839   \c_strc_registers_hangafter \plusone
840   \blank[\v!samepage]%
841   \let\currentregister\savedcurrentregister}
842
843\unexpanded\def\stopregisterentries
844  {\endgraf
845   \dostoptagged
846   \endgroup}
847
848\unexpanded\def\startregisterentry#1% todo: level
849  {\typo_injectors_check_register
850   \begingroup
851   \dostarttagged\t!registerentry\empty
852   \global\setconstant\c_strc_registers_page_state\zerocount
853   \hangindent\d_strc_registers_hangindent
854   \hangafter \c_strc_registers_hangafter
855   \typo_injectors_mark_register}
856
857\unexpanded\def\stopregisterentry
858  {\endgraf
859   \global\setconstant\c_strc_registers_page_state\zerocount
860   \dostoptagged
861   \endgroup}
862
863\unexpanded\def\startregistersection#1% title
864  {\dostarttagged\t!registersection\empty
865   \dostarttagged\t!registertag\empty
866   \registercharacter{#1}\endgraf
867   \dostoptagged}
868
869\unexpanded\def\stopregistersection
870  {\dostoptagged
871   \endgraf}
872
873\unexpanded\def\startregisterpages
874  {\begingroup
875   \dostarttagged\t!registerpages\empty
876   \useregisterstyleandcolor\c!pagestyle\c!pagecolor
877   \registerparameter\c!pageleft}
878
879\unexpanded\def\stopregisterpages
880  {\registerparameter\c!pageright
881   \dostoptagged
882   \endgroup}
883
884\unexpanded\def\startregisterseewords
885  {\begingroup
886   \dostarttagged\t!registerpage\empty
887   \useregisterstyleandcolor\c!pagestyle\c!pagecolor}
888
889\unexpanded\def\stopregisterseewords
890  {\dostoptagged
891   \endgroup}
892
893\unexpanded\def\registerpageseparator % todo: , configurable
894  {\ifcase\c_strc_registers_page_state
895     \hskip\d_strc_registers_distance\relax
896   \or
897     \dostarttagged\t!registerseparator\empty
898     \registerpageseparatorsymbol % page
899     \dostoptagged
900   \or
901     \dostarttagged\t!registerseparator\empty
902     \registerpageseparatorsymbol % see
903     \dostoptagged
904   \fi}
905
906\unexpanded\def\registeronepagerangeseparator
907  {|\endash|} % todo use \prewordbreak
908
909% \unexpanded\def\withregisterpagecommand#1#2#3#4%
910%   {\def\currentregisterpageindex{#2}%
911%    \iflocation
912%      \goto{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
913%    \else
914%      \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
915%    \fi}
916
917\unexpanded\def\withregisterpagecommand#1#2#3#4%
918  {\ifcase#3\relax
919     {\tt [entry\space not\space flushed]}%
920   \else
921     \def\currentregisterpageindex{#2}%
922     \iflocation
923       \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]%
924     \else
925       \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}%
926     \fi
927   \fi}
928
929\unexpanded\def\pushcurrentregister#1%
930  {\let\m_current_register\currentregister
931   \edef\currentregister{#1}}
932
933\unexpanded\def\popcurrentregister
934  {\let\currentregister\m_current_register}
935
936\unexpanded\def\registeronepage#1#2#3#4#5% #1:class #2:processor content
937  {\pushcurrentregister{#1}%
938   \edef\p_pagenumber{\registerparameter\c!pagenumber}%
939   \ifx\p_pagenumber\v!no\else
940     \registerpageseparator
941     \global\setconstant\c_strc_registers_page_state\plusone
942     \dostarttagged\t!registerpage\empty
943     \withregisterpagecommand{#2}{#3}{#4}{#5}%
944     \dostoptagged
945   \fi
946   \popcurrentregister}
947
948\newconditional\c_strc_registers_following
949
950\appendtoks
951    \edef\p_compress{\registerparameter\c!compress}%
952    \ifx\p_compress\v!text
953      \settrue\c_strc_registers_following
954      \letregisterparameter\c!compress\v!yes
955    \else
956      \setfalse\c_strc_registers_following
957    \fi
958\to \everyplaceregister
959
960\unexpanded\def\registerpagerange#1#2#3#4#5#6#7#8% #1:class #2:processor  content, content todo: -- configurable
961  {\pushcurrentregister{#1}%
962   \edef\p_pagenumber{\registerparameter\c!pagenumber}%
963   \ifx\p_pagenumber\v!no\else
964     \registerpageseparator
965     \global\setconstant\c_strc_registers_page_state\plusone
966     \dostarttagged\t!registerpagerange\empty
967     \dostarttagged\t!registerfrompage\empty
968     \withregisterpagecommand{#2}{#3}{#4}{#5}%
969     \dostoptagged
970     \ifconditional\c_strc_registers_following
971       \ifnum#3=\numexpr#6-1\relax
972         \labeltext{following:\s!singular}%
973       \else
974         \labeltext{following:\s!plural}%
975       \fi
976    \else
977       \registeronepagerangeseparator
978       \dostarttagged\t!registertopage\empty
979       \withregisterpagecommand{#2}{#6}{#7}{#8}%
980     \fi
981     \dostoptagged
982     \dostoptagged
983   \fi
984   \popcurrentregister}
985
986\unexpanded\def\defaultregisterentry#1#2#3#4#5% #1:class #2:processor #3:internal #4:seeindex #5:word
987  {\pushcurrentregister{#1}%
988   \def\currentregisterpageindex{#3}%
989   \iflocation
990     \def\currentregisterseeindex{#4}%
991     \ifconditional\c_strc_registers_text_interaction
992       \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#2}{#5}}[internal(#3)]%
993     \else
994       \doapplyregisterentrycommand{#2}{#5}%
995     \fi
996   \else
997     \let\currentregisterseeindex\empty
998     \doapplyregisterentrycommand{#2}{#5}%
999   \fi
1000   \popcurrentregister}
1001
1002\unexpanded\def\doapplyregisterentrycommand#1#2% processor text
1003  {\dostarttagged\t!registercontent\empty
1004   \ifx\currentregisterseeindex\empty \else
1005     \dontleavehmode
1006     \dosetdirectpagereference{seeindex:\currentregisterseeindex}% maybe some day we will support an area
1007   \fi
1008   \applyprocessor{#1}{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#2}}}}%
1009   \dostoptagged}
1010
1011\unexpanded\def\doapplyregisterseecommand#1#2%
1012  {\ifx\currentregisterseeindex\empty
1013     \applyprocessor{#1}{#2}%
1014   \else\iflocation
1015     \strc_references_goto_internal{\applyprocessor{#1}{#2}}[seeindex:\currentregisterseeindex]%
1016   \else
1017     \applyprocessor{#1}{#2}%
1018   \fi\fi}
1019
1020\unexpanded\def\defaultregisterseeword#1#2#3#4#5#6#7% class i n #3:processor #4:internal #5:seeindex #6:word
1021  {\pushcurrentregister{#1}%
1022   \ifnum#2=\plusone
1023     \registerpageseparator
1024   \fi
1025   \global\setconstant\c_strc_registers_page_state\plustwo
1026   \def\currentregisterpageindex{#5}%
1027   \dostarttagged\t!registersee\empty
1028   \settrue\c_strc_registers_page_done
1029   \iflocation
1030     \def\currentregisterseeindex{#6}%
1031   \else
1032     \let\currentregisterseeindex\empty
1033   \fi
1034   \ifnum#2=\plusone
1035     \labeltexts\v!see{\doapplyregisterseecommand{#4}{#7}}%
1036   \else\ifnum#2=#3\relax
1037     \labeltexts\v!and{\doapplyregisterseecommand{#4}{#7}}%
1038   \else
1039     ,\space\doapplyregisterseecommand{#4}{#7}%
1040   \fi\fi
1041   \dostoptagged
1042   \popcurrentregister}
1043
1044\unexpanded\def\doapplyregistersectioncommand#1#2%
1045  {\ifx\currentregistersectionindex\empty
1046     \applyprocessor{#1}{#2}%
1047   \else\iflocation
1048     \strc_references_goto_internal{\applyprocessor{#1}{#2}}[sectionindex:\currentregistersectionindex]%
1049   \else
1050     \applyprocessor{#1}{#2}%
1051   \fi\fi}
1052
1053\unexpanded\def\defaultregistersection#1#2#3#4#5#6#7% class i n #4:processor #5:internal #6:sectionindex #7:word
1054  {\pushcurrentregister{#1}%
1055   \ifnum#2=\plusone
1056     \registerpageseparator
1057   \fi
1058   \global\setconstant\c_strc_registers_page_state\plustwo
1059   \def\currentregisterpageindex{#5}%
1060   \dostarttagged\t!registersection\empty
1061   \settrue\c_strc_registers_page_done
1062   \iflocation
1063     \def\currentregistersectionindex{#6}%
1064   \else
1065     \let\currentregistersectionindex\empty
1066   \fi
1067   \ifnum#2=\plusone\else
1068      ,\space
1069   \fi
1070   \doapplyregistersectioncommand{#4}{#7}%
1071   \dostoptagged
1072   \popcurrentregister}
1073
1074\let\registersection  \defaultregistersection
1075\let\registerseeword  \defaultregisterseeword
1076\let\registerentry    \defaultregisterentry
1077\let\registercharacter\defaultregistercharacter
1078
1079%D Experimental:
1080%D
1081%D \starttyping
1082%D \setupregister
1083%D   [index]
1084%D   [pagesegments=1:4,
1085%D    pagemethod=section]
1086%D
1087%D \starttext
1088%D
1089%D     \chapter {one} \section {alpha}
1090%D
1091%D     x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
1092%D     x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
1093%D
1094%D     \chapter {one} \section {alpha}
1095%D
1096%D     x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
1097%D     x\index {whatever 1}x\index {whatever 2}x\index {whatever 2}x \page
1098%D
1099%D     \placeindex[n=1]
1100%D
1101%D \stoptext
1102%D \stoptyping
1103
1104%D A few specific rendering variants:
1105
1106% \def\doregisterpagelocation#1#2%
1107%   {\nextregisterpage
1108%    \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}}
1109
1110% todo: \installregisterpagehandler
1111
1112% \def\MyRegisterPageCommand#1%
1113%   {#1\currentregisterpageuserdata{whatever}}
1114%
1115% \starttext
1116%     \setregisterentry[index][entries=aaa][whatever=f.] test \index{bbb} test
1117%     \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand]
1118% \stoptext
1119
1120\def\registerpageuserdata       #1#2{\clf_registeruserdata#1{#2}}
1121\def\currentregisterpageuserdata    {\registerpageuserdata\currentregisterpageindex} % {#1}
1122
1123% not yet ok : new internal handler names
1124
1125\unexpanded\def\registerpagebuttonsymbol
1126  {\vrule\s!width\emwidth\s!height\exheight\s!depth\zeropoint\relax}
1127
1128\installcorenamespace{registersymbol}
1129
1130\setvalue{\??registersymbol n}%
1131  {\def\registerpageseparatorsymbol{,\space}}
1132
1133\setvalue{\??registersymbol a}%
1134  {\def\registerpageseparatorsymbol{,\space}} % now done via conversion
1135
1136\setvalue{\??registersymbol\v!none}%
1137  {\let\registerpageseparatorsymbol\empty
1138   \let\registeronepage  \gobblefivearguments
1139   \let\registerpagerange\gobbleeightarguments}
1140
1141\setvalue{\??registersymbol 1}%
1142  {\let\registerpageseparatorsymbol\space
1143   \def\registeronepage  {\symbol[1]\gobblefivearguments}%
1144   \def\registerpagerange{\symbol[1]\gobbleeightarguments}}
1145
1146\setvalue{\??registersymbol 2}%
1147  {\let\registerpageseparatorsymbol\space
1148   \def\registeronepage  {\registerpagebuttonsymbol\gobblefivearguments}%
1149   \def\registerpagerange{\registerpagebuttonsymbol\gobbleeightarguments}}
1150
1151\unexpanded\def\setregisterpagerendering
1152  {\doifelse{\registerparameter\c!pagenumber}\v!no
1153     {\let \currentregisterpagesymbol\v!none}
1154     {\edef\currentregisterpagesymbol{\registerparameter\c!symbol}}%
1155   \ifx\currentregisterpagesymbol\empty
1156     \csname\??registersymbol n\endcsname
1157   \else\ifcsname\??registersymbol\currentregisterpagesymbol\endcsname
1158     \csname\??registersymbol\currentregisterpagesymbol\endcsname
1159   \else
1160     \let\registerpageseparatorsymbol\space
1161     \def\registeronepage  {\registerparameter\c!symbol\gobblefivearguments}%
1162     \def\registerpagerange{\registerparameter\c!symbol\gobbleeightarguments}%
1163   \fi\fi}
1164
1165\appendtoks
1166     \setregisterpagerendering
1167\to \everyplaceregister
1168
1169%D The linked register code will be reimplemented (not that hard) when it's needed
1170%D again and/or when I'm bored.
1171
1172           \def\findregisterinternal#1#2#3{\clf_findregisterinternal{#1}{#2}#3\relax}
1173\unexpanded\def\pageofinternal          #1{\clf_pageofinternal#1\relax}
1174
1175\unexpanded\def\linkedregisterentrylink#1#2#3#4% tag where before after
1176  {\iflocation
1177     \scratchcounter\findregisterinternal{#1}{#2}\currentregisternumber\relax\relax
1178     \ifcase\scratchcounter\else
1179       #3\relax
1180       \goto{\symbol[#2]}[internal(\the\scratchcounter)]%
1181       #4\relax
1182     \fi
1183   \else
1184   % \scratchcounter\findregisterinternal{#1}{#2}\currentregisternumber\relax\relax
1185   % \ifcase\scratchcounter\else
1186   %   #3\relax
1187   %   \pageofinternal\scratchcounter
1188   %   #4\relax
1189   % \fi
1190   \fi}
1191
1192\unexpanded\def\linkedregisterentry#1%
1193  {\dontleavehmode
1194   \begingroup
1195   \setbox\scratchbox\hbox{#1}%
1196   \linkedregisterentrylink\currentregistername\v!previous\relax\nobreakspace
1197   \unhbox\scratchbox
1198   \linkedregisterentrylink\currentregistername\v!next\nobreakspace\relax
1199   \endgroup}
1200
1201\unexpanded\def\registerpacked#1#2%
1202  {\iflocation
1203     \hskip\d_strc_registers_distance\relax
1204     \nobreak
1205     \ifnum#1=#2\relax
1206       \goto{\symbol[\v!somewhere]}[internal(#1)]%
1207     \else
1208       \goto{\symbol[\v!first]}[internal(#1)]%
1209       \nobreakspace
1210       \goto{\symbol[\v!last]}[internal(#2)]%
1211     \fi
1212   \fi}
1213
1214%D Default index:
1215
1216\defineregister
1217  [\v!index]
1218%  [\v!indices]
1219
1220\stopcontextdefinitioncode
1221
1222\protect \endinput
1223