strc-ref.mklx /size: 76 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=strc-ref,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Cross Referencing,
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% \ifexporting\dostarttaggednodetail\t!link\fi
15% \ifexporting\dostoptagged\fi
16
17% todo: (1) configure references, (2) rendering => with presets
18%
19% \defineconversionset[default][Character,number,Romannumerals,Character][number]
20% \defineseparatorset [default][.,.,--][.]
21% \setuphead[subsection][sectionstopper=),sectionsegments=4:4]
22% \setupreferencestructureprefix[default][prefixsegments=2:4]
23% \setupreferencestructureprefix[figure][default][prefixsegments=3:4]
24% \chapter {One}
25% \section {One}
26% \subsection[sec:test]{Two}
27% See \in[sec:test] and \in[fig:xx] and \in[fig:yy]
28% \placefigure[here][fig:xx]{}{}
29% \placefigure[here][fig:yy]{}{}
30
31\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing}
32
33\newif     \iflocation
34\newinteger\locationcount
35\newinteger\locationorder
36\newbox    \locationbox
37\newinteger\lastreferenceattribute
38\newinteger\lastdestinationattribute
39\newinteger\prefixcounter
40
41\registerctxluafile{strc-rsc}{autosuffix}
42\registerctxluafile{strc-ref}{autosuffix}
43\registerctxluafile{node-ref}{autosuffix}
44
45\unprotect
46
47% todo : unknown/illegal reference no arg
48% todo : +n pages check on 'samepage' (contrastcolor)
49% todo : multiple text in reference
50
51% Makes more sense to build action data first, especially now openaction etc are
52% supported.
53%
54% \definespecial\doexecuteactionchain w h
55% \definespecial\dosetgotolocation
56% \definespecial\dosetexecuteJScode
57% ...
58
59%D This module deals with referencing. In \CONTEXT\ referencing is one of the core
60%D features, although at a first glance probably nobody will notice. This is good,
61%D because referencing should be as hidden as possible.
62%D
63%D Before we start implementing functionality we provide a way to set up this
64%D mechanism.
65%D
66%D \showsetup{setupreferencing}
67%D
68%D In interactive documents verbose references don't always make sense (what is a
69%D page number in an unnumbered document). By setting the \type{interaction}
70%D variable, one can influences the way interactive references are set.
71
72\installcorenamespace{referencing}
73
74\installdirectcommandhandler \??referencing {referencing} % \??referencing
75
76\mutable\lettonothing\referenceprefix
77
78\mutable\lettonothing\currentdestinationattribute
79
80\mutable\lettonothing\currentreferenceattribute
81\mutable\lettonothing\currentreferencecoding
82\mutable\lettonothing\currentreferencecontent
83\mutable\lettonothing\currentreferencedata
84\mutable\lettonothing\currentreferenceexpansion
85\mutable\lettonothing\currentreferenceformatautocase
86\mutable\lettonothing\currentreferenceformatlabel
87\mutable\lettonothing\currentreferenceformatsetups
88\mutable\lettonothing\currentreferenceformattype
89\mutable\lettonothing\currentreferencekind
90\mutable\lettonothing\currentreferencelabels
91%mutable\lettonothing\currentreferencenumber
92%mutable\lettonothing\currentreferenceorder
93%mutable\lettonothing\currentreferencepage
94%mutable\lettonothing\currentreferencerealpage
95%mutable\lettonothing\currentreferencetext
96%mutable\lettonothing\currentreferencetitle
97\mutable\lettonothing\currentreferenceuserdata
98
99\newif\ifreferencing \referencingtrue
100
101\appendtoks
102    \ifcstok{\referencingparameter\c!state}\v!start
103      \referencingtrue
104    \else
105      \referencingfalse
106    \fi
107\to \everysetupreferencing
108
109%D In paper documents, referencing comes down to cross referencing, but in
110%D their interactive counterparts, is also involves navigation. Many features
111%D implemented here are therefore closely related to navigation.
112%D
113%D Many \CONTEXT\ commands can optionally be fed with a reference. Such a
114%D reference, when called upon, returns the number of a figure, table, chapter
115%D etc, a piece of text, or a pagenumber.
116%D
117%D There are three ways of defining a reference:
118%D
119%D \starttyping
120%D \pagereference[here]
121%D \textreference[here]{some text}
122%D \stoptyping
123%D
124%D the third alternative combines them in:
125%D
126%D \starttyping
127%D \reference[here]{some text}
128%D \stoptyping
129
130\permanent\protected\def\showreferences{\enabletrackers[nodes.references.show,nodes.destinations.show]}
131
132%D These are implemented in a low level form as:
133
134\permanent\tolerant\protected\def\textreference                   [#labels]{\strc_references_set_named_reference\s!text{#labels}{}}
135\permanent\tolerant\protected\def\pagereference                   [#labels]{\strc_references_set_named_reference\s!page{#labels}{}{}}
136\permanent\tolerant\protected\def\reference                       [#labels]{\strc_references_set_named_reference\s!full{#labels}{}}
137\permanent\tolerant\protected\def\setreference [#labels]#spacer[#S#settings]{\strc_references_set_named_reference\s!user{#labels}{#settings}{}}
138
139\permanent\protected\def\dosetdirectpagereference#1{\strc_references_set_named_reference\s!page{#1}{}{}} % low level, maybe use _
140
141\permanent\protected\def\usereferenceparameter#1% faster local variant
142  {\edef\m_strc_references_asked{#1\c!reference}%
143   \ifempty\m_strc_references_asked\else
144     \dosetdirectpagereference\m_strc_references_asked
145   \fi}
146
147%D Actually there is not much difference between a text and a full reference, but
148%D it's the concept that counts. The low level implementation is:
149
150% sett top : \newinteger\lastreferenceattribute
151% sett top : \newinteger\lastdestinationattribute
152
153\def\strc_references_finish#prefix#reference#internal% gets expanded anyway
154  {\normalexpanded{\clf_deferredenhancereference{#prefix}{#reference}}}
155
156\permanent\let\dofinishreference\strc_references_finish % used at lua end
157
158%D This is somewhat tricky: we want to keep the reference with the following word but
159%D that word should also hyphenate. We need to find a better way.
160
161% 0 = nothing
162% 1 = bind to following word
163
164\setnewconstant\c_strc_references_bind_state\plusone
165
166\def\strc_references_inject_before
167  {}
168
169\def\strc_references_inject_after
170  {\ifcase\c_strc_references_bind_state
171     % nothing
172   \or
173     \prewordbreak % to be tested: \removeunwantedspaces\permithyphenation
174   \fi}
175
176\protected\def\strc_references_set_named_reference
177  {\ifreferencing
178     \expandafter\strc_references_set_named_reference_indeed
179   \else
180     \expandafter\gobblefourarguments
181   \fi}
182
183\newbox\b_strc_destination_nodes
184
185\protected\def\strc_references_flush_destination_nodes
186  {\ifvoid\b_strc_destination_nodes \else
187     \unhbox\b_strc_destination_nodes
188   \fi}
189
190\def\strc_references_placeholder
191  {\ifempty\dotaggedplaceholder\else
192     \c_attr_destination\lastdestinationattribute
193     \dotaggedplaceholder
194   \fi}
195
196\protected\def\strc_references_destination_point_yes
197  {\strc_references_inject_before % new
198   %dostarttaggednodetail\t!reference
199   \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup % \hpack
200     \strc_references_flush_destination_nodes
201     \strc_references_placeholder
202     \egroup
203   %dostoptagged
204   \strc_references_inject_after}
205
206\protected\def\strc_references_destination_point_nop
207  {\strc_references_inject_before % new
208   %\dostarttaggednodetail\t!reference
209   \dontleavehmode\hbox \bgroup % \hpack
210     \strc_references_flush_destination_nodes
211     \strc_references_placeholder
212   \egroup
213   %\dostoptagged
214   \strc_references_inject_after}
215
216\protected\def\strc_references_start_destination_nodes % messy but we need the delay
217  {\setbox\b_strc_destination_nodes\hbox\bgroup}       % also sets lastdestinationattribute
218
219\protected\def\strc_references_stop_destination_nodes
220  {\normalexpanded{\egroup\lastdestinationattribute\the\lastdestinationattribute\relax}}
221
222\protected\def\strc_references_set_named_reference_indeed#kind#labels#userdata#text% labels userdata text -> todo: userdata
223  {\ifreferencing
224     % we could have a more efficient one for page references but for the moment
225     % we don't care too much
226     \edef\currentreferencekind     {#kind}%
227     \edef\currentreferencelabels   {#labels}%
228     \edef\currentreferenceuserdata {#userdata}%
229     \edef\currentreferenceexpansion{\referencingparameter\c!expansion}% {\referenceparameter\c!expansion}
230     \ifempty\currentreferencelabels
231       \lastdestinationattribute\attributeunsetvalue
232     \else
233       \ifx\currentreferenceexpansion\s!xml
234         \xmlstartraw
235           \xdef\currentreferencedata{#text}% data, no text else conflict
236         \xmlstopraw
237         \glet\currentreferencecoding\s!xml
238       \else
239         \ifx\currentreferenceexpansion\v!yes
240           \xdef\currentreferencedata{#text}%
241         \else
242           \xdef\currentreferencedata{\detokenize{#text}}%
243         \fi
244         \glet\currentreferencecoding\s!tex
245       \fi
246       % beware, the structures.references.set writes a
247       \setnextinternalreference
248       \strc_references_start_destination_nodes
249       \clf_setdestinationattribute
250            {%
251                references {%
252                    internal  \locationcount
253                  % block     {\currentsectionblock}%
254                    view      {\interactionparameter\c!focus}%
255                \ifempty\referenceprefix\else
256                    prefix    {\referenceprefix}%
257                \fi
258                    reference {\currentreferencelabels}%
259                }%
260                metadata {%
261                    kind     {\currentreferencekind}%
262            \ifx\currentreferencekind\s!page\else
263                \ifx\currentreferencecoding\s!xml
264                    xmlroot  {\xmldocument}%
265                \fi
266                    catcodes \catcodetable
267            \fi
268                }%
269            \ifempty\currentreferencedata\else
270                entries {%
271                    text {\currentreferencedata}%
272                }%
273            \fi
274            \ifempty\currentreferenceuserdata\else
275                userdata {\detokenize{#userdata}}%
276            \fi
277            }%
278       \relax
279       \strc_references_stop_destination_nodes
280     \fi
281   \else
282     \setbox\b_strc_destination_nodes\emptyhbox
283     \lastdestinationattribute\attributeunsetvalue
284   \fi
285   % will become obsolete:
286   \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
287   % will become an option:
288   \ifnum\lastdestinationattribute>\zerocount
289     \strc_references_destination_point_yes
290   \orelse\ifvoid\b_strc_destination_nodes\else
291     \strc_references_destination_point_nop
292   \fi}
293
294\def\strc_references_set_page_only_destination_attribute#labels% could in fact be fully expandable
295  {\ifreferencing
296     \edef\currentreferencelabels{#labels}%
297     \ifempty\currentreferencelabels
298       \setbox\b_strc_destination_nodes\emptyhbox
299       \lastdestinationattribute\attributeunsetvalue
300     \else
301       \strc_references_start_destination_nodes
302       \setnextinternalreference
303       \clf_setdestinationattribute
304            {%
305                references {%
306                    internal  \locationcount
307                 %  block     {\currentsectionblock}%
308                    view      {\interactionparameter\c!focus}%
309                \ifempty\referenceprefix\else
310                    prefix    {\referenceprefix}%
311                \fi
312                    reference {\currentreferencelabels}%
313                }%
314                metadata {%
315                    kind {page}%
316                }%
317            }%
318       \relax
319       \strc_references_stop_destination_nodes
320     \fi
321   \else
322     \setbox\b_strc_destination_nodes\emptyhbox
323     \lastdestinationattribute\attributeunsetvalue
324   \fi}
325
326\protected\def\strc_references_direct_full_user#user#labels#text%
327  {\ifreferencing
328     \strc_references_start_destination_nodes
329     \setnextinternalreference
330     \edef\m_strc_references_user{#user}%
331     \edef\m_strc_references_text{#text}%
332     \clf_setdestinationattribute
333        {%
334            references {%
335                internal  \locationcount
336              % block     {\currentsectionblock}%
337                view      {\interactionparameter\c!focus}%
338            \ifempty\referenceprefix\else
339                prefix    {\referenceprefix}%
340            \fi
341                reference {#labels}%
342            }%
343            metadata {%
344                kind {\s!full}%
345            }%
346        \ifempty\m_strc_references_text \else
347            entries {%
348                text {\m_strc_references_text}%
349            }%
350        \fi
351        \ifempty\m_strc_references_user \else
352            userdata {\m_strc_references_user}% \detokenize\expandafter{\normalexpanded{...}}
353        \fi
354        }%
355     \relax
356     \strc_references_stop_destination_nodes
357   \else
358     \setbox\b_strc_destination_nodes\emptyhbox
359     \lastdestinationattribute\attributeunsetvalue
360   \fi
361   % will become obsolete:
362   \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
363   % will become an option:
364   \ifnum\lastdestinationattribute>\zerocount
365     \strc_references_destination_point_yes
366   \orelse\ifvoid\b_strc_destination_nodes\else
367     \strc_references_destination_point_nop
368   \fi}
369
370\protected\def\strc_references_direct_full
371  {\strc_references_direct_full_user\empty}
372
373\permanent\let\dodirectfullreference\strc_references_direct_full % for at lua end (no longer)
374
375\def\strc_references_set_page_only_destination_box_attribute#cs#labels%
376  {\strc_references_set_page_only_destination_attribute{#labels}%
377   \ifnum\lastdestinationattribute>\zerocount
378     \edef#cs{attr \destinationattribute\number\lastdestinationattribute}%
379   \else
380     \lettonothing#cs%
381   \fi}
382
383%D It's about time to clean up references .. stable enough now.
384
385\permanent\protected\def\boxreference[#1]%
386  {\begingroup
387   \dowithnextbox
388    {\strc_references_set_page_only_destination_attribute{#1}%
389     \hpack % \hbox
390       \ifnum\lastdestinationattribute=\attributeunsetvalue\else attr \destinationattribute \lastdestinationattribute \fi
391       {\box\b_strc_destination_nodes\box\nextbox}%
392     \endgroup}}
393
394\permanent\protected\def\hboxreference[#1]{\boxreference[#1]\hbox}
395\permanent\protected\def\vboxreference[#1]{\boxreference[#1]\vbox}
396
397\mutable\def\defaultreferencepage#text{[[[#text]]]}
398\mutable\def\defaultreferencetext#text{[[[#text]]]}
399
400%D For internal usage:
401
402\def\strc_references_set_simple_reference#label%
403  {\iflocation
404     \strc_references_start_destination_nodes
405     \setnextinternalreference
406     \clf_setdestinationattribute
407        {%
408            references {%
409                view      {\interactionparameter\c!focus}%
410            \ifempty\referenceprefix\else
411                prefix    {\referenceprefix}%
412            \fi
413                reference {#label}%
414                internal  \locationcount
415            }%
416            metadata {%
417                kind {\s!page}%
418            }%
419        }%
420     \relax
421     \strc_references_stop_destination_nodes
422     \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
423   \else
424     \setbox\b_strc_destination_nodes\emptyhbox
425     \xdef\currentdestinationattribute{\number\attributeunsetvalue}%
426   \fi}
427
428\def\strc_references_set_simple_internal_reference#label% no prefix
429  {\iflocation
430     \strc_references_start_destination_nodes
431     \setnextinternalreference
432     \clf_setdestinationattribute
433        {%
434            references {%
435                view      {\interactionparameter\c!focus}%
436                reference {#label}%
437                internal  \locationcount
438            }%
439            metadata {%
440                kind {\s!page}%
441            }%
442        }%
443     \relax
444     \strc_references_stop_destination_nodes
445     \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
446   \else
447     \setbox\b_strc_destination_nodes\emptyhbox
448     \xdef\currentdestinationattribute{\number\attributeunsetvalue}%
449   \fi}
450
451\def\strc_references_get_simple_reference#label%
452  {\iflocation
453     \clf_injectreference
454        {\referenceprefix}%
455        {#label}%
456        {%
457            height \strutht
458            depth  \strutdp
459            \extrareferencearguments
460        }%
461     \relax
462     \xdef\currentreferenceattribute{\number\lastreferenceattribute}%
463   \else
464     \xdef\currentreferenceattribute{\number\attributeunsetvalue}%
465   \fi}
466
467%D \macros
468%D   {contentreference}
469%D
470%D \starttyping
471%D \setupinteraction
472%D   [state=start,
473%D    focus=standard]
474%D
475%D \setupheader
476%D   [state=stop]
477%D
478%D  See page \goto{page 2}[page2] \page
479%D
480%D  \contentreference
481%D    [page2]
482%D    [offset=1cm,toffset=2cm,frame=on]
483%D    {\externalfigure[cow.pdf][factor=fit]}
484%D
485%D \stoptyping
486
487\permanent\tolerant\protected\def\contentreference[#1]#*[#S#2]%
488  {\ifarguments
489     \expandafter\gobbletwoarguments
490   \or
491     \expandafter\strc_references_content_pickup_nop
492   \else
493     \expandafter\strc_references_content_pickup_yes
494   \fi{#1}{#2}}
495
496\def\strc_references_content_pickup_yes#1#2%
497 {\hbox\bgroup\dowithnextbox{\strc_references_content_yes_finish{#1}{#2}}\hbox}
498
499\def\strc_references_content_pickup_nop#1#2%
500 {\hbox\bgroup\dowithnextbox{\strc_references_content_nop_finish{#1}{#2}}\hbox}
501
502\def\strc_references_content_yes_finish#1#2%
503  {\scratchwidth \wd\nextbox
504   \scratchheight\ht\nextbox
505   \scratchdepth \dp\nextbox
506   \setbox\nextbox\hpack
507     {\framed[\c!frame=\v!off,#2]{\box\nextbox}}%
508   \strc_references_set_simple_reference{#1}%
509   \setbox\nextbox\hpack attr \destinationattribute \currentdestinationattribute % \hpack ?
510     {\strc_references_flush_destination_nodes
511      \box\nextbox}%
512   \setbox\nextbox\hpack{\box\nextbox}%
513   \wd\nextbox\scratchwidth
514   \ht\nextbox\scratchheight
515   \dp\nextbox\scratchdepth
516   \box\nextbox
517   \egroup}
518
519\def\strc_references_content_nop_finish#1#2%
520  {\strc_references_set_simple_reference{#1}%
521   \hpack attr \destinationattribute \currentdestinationattribute % \hpack ?
522     {\strc_references_flush_destination_nodes
523      \box\nextbox}%
524   \egroup}
525
526%D \macros
527%D   {everyreference}
528%D
529%D For rather tricky purposes, one can assign sanitizing macros to \type
530%D {\everyreference} (no longer that relevant).
531
532\newevery \everyreference \relax
533
534%D This is really needed, since for instance Polish has a different alphabet and
535%D needs accented entries in registers.
536
537\appendtoks
538    \cleanupfeatures
539\to \everyreference
540
541%D We did not yet discuss prefixing. Especially in interactive documents, it's not
542%D always easy to keep track of duplicate references. The prefix mechanism, which we
543%D will describe later on, solves this problem. By (automatically) adding a prefix
544%D one keeps references local, but the global ones in view. To enable this feature,
545%D we explictly split the prefix from the reference.
546
547\lettonothing\referenceprefix
548
549%D For a long time the only way to access an external file was to use the file
550%D prefix (\type {somefile::}. However, when you split up a document, redefining the
551%D references may be such a pain, that another approach is feasible. By setting the
552%D \type {autofile} variable to \type {yes} or \type {page}, you can access the
553%D reference directly.
554%D
555%D \starttabulate[||||]
556%D \NC filename::tag \NC page(filename::pnum) \NC tag     \NC\NR
557%D \NC   $\star$     \NC                      \NC         \NC\NR
558%D \NC   $\star$     \NC $\star$              \NC $\star$ \NC\NR
559%D \NC               \NC $\star$              \NC         \NC\NR
560%D \stoptabulate
561
562% \permanent\protected\def\usereferences[#filename]{} % defined at the lua end
563
564%D As mentioned we will also use the cross reference mechanism for navigational
565%D purposes. The main reason for this is that we want to treat both categories
566%D alike:
567%D
568%D \starttyping
569%D \goto{go back}[PreviousJump]
570%D \goto{colofon}[colofon page]
571%D \stoptyping
572%D
573%D Here \type{PreviousJump} is handled by the viewer, while the
574%D \type{colofon page} reference is, apart from hyperlinking, a
575%D rather normal reference.
576%D
577%D We already saw that cross refences are written to and read from a file. The pure
578%D navigational ones don't need to be written to file, but both for fast processing
579%D and transparant integration, they are saved internally as a sort of reference. We
580%D can easily distinguish such system references from real cross reference ones by
581%D their tag.
582%D
583%D We also use the odd/even characteristic to determine the page state.
584
585\mutable\lettonothing\currentrealreference
586\mutable\lettonothing\currentpagereference
587\mutable\lettonothing\currenttextreference
588\mutable\lettonothing\currentsubtextreference
589\mutable\lettonothing\currentsubsubtextreference
590
591% referencepagestate:
592%
593% 0 = no page ref, 1=same page, 2=before, 3=after
594
595%D Cross references appear as numbers (figure~1.1, chapter~2) or pagenumbers
596%D (page~2, page 3--2), and are called with \type {\in} and \type {\at}. In
597%D interactive documents we also have \type {\goto}, \type {\button} and alike.
598%D These are more versatile and look like:
599%D
600%D \starttyping
601%D \goto[reference]
602%D \goto[outer reference::]
603%D \goto[outer reference::inner reference]
604%D \goto[operation(argument)]
605%D \goto[operation(action{argument,argument})]
606%D \goto[action]
607%D \goto[action{argument}]
608%D \stoptyping
609%D
610%D The first one is a normal reference, the second and third are references to a
611%D file or \URL. The brace delimited references for instance refer to a \JAVASCRIPT.
612%D The last example shows that we can pass arguments to the actions.
613%D
614%D Now we've come to the testing step. As we can see below, this macro does bit more
615%D than testing: it also resolves the reference. This means that whenever we test
616%D for the existance of a reference at an outer level, we have all the relevant
617%D properties of that reference avaliable inside the true branche~(\type {#2}).
618%D
619%D The prefix has to do with localizing references. When a prefix is set, looking
620%D for a reference comes to looking for the prefixed one, and when not found,
621%D looking for the non prefixed one. Consider for instance the prefix set to \type
622%D {sidetrack}.
623%D
624%D \starttyping
625%D \pagereference[important]
626%D \pagereference[unimportant]
627%D \setupreferencing[prefix=sidetrack]
628%D \pagereference[important]
629%D \stoptyping
630%D
631%D results in saving (writing) the references
632%D
633%D \starttyping
634%D ...{}{important}
635%D ...{}{unimportant}
636%D ...{sidetrack}{important}...
637%D \stoptyping
638%D
639%D Now when we call for \type{unimportant}, we will indeed get the pagenumber
640%D associated to this reference. But when we call for \type{important}, while the
641%D prefix is still set, we will get the pagenumber bound to the prefixed one.
642%D
643%D {\em Some day, when processing time and memory are no longer
644%D performance factors, we will introduce multi||level
645%D prefixes.}
646%D
647%D Before we start analyzing, I introduce a general definition macro. Consider:
648%D
649%D \starttyping
650%D \goto{do}[JS(My_Script{"test",123}),titlepage]
651%D \stoptyping
652%D
653%D This can also be achieved by:
654%D
655%D \starttyping
656%D \definereference[startup][JS(My_Script{"test",123}),titlepage]
657%D \goto{do}[startup]
658%D \stoptyping
659%D
660%D Now is this is a handy feature or not?
661%D
662%D \showsetup{definereference}
663%D
664%D We can trace references by setting the next switch to true.
665
666\permanent\tolerant\protected\def\definereference[#name]#spacer[#S#specification]%
667  {\clf_definereference{\referenceprefix}{#name}{\detokenize{#specification}}}
668
669\permanent\protected\def\resetreference[#name]%
670  {\clf_resetreference{\referenceprefix}{#name}}
671
672\permanent\def\setpagereference#name#specification% hm,. low level ?
673  {\clf_definereference{}{#name}{\v!page(\detokenize{#specification}}} % is detokenize needed here?
674
675%D Chained references are defined as:
676%D
677%D \starttyping
678%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)]
679%D \stoptyping
680%D
681%D Actually supporting chains is up to the special driver. Here we only provide the
682%D hooks.
683
684%D \macros
685%D   {highlighthyperlinks}
686%D
687%D The next switch can be used to make user hyperlinks are not highlighted when
688%D clicked on.
689
690\newconditional\highlighthyperlinks \highlighthyperlinks\conditionaltrue
691
692%D \macros
693%D   {gotonewwindow}
694%D
695%D To make the {\em goto previous jump} feature more convenient when using more than
696%D one file, it makes sense to force the viewer to open a new window for each file
697%D opened.
698
699\newconditional\gotonewwindow \gotonewwindow\conditionalfalse
700
701\permanent\def\doifelsereferencefound#label%
702  {\clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}}
703
704\aliased\let\doifreferencefoundelse\doifelsereferencefound
705
706\permanent\def\doifelsereferencechecked#label%
707  {\clf_doifelsereferencechecked{\referenceprefix}{#label}{\extrareferencearguments}}
708
709\aliased\let\doifcheckedreferencefoundelse\doifelsereferencechecked
710
711%D The tester only splits the reference in components but does not look into them.
712%D The following macro does a preroll and determines for instance the current real
713%D reference pagenumber. The \type {\currentrealreference} macro does the same so
714%D unless one wants to use the pagestate the next macro seldom needs to be called.
715%D
716%D The inner case is simple. Only two cases have to be taken
717%D care of:
718%D
719%D \starttyping
720%D \goto{some text}[reference]
721%D \goto{some text}[prefix:reference]
722%D \stoptyping
723%D
724%D References to other files however are treated strict or tolerant, depending on
725%D their loading and availability:
726%D
727%D \starttyping
728%D \useexternaldocument[somefile][filename][a nice description]
729%D
730%D \goto{checked   reference}[somefile::reference]
731%D \goto{unchecked reference}[somefile::]
732%D \goto{unchecked reference}[anotherfile::reference]
733%D \stoptyping
734%D
735%D An unknown reference is reported on the screen, in the log file and, when
736%D enabled, in the left margin of the text.
737
738\mutable\let\unknownreference\gobbleoneargument
739
740%D When a reference is not found, we typeset a placeholder (two glyphs are often
741%D enough to represent the reference text).
742
743% \askedreference defined in lua
744
745\mutable\def\dummyreference{{\tttf ??}}
746\mutable\def\emptyreference{{\tttf !!}}
747
748\installtextracker
749  {structures.referencing.show}
750  {\let\strc_references_dummy\strc_references_dummy_yes}
751  {\let\strc_references_dummy\strc_references_dummy_nop}
752
753\def\strc_references_dummy_nop
754  {\dummyreference}
755
756\def\strc_references_dummy_yes
757  {\dummyreference
758   \margindata
759     [\referencingparameter\c!labelalternative]% alternative?
760     [\c!style=\referencingparameter\c!labelstyle,
761      \c!color=\referencingparameter\c!labelcolor]
762     {\askedreference}}
763
764\let\strc_references_dummy\strc_references_dummy_nop
765
766\setupreferencing
767  [\c!labelalternative=\v!inleft,
768         \c!labelcolor=darkred,
769         \c!labelstyle=\smallinfofont]
770
771%D To prevent repetitive messages concerning a reference being defined, we set such
772%D an unknown reference to an empty one after the first encounter.
773%D
774%D Apart from cross references supplied by the user, \CONTEXT\ generates cross
775%D references itself. Most of them are not saved as a reference, but stored with
776%D their source, for instance a list or an index entry. Such automatically
777%D generated, for the user invisible, references are called {\em internal
778%D references}. The user supplied ones are labeled as {\em external references}.
779%D
780%D A second important characteristic is that when we want to support different
781%D backends (viewers), we need to support named destinations as well as page
782%D numbers. I invite readers to take a glance at the special driver modules to
783%D understand the fine points of this. As a result we will deal with {\em locations}
784%D as well as {\em real page numbers}. We explictly call this pagenumber a real one,
785%D because it is independant of the page numbering scheme used in the document.
786%D
787%D One of the reasons for \CONTEXT\ being the first \TEX\ base macropackage to
788%D support sophisticated interactive \PDF\ files, lays in the mere fact that real
789%D page numbers are available in most two pass data, like references, list data and
790%D index entries.
791%D
792%D We will speak of \type {thisis...} when we are marking a location, and
793%D \type {goto...} when we point to such a location. The latter one can be seen as a
794%D hyperlink to the former one. In the next macros one we use constructs like:
795%D
796%D \starttyping
797%D \dostart...
798%D \dostop...
799%D \stoptyping
800%D
801%D The flag \type {\iflocation} signals if we're in interactive mode.
802
803\ifdefined\buttonheight \else \newdimension\buttonheight \fi
804\ifdefined\buttonwidth  \else \newdimension\buttonwidth  \fi
805
806%D Internal references can best be set using the next few macros. Setting such
807%D references to unique values is completely up to the macros that call them.
808%D
809%D \starttyping
810%D \thisissomeinternal{tag}{identifier}
811%D \gotosomeinternal  {tag}{identifier}{pagenumber}{text}
812%D \stoptyping
813%D
814%D We could do this in \LUA\ \unknown
815
816% seet top: \newif     \iflocation
817% seet top: \newinteger\locationcount
818% seet top: \newinteger\locationorder
819% seet top: \newbox    \locationbox
820
821\appendtoks
822    \locationfalse
823\to \everypreroll
824
825\permanent\def\nextinternalreference     {\the\locationcount}
826\permanent\def\nextinternalorderreference{\the\locationorder}
827
828\permanent\def\setnextinternalreference
829  {\global\advanceby\locationcount\plusone}
830
831% defined at the lua end
832%
833% \permanent\def\setnextinternalreferences#kind#name% plural
834%   {\clf_setnextinternalreference{#kind}{#name}}
835%
836% \permanent\def\getinternalorderreference#kind#name%
837%   {\clf_currentreferenceorder{#kind}{#name}}
838
839\permanent\def\thisissomeinternal#kind#name% only for old time sake, will go away
840  {\begingroup
841   \clf_setinternalreference
842     reference {#kind:#name}% no view
843   \relax
844   \hpack attr \destinationattribute\lastdestinationattribute{}%
845   \endgroup}
846
847\installcorenamespace{savedinternalreference}
848
849\letcsname\??savedinternalreference\s!default\endcsname\!!zerocount
850
851\permanent\protected\def\storeinternalreference#1#2%
852  {\xdefcsname\??savedinternalreference\currentstructurename\endcsname{\number#2}}
853
854\newconditional\preferpagereferences
855
856\permanent\def\gotosomeinternal#kind#name#target#text%
857  {\ifconditional\preferpagereferences
858     \directgoto{#text}[page(#target)]%
859   \else
860     \directgoto{#text}[#kind:#name]%
861   \fi}
862
863\permanent\def\gotonextinternal#text#target%
864  {\directgoto{#text}[internal(#target)]}
865
866%D In this module we define three system references: one for handling navigational,
867%D viewer specific, commands, another for jumping to special pages, like the first
868%D or last one, and a third reference for linking tree like lists, like tables of
869%D contents. The latter two adapt themselves to the current state.
870%D
871%D An example of an action is:
872%D
873%D \starttyping
874%D \goto{some action}[PreviousJump]
875%D \stoptyping
876%D
877%D as well as:
878%D
879%D \starttyping
880%D \goto{some text}[\v!action(PreviousJump]
881%D \stoptyping
882%D
883%D One can also activate an automatic prefix mechanism. By setting the
884%D \type {\prefix} variable to \type {+}, the prefix is incremented, when set to
885%D \type {-} or empty, the prefix is reset. Other values become the prefix.
886
887% \see top: newinteger\prefixcounter
888
889\newconditional\autocrossfilereferences
890
891\appendtoks
892    \ifcstok{\referencingparameter\c!autofile}\v!yes
893      \autocrossfilereferences\conditionaltrue
894    \else
895      \autocrossfilereferences\conditionalfalse
896    \fi
897\to \everysetupreferencing
898
899\appendtoks
900    \ifcstok{\referencingparameter\c!export}\v!yes
901      \clf_exportreferences
902    \fi
903\to \everygoodbye
904
905\permanent\protected\def\setupglobalreferenceprefix[#prefix]%
906  {\xdef\referenceprefix{#prefix}}
907
908\permanent\protected\def\globalpushreferenceprefix#prefix%
909  {\xdef\referenceprefix{\clf_pushreferenceprefix{#prefix}}}
910
911\permanent\protected\def\globalpopreferenceprefix
912  {\xdef\referenceprefix{\clf_popreferenceprefix}}
913
914\permanent\protected\def\pushreferenceprefix#prefix%
915  {\edef\referenceprefix{\clf_pushreferenceprefix{#prefix}}}
916
917\permanent\protected\def\popreferenceprefix
918  {\edef\referenceprefix{\clf_popreferenceprefix}}
919
920\def\m_strc_references_prefix_yes{+}
921\def\m_strc_references_prefix_nop{-}
922
923\permanent\protected\def\setupreferenceprefix[#prefix]%
924  {\edef\p_prefix{#prefix}%
925   \ifempty\p_prefix
926     \lettonothing\referenceprefix
927   \orelse\ifx\p_prefix\m_strc_references_prefix_yes
928     \letreferencingparameter\c!prefix\s!unknown
929     \global\advanceby\prefixcounter\plusone
930     \edef\referenceprefix{\the\prefixcounter}%
931   \orelse\ifx\p_prefix\m_strc_references_prefix_nop
932     \letreferencingparameter\c!prefix\s!unknown
933     \lettonothing\referenceprefix
934   \orelse\ifx\p_prefix\s!unknown
935     % forget about it
936   \else
937     \let\referenceprefix\p_prefix
938   \fi}
939
940\appendtoks
941    \setupreferenceprefix[\referencingparameter\c!prefix]
942\to \everysetupreferencing
943
944%D We can typeset a reference using \type {\in}, \type {\at} and \type {\about} and
945%D goto specific locations using \type {\goto}. The last one does not make that much
946%D sense in a paper document. To complicate things, \PLAIN\ \TEX\ also implements an
947%D \type {\in} but fortunately that one only makes sense in math mode.
948%D
949%D Typesetting the reference is a bit more complicated than one would at first sight
950%D expect. This is due to the fact that we distinguish three (five) alternative
951%D calls:
952%D
953%D \placefigure
954%D   [here][three calls]
955%D   {Three alternatives reference calls.}
956%D   {\startcombination[1*3]
957%D      {\framed{\type{ \in }}} {a}
958%D      {\framed{\type{ \at }}} {b}
959%D      {\framed{\type{\goto}}} {c}
960%D    \stopcombination}
961%D
962%D \startbuffer
963%D \in figure[fig:three calls]
964%D \in{figure}[fig:three calls]
965%D \in figure a[fig:three calls]
966%D \in{figure}{a}[fig:three calls]
967%D figure~\in[fig:three calls]
968%D \stopbuffer
969%D
970%D \typebuffer
971%D
972%D This turns up as:
973%D
974%D \startlines
975%D \getbuffer
976%D \stoplines
977%D
978%D The dual \type {{}} results in a split reference. In a document meant for paper,
979%D one is tempted to use the last (most straightforward) alternative. When a
980%D document is also meant voor electronic distribution, the former alternatives have
981%D preference, because everything between the \type {\in} and~\type {[} becomes
982%D active (and when asked for, typeset in a different color and typeface).
983
984\appendtoks
985    % likely math
986    \ifdefined\in    \aliased\let\normalmathin   \in    \permanent\protected\def\in   {\mathortext\normalmathin   \strc_references_in   } \else \aliased\let\in   \strc_references_in    \fi
987    \ifdefined\over  \aliased\let\normalmathover \over  \permanent\protected\def\over {\mathortext\normalmathover \strc_references_about} \else \aliased\let\over \strc_references_about \fi
988    %
989  % \ifdefined\at    \aliased\let\normalmathat   \at    \permanent\protected\def\at   {\mathortext\normalmathat   \strc_references_at   } \else \aliased\let\at   \strc_references_at    \fi
990  % \ifdefined\about \aliased\let\normalmathabout\about \permanent\protected\def\about{\mathortext\normalmathabout\strc_references_about} \else \aliased\let\about\strc_references_about \fi
991  % \ifdefined\from  \aliased\let\normalmathfrom \from  \permanent\protected\def\from {\mathortext\normalmathfrom \strc_references_from } \else \aliased\let\from \strc_references_from  \fi
992    \aliased\let\at   \strc_references_at
993    \aliased\let\about\strc_references_about
994    \aliased\let\from \strc_references_from
995\to \everydump
996
997% can be defined visible at lua end
998
999\permanent          \def\filterreference  #key{\clf_filterreference{#key}} % no checking, expandable
1000\permanent\protected\def\getreferenceentry#key{\clf_filterreference{#key}} % no checking, not expandable
1001
1002\permanent\def\currentreferencenumber  {\clf_filterreference{number}}
1003\permanent\def\currentreferencepage    {\clf_filterreference{page}}
1004\permanent\def\currentreferencetitle   {\clf_filterreference{title}}
1005\permanent\def\currentreferencetext    {\clf_filterreference{text}}
1006%permanent\def\currentreferencedefault {\clf_filterreference{default}}
1007\permanent\def\currentreferencerealpage{\clf_filterreference{realpage}}
1008\aliased  \let\currentreferenceorder    \getinternalorderreference
1009
1010%D The most straightforward way of retrieving references is using \type {\ref}.
1011
1012\permanent\tolerant\protected\def\getreference[#key]#spacer[#label]% #key = number page title text default realpage ...
1013  {\ifarguments\or
1014     \strc_references_dummy
1015   \else
1016     \doifelsereferencefound{#label}{\clf_filterreference{#key}}\strc_references_dummy
1017   \fi}
1018
1019\aliased\let\ref\getreference
1020
1021% setnumber-001.tex
1022%
1023% \starttext
1024%     \chapter[one]{One} see setnumber-002
1025%     \chapter[two]{Two} see setnumber-002
1026% \stoptext
1027%
1028% setnumber-002.tex
1029%
1030% \setupreferencing[autofile=yes]
1031% \useexternaldocument[foo] [setnumber-001] [{TEST 1}]
1032% \setupheadnumber[chapter][\getreferencesectionnumber{foo::two}]
1033% \starttext
1034%     \chapter[three]{Three} from setnumber-001, one: \getreferencesectionnumber{foo::one}\par
1035%     \chapter[four] {Four}  from setnumber-001, two: \getreferencesectionnumber{foo::two}\par
1036% \stoptext
1037%
1038% \getreferencesectionnumber{reference} : defined at the lua end
1039
1040%D Special cases:
1041
1042\permanent\protected\def\strc_references_about[#label]%
1043  {\dontleavehmode
1044   \begingroup
1045   \enforced\let\crlf\space
1046   \enforced\let\\\space
1047   \postponenotes % might go
1048   \referencingparameter\c!left
1049   \doifelsereferencefound{#label}
1050     {\goto{\limitatetext\currentreferencetitle{\dimexpr\referencingparameter\c!width\relax}\unknown}[#label]}% not so efficient (dup lookup)
1051     {}% todo
1052   \flushnotes % might go
1053   \referencingparameter\c!right
1054   \endgroup}
1055
1056%D The previously discussed setup macro lets us specify the representation of
1057%D references. A symbol reference does not show the specific data, like the number
1058%D of a figure, but shows one of: \hbox {$^\goforwardcharacter$
1059%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending on the direction to
1060%D go.
1061%D
1062%D \starttyping
1063%D ... \somewhere{backward text}{forward text}[someref] ...
1064%D ... \atpage[someref] ...
1065%D \stoptyping
1066
1067% standard      detail
1068%
1069% 0 = unknown   unknown
1070% 1 = same      on same page
1071% 2 = before    preceding page
1072% 3 = after     following page
1073%
1074% 4 = above     above on same page
1075% 5 = below     below on same page
1076
1077% todo: optimize for use in pagebody
1078% todo: maybe make it optional
1079
1080% \setuppagenumbering[alternative=doublesided]
1081% \setupreferencing  [doublesided=no] % yes is default
1082%
1083% \somewhere{backward}{foreward}[label]
1084% \someplace{preceding}{backward}{current}{foreward}{following}[label]
1085% \atpage[#label]
1086% \doifcheckedpagestate{label}{preceding}{backward}{current}{foreward}{following}{otherwise}
1087%
1088% \dorecurse {20} {
1089%     \placefigure[here][fig:#1]{}{\externalfigure[dummy]}
1090%     \dorecurse {20} {
1091%         ##1: \atpage[fig:##1] /
1092%         \doifcheckedpagestate
1093%             {fig:##1}
1094%             {preceding}{backward}{current}{foreward}{following}
1095%             {otherwise}
1096%     }
1097% }
1098
1099\newinteger    \nofreferencestates
1100\newconditional\pagestatespread
1101
1102\appendtoks
1103    \ifcstok{\referencingparameter\c!doublesided}\v!yes
1104        \pagestatespread\conditionaltrue
1105    \else
1106        \pagestatespread\conditionalfalse
1107    \fi
1108\to \everysetupreferencing
1109
1110\setupreferencing
1111  [\c!doublesided=\v!yes]
1112
1113\permanent\def\referencepagestate
1114  {\numexpr\clf_referencepagestate
1115     {rst::\number\nofreferencestates}%
1116   \relax}
1117
1118\permanent\def\referencepagedetail
1119   {\numexpr\clf_referencepagedetail
1120      {rst::\number\nofreferencestates}%
1121      true %
1122      \ifconditional\pagestatespread false\ifdoublesided true\else false\fi\fi
1123    \relax}
1124
1125\permanent\def\referencerealpage    {\clf_referencerealpage} % todo: no need for wrapping
1126\permanent\def\referencecolumnnumber{\clf_referencecolumn}   % todo: no need for wrapping
1127
1128% So we need : instead of \ but that's only lmtx:
1129%
1130% \def\referencecolumnnumber
1131%   {\numexpr\dimexpr\clf_referenceposx-\cutspace\relax:\dimexpr\makeupwidth/\nofcolumns\relax+\plusone\relax}
1132%
1133% Tacos patch of the older one, kept here as illustration
1134%
1135% \def\referencecolumnnumber
1136%   {\numexpr
1137%       \dimexpr\clf_referenceposx-\cutspace-\makeupwidth/(2*\nofcolumns)\relax
1138%      /\dimexpr                             \makeupwidth/   \nofcolumns \relax
1139%      +\plusone
1140%    \relax}
1141
1142
1143\permanent\protected\def\tracedpagestate
1144  {{\blue\tttf(\ifcase\referencepagedetail unknown\or same\or previous\or next\or above\or below\else unknown\fi)}}
1145
1146\permanent\protected\def\markreferencepage
1147  {\dontleavehmode\begingroup
1148   \iftrialtypesetting
1149     % issue warning that not stable
1150   \else
1151     % needs checking ... but probably never in trialmode
1152     \global\advanceby\nofreferencestates\plusone
1153     \xypos{rst::\number\nofreferencestates}%
1154     % \tracedpagestate
1155   \fi
1156   \endgroup}
1157
1158\permanent\protected\def\doifcheckedpagestate#label% #preceding#backward#current#foreward#following#otherwise%
1159  {\doifelsereferencefound{#label}\strc_references_handle_page_state_yes\strc_references_handle_page_state_nop}
1160
1161\let\strc_references_handle_page_state_nop\sixthofsixarguments
1162
1163\def\strc_references_handle_page_state_yes
1164  {\markreferencepage
1165   \ifcase\referencepagedetail\relax
1166     \expandafter\sixthofsixarguments \or
1167     \expandafter\thirdofsixarguments \or
1168     \expandafter\firstofsixarguments \or
1169     \expandafter\fifthofsixarguments \or
1170     \expandafter\secondofsixarguments\or
1171     \expandafter\fourthofsixarguments\else
1172     \expandafter\sixthofsixarguments \fi}
1173
1174\permanent\protected\def\referencesymbol
1175  {\hpack\bgroup
1176     \strut
1177     \markreferencepage
1178     \high
1179       {\setupsymbolset[\interactionparameter\c!symbolset]%
1180        \symbol[\ifcase\referencepagedetail\v!somewhere\or\v!nowhere\or\v!previous\or\v!next\or\v!previous\or\v!next\else\v!somewhere\fi]}%
1181   \egroup}
1182
1183%D Hereafter the \type {\ignorespaces} binds the state node to next character (more likely
1184%D than a preceding one) and one can always add an explicit space.
1185
1186\permanent\protected\def\somewhere#backward#foreward#dummy[#label]% #dummy gobbles space around #foreward
1187  {\doifcheckedpagestate{#label}%
1188     {\goto{#backward}[#label]}%
1189     {\goto{#backward}[#label]}%
1190     {\ignorespaces}%
1191     {\goto{#foreward}[#label]}%
1192     {\goto{#foreward}[#label]}%
1193     {#label}}%
1194
1195\permanent\protected\def\someplace#preceding#backward#current#foreward#following#dummy[#label]% #dummy gobbles space around #foreward
1196  {\doifcheckedpagestate{#label}%
1197     {\ifempty{#preceding}\goto{#preceding}[#label]\fi\ignorespaces}%
1198     {\ifempty {#backward}\goto {#backward}[#label]\fi\ignorespaces}%
1199     {\ifempty  {#current}\goto  {#current}[#label]\fi\ignorespaces}%
1200     {\ifempty {#foreward}\goto {#foreward}[#label]\fi\ignorespaces}%
1201     {\ifempty{#following}\goto{#following}[#label]\fi\ignorespaces}%
1202     {#label}}
1203
1204\permanent\protected\def\atpage[#label]% todo
1205  {\doifcheckedpagestate{#label}%
1206     {\goto{\labeltext\v!precedingpage}[#label]}%
1207     {\goto{\labeltext\v!hencefore}[#label]}%
1208     {\ignorespaces}%
1209     {\goto{\labeltext\v!hereafter}[#label]}%
1210     {\goto{\labeltext\v!followingpage}[#label]}%
1211     {\goto{\labeltexts\v!page\strc_references_dummy}[#label]}}
1212
1213% Someone requested this but in retrospect didn't need it so we keep it as example.
1214% Beware: a node is injected which is why we add ignorespaces!
1215%
1216% \protected\def\strc_references_conditional#action#text[#condition]#dummy[#label]%
1217%   {\doifcheckedpagestate{#label}%
1218%      {\ifempty{#condition}\v!precedingpage#action{#text}[#label]\fi\ignorespaces}%
1219%      {\ifempty{#condition}\v!hencefore    #action{#text}[#label]\fi\ignorespaces}%
1220%      {\ifempty{#condition}\v!current      #action{#text}[#label]\fi\ignorespaces}%
1221%      {\ifempty{#condition}\v!hereafter    #action{#text}[#label]\fi\ignorespaces}%
1222%      {\ifempty{#condition}\v!followingpage#action{#text}[#label]\fi\ignorespaces}%
1223%      {#label}}
1224%
1225% \protected\def\conditionalat   {\strc_references_conditional\at}
1226% \protected\def\conditionalin   {\strc_references_conditional\in}
1227% \protected\def\conditionalabout{\strc_references_conditional\about}
1228
1229%D The other alternatives just conform their names: only the label, only the text, or the
1230%D label and the text.
1231
1232% \dounknownreference -> \dummyreference
1233
1234\permanent\def\symbolreference[#label]% for old times sake
1235  {\goto{\referencesymbol}[#label]}
1236
1237% \referencecontentmode 0=all 1=label 2=text 3=symbol
1238
1239\newtoks\leftreferencetoks
1240\newtoks\rightreferencetoks
1241\newtoks\defaultleftreferencetoks
1242\newtoks\defaultrightreferencetoks
1243
1244\permanent\lettonothing\rightofreferencecontent
1245\permanent\lettonothing\leftofreference
1246\permanent\lettonothing\rightofreference
1247
1248\permanent\protected\def\leftofreferencecontent
1249  {\removeunwantedspaces
1250   \nonbreakablespace
1251   \ignorespaces}
1252
1253\installcorenamespace{referencinginteraction}
1254
1255\def\strc_references_interaction_all
1256  {\ifempty\leftreferencetoks
1257     \leftofreference
1258   \else
1259     \expand\leftreferencetoks
1260     \leftofreferencecontent
1261     \leftofreference
1262     \onlynonbreakablespace\relax % new, replace space by nonbreakable if present
1263   \fi
1264   \currentreferencecontent
1265   \rightofreference
1266   \ifempty\rightreferencetoks\else
1267     \rightofreferencecontent
1268     \expand\rightreferencetoks
1269   \fi}
1270
1271\letcsname\??referencinginteraction\v!all\endcsname\strc_references_interaction_all
1272
1273\defcsname\??referencinginteraction\v!label\endcsname
1274  {\leftofreference
1275   \expand\leftreferencetoks
1276   \expand\rightreferencetoks
1277   \rightofreference}
1278
1279\defcsname\??referencinginteraction\v!text\endcsname
1280  {\leftofreference
1281   \currentreferencecontent
1282   \rightofreference}
1283
1284\defcsname\??referencinginteraction\v!symbol\endcsname
1285  {\referencesymbol}
1286
1287\permanent\def\referencesequence
1288  {\ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname
1289     \expandafter\lastnamedcs
1290   \else
1291     \expandafter\strc_references_interaction_all
1292   \fi}
1293
1294\newtoks\everyresetinatreference
1295
1296\appendtoks
1297    \enforced\glet\leftofreference \relax
1298    \enforced\glet\rightofreference\relax
1299\to \everyresetinatreference
1300
1301\def\strc_references_start_goto
1302  {\dontleavehmode
1303   \begingroup}
1304
1305\def\strc_references_stop_goto
1306  {\expand\everyresetinatreference
1307   \endgroup}
1308
1309% NEEDS TESTING:
1310
1311\tolerant\def\strc_references_pickup_goto#=#*#=#:#*[#3]% #* added so that we can do \in {} {} []
1312  {\leftreferencetoks
1313     \ifparameter#1\or
1314       {#1}%
1315     \else
1316       \defaultleftreferencetoks
1317       \enforced\lettonothing\leftofreferencecontent
1318     \fi
1319   \rightreferencetoks
1320     \ifparameter#2\or
1321       {#2}%
1322     \else
1323       \defaultrightreferencetoks
1324       \enforced\lettonothing\rightofreferencecontent
1325     \fi
1326   % inefficient: double resolve
1327   \doifelsereferencefound{#3} % we need to resolve the text
1328     {\goto{\referencesequence}[#3]}
1329     {\let\currentreferencecontent\strc_references_dummy
1330      \goto{\referencesequence}[#3]}%
1331   \strc_references_stop_goto}
1332
1333\permanent\protected\def\strc_references_in
1334  {\strc_references_start_goto
1335   \let\currentreferencecontent\currentreferencedefault
1336   \strc_references_pickup_goto}
1337
1338\permanent\protected\def\strc_references_at
1339  {\strc_references_start_goto
1340   \let\currentreferencecontent\currentreferencepage
1341   \strc_references_pickup_goto}
1342
1343%D \macros
1344%D   {definereferenceformat}
1345%D
1346%D The next few macros were made for for David Arnold and Taco Hoekwater. They can
1347%D be used for predefining reference texts, and thereby stimulate efficiency.
1348%D
1349%D \starttyping
1350%D \definereferenceformat[informula]  [left=(,right=),text=formula]
1351%D \definereferenceformat[informulas] [left=(,right=),text=formulas]
1352%D \definereferenceformat[andformula] [left=(,right=),text=and]
1353%D \definereferenceformat[andformulas][left=(,right=),text=and]
1354%D
1355%D \informula [b] and \informula [for:c]
1356%D the \informula {formulas}[b] \informula {and} [for:c]
1357%D the \informulas {formulas}[b] \informula {and} [for:c]
1358%D the \informulas [b] \informula {en} [for:c]
1359%D the \informulas [b] \andformula [for:c]
1360%D \stoptyping
1361%D
1362%D Instead of a text, one can specify a label, which should be defined with \type
1363%D {\setuplabeltext}.
1364%D
1365%D Watch out: the second argument is somewhat special and mostly meant for a suffix
1366%D to a number:
1367%D
1368%D \startbuffer
1369%D \definereferenceformat [intesta] [left=(,right=),text=Whatever~]
1370%D \definereferenceformat [intestb] [left=(,right=),label=figure]
1371%D
1372%D \placeformula[x]\startformula a \stopformula
1373%D
1374%D \starttabulate[|||||]
1375%D \NC \in     [x] \NC \in     {left}[x] \NC \in     {}{right}[x] \NC \in     {left}{right}[x] \NC \NR
1376%D \NC \intesta[x] \NC \intesta{left}[x] \NC \intesta{}{right}[x] \NC \intesta{left}{right}[x] \NC \NR
1377%D \NC \intestb[x] \NC \intestb{left}[x] \NC \intestb{}{right}[x] \NC \intestb{left}{right}[x] \NC \NR
1378%D \stoptabulate
1379%D \stopbuffer
1380%D
1381%D \typebuffer \getbuffer
1382
1383% to be done: interfaced
1384
1385\installcorenamespace{referenceformat}
1386
1387\installcommandhandler \??referenceformat {referenceformat} \??referenceformat
1388
1389\appendtoks
1390    \frozen\instance\protected\edefcsname\currentreferenceformat\endcsname{\strc_references_apply_format{\currentreferenceformat}}%
1391\to \everydefinereferenceformat
1392
1393\setupreferenceformat
1394  [\c!left=,
1395   \c!right=,
1396   \c!text=,
1397   \c!label=,
1398   \c!autocase=\v!no,
1399   \c!style=,
1400   \c!type=default, % to be done: interfaced
1401   \c!setups=,
1402   \c!color=]
1403
1404\protected\def\strc_references_apply_format#name%
1405  {\strc_references_start_goto
1406   \edef\currentreferenceformat{#name}%
1407   \enforced\gdef\leftofreference      {\referenceformatparameter\c!left    }%
1408   \enforced\gdef\rightofreference     {\referenceformatparameter\c!right   }%
1409   \edef\currentreferenceformatlabel   {\referenceformatparameter\c!label   }%
1410   \edef\currentreferenceformattype    {\referenceformatparameter\c!type    }%
1411   \edef\currentreferenceformatsetups  {\referenceformatparameter\c!setups  }%
1412   \edef\currentreferenceformatautocase{\referenceformatparameter\c!autocase}%
1413   \usereferenceformatstyleandcolor\c!style\c!color
1414   \ifempty\currentstyleparameter \else
1415     \resetinteractionstyle
1416   \fi
1417   \ifempty\currentcolorparameter \else
1418     \resetinteractioncolor
1419   \fi
1420   \ifx\currentreferenceformatlabel\wildcardsymbol
1421      \let\currentreferenceformatlabel\autoreferencelabeltext
1422   \fi
1423   \ifempty\currentreferenceformatlabel
1424     \defaultleftreferencetoks {\referenceformatparameter\c!text}%
1425     \defaultrightreferencetoks\emptytoks
1426   \else
1427     \defaultleftreferencetoks {\leftlabeltext \currentreferenceformatlabel}%
1428     \defaultrightreferencetoks{\rightlabeltext\currentreferenceformatlabel}%
1429   \fi
1430   \ifempty\currentreferenceformattype
1431     \def\currentreferenceformattype{default}%
1432   \fi
1433   %
1434   \ifempty\currentreferenceformatsetups
1435     \def\currentreferencecontent{\filterreference\currentreferenceformattype}%
1436   \else
1437     \def\currentreferencecontent{\directsetup\currentreferenceformatsetups}%
1438   \fi
1439   %
1440   \enforced\lettonothing\leftofreferencecontent
1441   \enforced\lettonothing\rightofreferencecontent
1442   %
1443   \ifx\currentreferenceformatautocase\v!yes
1444     \setcharactercleaning[1]%
1445   \fi
1446   \strc_references_pickup_goto}
1447
1448\permanent\def\autoreferencelabeltext
1449%   {\clf_getcurrentreferencemetadata{name}}
1450  {\clf_getcurrentreferencelabel}
1451
1452% \starttext
1453%     \definereferenceformat[inxx]  [left=(,right=),text=txt]
1454%     \setupinteraction[state=start]
1455%     \chapter[one]{xx}
1456%     [\goto{state}[file(mk-last-state)]]
1457%     [\goto{state} [file(mk-last-state)]]
1458%     [\at{page} [one]]
1459%     [\at{page}[one]]
1460%     [\at{page}{okay}[one]]
1461%     [\inxx{a}{b}[one]]
1462% \stoptext
1463
1464% \startsetups referenceformat:numberplustext
1465%     \filterreference{number}, \filterreference{title}
1466% \stopsetups
1467%
1468% \definereferenceformat[hellup][text=Hellup ,setups=referenceformat:numberplustext]
1469
1470%D In interactive documents going to a specific location is not bound to cross
1471%D references. The \type {\goto} commands can be used to let users access another
1472%D part of the document. In this respect, interactive tables of contents and
1473%D registers can be considered goto's. Because in fact a \type {\goto} is just a
1474%D reference without reference specific data, the previous macros are implemented
1475%D using the goto functionality.
1476%D
1477%D \showsetup{goto}
1478%D
1479%D One important characteristic is that the first argument of \type {\goto} (and
1480%D therefore \type {\at} and \type {\in} is split at spaces. This means that,
1481%D although hyphenation is prevented, long references can cross line endings.
1482
1483% \starttext
1484%     \setupinteraction[state=start]
1485%     [\goto{state}[file(mk-last-state)]]
1486%     [\goto{state} [file(mk-last-state)]]
1487% \stoptext
1488
1489\newconditional\uselocationstrut \uselocationstrut\conditionaltrue
1490
1491\permanent\def\extrareferencearguments
1492  {highlight \luaconditional\highlighthyperlinks\relaxedspace
1493   newwindow \luaconditional\gotonewwindow\relaxedspace
1494   layer     {\currentviewerlayer}}
1495
1496\permanent\protected\def\directgoto
1497  {\ifconditional\uselocationstrut
1498     \expandafter\strc_references_direct_goto
1499   \else
1500     \expandafter\strc_references_direct_goto_htdp
1501   \fi}
1502
1503\permanent\protected\def\goto
1504  {\ifconditional\uselocationstrut
1505     \expandafter\strc_references_goto
1506   \else
1507     \expandafter\strc_references_goto_htdp
1508   \fi}
1509
1510\permanent\tolerant\protected\def\namedgoto[#1]#:#*#=#*[#3]%
1511  {\dontleavehmode\begingroup
1512   \setinteraction[#1]%
1513   \goto{#2}[#3]%
1514   \endgroup}
1515
1516% The unbox trick is needed in order to permit \par inside a reference. Otherwise
1517% the reference attribute migrates to the outer boxes.
1518
1519\newinteger\lastsavedreferenceattribute
1520
1521\newbox\referencebox
1522
1523\permanent\def\revivesavedreferenceattribute % sometimes handy as no test etc needed
1524  {\c_attr_reference\lastsavedreferenceattribute}
1525
1526\def\strc_references_direct_goto#content[#label]% no test for valid references
1527  {\dontleavehmode
1528   \begingroup
1529   \c_attr_reference\attributeunsetvalue
1530   \global\lastsavedreferenceattribute\attributeunsetvalue
1531   \iflocation
1532     \clf_injectreference
1533        {\referenceprefix}%
1534        {#label}%
1535        {%
1536            height \strutht
1537            depth  \strutdp
1538            \extrareferencearguments
1539        }%
1540     \relax
1541     \setlocationattributes
1542     \setstrut % can be option
1543     \global\lastsavedreferenceattribute\lastreferenceattribute
1544     \c_attr_reference\lastreferenceattribute
1545     \ifexporting\dostarttaggednodetail\t!link\fi
1546     #content%
1547     \ifexporting\dostoptagged\fi
1548   \else
1549     #content%
1550   \fi
1551   \endgroup}
1552
1553\def\strc_references_direct_goto_htdp#content[#label]% no test for valid references
1554  {\dontleavehmode
1555   \begingroup
1556   \global\lastsavedreferenceattribute\attributeunsetvalue
1557   \c_attr_reference\attributeunsetvalue
1558   \iflocation
1559     \clf_injectreference
1560        {\referenceprefix}%
1561        {#label}%
1562        {%
1563            height {\interactionparameter\c!height}%
1564            depth  {\interactionparameter\c!depth}%
1565            \extrareferencearguments
1566        }%
1567     \relax
1568     \setlocationattributes
1569     \c_attr_reference\lastreferenceattribute
1570     \global\lastsavedreferenceattribute\lastreferenceattribute
1571     \ifexporting\dostarttaggednodetail\t!link\fi
1572     #content%
1573     \ifexporting\dostoptagged\fi
1574   \else
1575     #content%
1576   \fi
1577   \endgroup}
1578
1579\def\strc_references_goto#content#dummy[#label]% #dummy gobbles spaces
1580  {\dontleavehmode
1581   \begingroup
1582  %\setbox\referencebox\hbox\bgroup % experiment, might change again to non \par support
1583   \global\lastsavedreferenceattribute\attributeunsetvalue
1584   \c_attr_reference\attributeunsetvalue
1585   \iflocation
1586     \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
1587       {\clf_injectcurrentreferencehtdp
1588          \strutht
1589          \strutdp
1590        \relax
1591        \setlocationattributes
1592        \setstrut % can be option
1593        \global\lastsavedreferenceattribute\lastreferenceattribute
1594        \c_attr_reference\lastreferenceattribute
1595        \ifexporting\dostarttaggednodetail\t!link\fi
1596        #content%
1597        \ifexporting\dostoptagged\fi}%
1598       {#content}%
1599   \else
1600     #content%
1601   \fi
1602  %\egroup\unhbox\referencebox}
1603   \endgroup}
1604
1605\def\strc_references_goto_internal#content#dummy[#internal]% #dummy gobbles spaces
1606  {\dontleavehmode
1607   \begingroup
1608   \global\lastsavedreferenceattribute\attributeunsetvalue
1609   \c_attr_reference\attributeunsetvalue
1610   \iflocation
1611     \setstrut % can be option
1612     \strc_references_get_simple_reference{#internal}%
1613     \global\lastsavedreferenceattribute\currentreferenceattribute
1614     \c_attr_reference\currentreferenceattribute
1615     \setlocationattributes
1616     \ifexporting\dostarttaggednodetail\t!link\fi
1617     #content%
1618     \ifexporting\dostoptagged\fi
1619   \else
1620     #content%
1621   \fi
1622   \endgroup}
1623
1624\permanent\protected\def\startgoto[#label]%
1625  {\dontleavehmode
1626   \begingroup
1627   \iflocation
1628     \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
1629       {\expandafter\strc_references_start_goto_yes}%
1630       {\expandafter\strc_references_start_goto_nop}%
1631   \else
1632     \expandafter\strc_references_start_goto_nop
1633   \fi}
1634
1635\permanent\protected\lettonothing\stopgoto
1636
1637\permanent\protected\def\strc_references_start_goto_nop
1638  {\enforced\let\stopgoto\strc_references_stop_goto_nop}
1639
1640\permanent\protected\def\strc_references_stop_goto_nop
1641  {\endgroup}
1642
1643\protected\def\strc_references_start_goto_yes
1644  {\clf_injectcurrentreferencehtdp
1645     \strutht
1646     \strutdp
1647   \relax
1648   \setlocationattributes
1649   \setstrut % can be option
1650   \global\lastsavedreferenceattribute\lastreferenceattribute
1651   \c_attr_reference\lastreferenceattribute
1652   \ifexporting\dostarttaggednodetail\t!link\fi
1653   \let\stopgoto\strc_references_stop_goto_yes}
1654
1655\protected\def\strc_references_stop_goto_yes
1656  {\ifexporting\dostoptagged\fi
1657   \endgroup}
1658
1659\def\strc_references_goto_htdp#content#dummy[#label]% dummy gobbles spaces
1660  {\dontleavehmode
1661   \begingroup
1662   \global\lastsavedreferenceattribute\attributeunsetvalue
1663   \c_attr_reference\attributeunsetvalue
1664   \iflocation
1665     \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
1666       {\clf_injectcurrentreferencehtdp
1667          {\interactionparameter\c!height}%
1668          {\interactionparameter\c!depth}%
1669        \relax
1670        \setlocationattributes
1671        \global\lastsavedreferenceattribute\lastreferenceattribute
1672        \c_attr_reference\lastreferenceattribute
1673        \ifexporting\dostarttaggednodetail\t!link\fi
1674        #content%
1675        \ifexporting\dostoptagged\fi}%
1676       {#content}%
1677   \else
1678     #content%
1679   \fi
1680   \endgroup}
1681
1682\permanent\protected\def\directgotobox#content[#label]% no test for valid references
1683  {\dontleavehmode
1684   \begingroup
1685   \global\lastsavedreferenceattribute\attributeunsetvalue
1686   \c_attr_reference\attributeunsetvalue
1687   \iflocation
1688     \clf_injectreference
1689       {\referenceprefix}%
1690       {#label}%
1691       {\extrareferencearguments}%
1692     \relax
1693     \setlocationattributes
1694     \global\lastsavedreferenceattribute\lastreferenceattribute
1695     \ifexporting\dostarttaggednodetail\t!link\fi
1696     \hbox attr \referenceattribute \lastreferenceattribute {#content}%
1697     \ifexporting\dostoptagged\fi
1698   \else
1699     #content%
1700   \fi
1701   \endgroup}
1702
1703\permanent\protected\def\directgotospecbox#resolver#content[#label]% no test for valid references
1704  {\dontleavehmode
1705   \begingroup
1706   \global\lastsavedreferenceattribute\attributeunsetvalue
1707   \c_attr_reference\attributeunsetvalue
1708   \iflocation
1709     \clf_injectreference
1710       {\referenceprefix}%
1711       {#label}%
1712       {\extrareferencearguments}%
1713     \relax
1714     \setlocationcolorspec{#resolver}% no consequence for strut
1715     \global\lastsavedreferenceattribute\lastreferenceattribute
1716     \ifexporting\dostarttaggednodetail\t!link\fi
1717     \hbox attr \referenceattribute \lastreferenceattribute {#content}%
1718     \ifexporting\dostoptagged\fi
1719   \else
1720     #content%
1721   \fi
1722   \endgroup}
1723
1724\permanent\protected\def\directgotodumbbox#content[#label]% no test for valid references
1725  {\dontleavehmode
1726   \begingroup
1727   \global\lastsavedreferenceattribute\attributeunsetvalue
1728   \c_attr_reference\attributeunsetvalue
1729   \iflocation
1730     \clf_injectreference
1731       {\referenceprefix}%
1732       {#label}%
1733       {\extrareferencearguments}%
1734     \relax
1735     \global\lastsavedreferenceattribute\lastreferenceattribute
1736     \ifexporting\dostarttaggednodetail\t!link\fi
1737     \hbox attr \referenceattribute \lastreferenceattribute {#content}%
1738     \ifexporting\dostoptagged\fi
1739   \else
1740     #content%
1741   \fi
1742   \endgroup}
1743
1744\permanent\protected\def\gotobox#content[#label]%
1745  {\dontleavehmode
1746   \begingroup
1747   \global\lastsavedreferenceattribute\attributeunsetvalue
1748   \c_attr_reference\attributeunsetvalue
1749   \iflocation
1750     \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
1751       {\clf_injectcurrentreference
1752        \setlocationattributes
1753        \global\lastsavedreferenceattribute\lastreferenceattribute
1754        \ifexporting\dostarttaggednodetail\t!link\fi
1755        \hbox attr \referenceattribute \lastreferenceattribute {#content}%
1756        \ifexporting\dostoptagged\fi}%
1757       {#content}%
1758   \else
1759     #content%
1760   \fi
1761   \endgroup}
1762
1763\permanent\protected\def\gotowdhtbox#width#height[#label]% fast variant for overlays
1764  {\dontleavehmode
1765   \begingroup
1766   \setbox\scratchbox\emptyhbox
1767   \wd\scratchbox#width%
1768   \ht\scratchbox#height%
1769   \global\lastsavedreferenceattribute\attributeunsetvalue
1770   \c_attr_reference\attributeunsetvalue
1771   \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}%
1772     {\clf_injectcurrentreference
1773      \global\lastsavedreferenceattribute\lastreferenceattribute
1774      \hpack attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}
1775     {\box\scratchbox}%
1776   \endgroup}
1777
1778%D An reference to another document can be specified as a file or as an \URL. Both
1779%D are handled by the same mechanism and can be issued by saying something like:
1780%D
1781%D \starttyping
1782%D \goto[dictionary::the letter a]
1783%D \stoptyping
1784%D
1785%D One can imagine that many references to such a dictionary are made, so in most
1786%D cases such a document reference in an indirect one.
1787%D
1788%D \showsetup{useexternaldocument}
1789%D
1790%D For example:
1791%D
1792%D \starttyping
1793%D \useexternaldocument
1794%D   [dictionary][engldict]
1795%D   [The Famous English Dictionary]
1796%D \stoptyping
1797%D
1798%D The next macro implements these relations, and also take care of loading the
1799%D document specific references.
1800%D
1801%D The \URL\ alternative takes four arguments:
1802%D
1803%D \showsetup{useURL}
1804%D
1805%D like:
1806%D
1807%D \starttyping
1808%D \useURL
1809%D   [dictionary][http://www.publisher.com/public][engldict]
1810%D   [The Famous English Dictionary]
1811%D \stoptyping
1812%D
1813%D Several specifications are possible:
1814%D
1815%D \starttyping
1816%D \useURL [id] [url] [file] [description]
1817%D \useURL [id] [url] [file]
1818%D \useURL [id] [url]
1819%D \stoptyping
1820%D
1821%D This time we don't load the references when no file is specified. This is logical
1822%D when one keeps in mind that a valid \URL\ can also be a mail address.
1823
1824\permanent\tolerant\protected\def\useurl[#label]#spacer[#url]#spacer[#file]#spacer[#description]%
1825  {\clf_useurl{#label}{\detokenize{#url}}{\detokenize{#file}}{\detokenize{#description}}}
1826
1827\permanent\tolerant\protected\def\usefile[#label]#spacer[#file]#spacer[#description]%
1828  {\clf_usefile{#label}{\detokenize{#file}}{\detokenize{#description}}}
1829
1830\aliased\let\useURL             \useurl
1831\aliased\let\useexternaldocument\usefile
1832
1833\permanent\def\doifelseurldefined #label{\clf_doifelseurldefined {#label}} % todo: no wrap
1834\permanent\def\doifelsefiledefined#label{\clf_doifelsefiledefined{#label}} % todo: no wrap
1835
1836\aliased\let\doifurldefinedelse \doifelseurldefined
1837\aliased\let\doiffiledefinedelse\doifelsefiledefined
1838
1839%D \macros
1840%D   {url,setupurl}
1841%D
1842%D We also have: \type {\url} for directly calling the description. So we can say:
1843%D
1844%D \starttyping
1845%D \useURL [one] [http://www.test.nl]
1846%D \useURL [two] [http://www.test.nl] [] [Some Site]
1847%D
1848%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)]
1849%D \stoptyping
1850%D
1851%D An \URL\ can be set up with
1852%D
1853%D \showsetup{setupurl}
1854
1855\installcorenamespace{url}
1856
1857\installdirectcommandhandler \??url {url}
1858
1859\setupurl
1860  [\c!style=\v!type,
1861   \c!color=]
1862
1863\permanent\protected\def\url[#label]% move \hyphenatedurl to lua end (is already lua)
1864  {\dontleavehmode
1865   \begingroup
1866   \useurlstyleandcolor\c!style\c!color
1867   \hyphenatedurl{\clf_geturl{#label}}%
1868   \endgroup}
1869
1870%D This macro is hooked into a support macro, and thereby \URL's break ok, according
1871%D to the setting of a switch,
1872%D
1873%D \startbuffer
1874%D \useURL
1875%D   [test]
1876%D   [sentence_sentence~sentence//sentence:sentence.sentence]
1877%D \stopbuffer
1878%D
1879%D \typebuffer
1880%D
1881%D Such an \URL\ is, depending on the settings, hyphenated as:
1882%D
1883%D \getbuffer
1884
1885%D When defining the external source of information, one can also specify a suitable
1886%D name (the last argument). This name can be called upon with:
1887%D
1888%D \showsetup{from}
1889%D
1890%D We keep this for compatibility reasons, hence the hackery.
1891
1892\permanent\tolerant\protected\def\strc_references_from[#label]%
1893  {\dontleavehmode
1894   \goto{\clf_from{#label}}[fileorurl(#label)]}
1895
1896\permanent\def\dofromurldescription#content% called at the lua end
1897  {#content}
1898
1899\permanent\def\dofromurlliteral#content% called at the lua end
1900  {\useurlstyleandcolor\c!style\c!color
1901   \hyphenatedurl{#content}}
1902
1903\aliased\let\dofromfiledescription\dofromurldescription
1904\aliased\let\dofromfileliteral    \dofromurlliteral     % maybe some day setupfile that inherits from url
1905
1906%D We also support:
1907%D
1908%D \starttyping
1909%D \goto{some text}[file(identifier{location}]
1910%D \stoptyping
1911%D
1912%D which is completely equivalent with
1913%D
1914%D \starttyping
1915%D \goto{some text}[identifier::location]
1916%D \stoptyping
1917
1918%D A special case of references are those to programs. These, very system dependant
1919%D references are implemented by abusing some of the previous macros.
1920%D
1921%D \showsetup{setupprograms}
1922%D \showsetup{defineprogram}
1923%D \showsetup{program} % changed functionality !
1924%D
1925%D The latter gives access to the description of the program,
1926%D being the last argument to the definition command.
1927
1928% also lua, like urls and files
1929
1930\installcorenamespace{programs}
1931
1932\installdirectcommandhandler \??programs {programs}
1933
1934\permanent\tolerant\protected\def\defineprogram[#name]#spacer[#program]#spacer[#description]%
1935  {\clf_defineprogram{#name}{#program}{#description}}
1936
1937\permanent\protected\def\program[#name]% incompatible, more consistent, hardy used anyway
1938  {\dontleavehmode
1939   \begingroup
1940   \useprogramsstyleandcolor\c!style\c!color
1941   \clf_getprogram{#name}%
1942   \endgroup}
1943
1944%D As we can see, we directly use the special reference mechanism, which means that
1945%D
1946%D \starttyping
1947%D \goto{some text}[program(name{args})]
1948%D \stoptyping
1949%D
1950%D is valid.
1951
1952%D The next macro provides access to the actual pagenumbers. When documenting and
1953%D sanitizing the original reference macros, I decided to keep the present meaning
1954%D as well as to make this meaning available as a special reference method. So now
1955%D one can use:
1956%D
1957%D \starttyping
1958%D \gotopage{some text}[location]
1959%D \gotopage{some text}[number]
1960%D \gotopage{some text}[file::number]
1961%D \stoptyping
1962%D
1963%D as well as:
1964%D
1965%D \starttyping
1966%D \goto{some text}[page(location)]
1967%D \goto{some text}[page(number)]
1968%D \goto{some text}[file::page(number)]
1969%D \stoptyping
1970%D
1971%D Here location is a keyword like \type{nextpage}.
1972%D
1973%D \showsetup{gotopage}
1974
1975\permanent\tolerant\protected\def\definepage[#name]#spacer[#target]%
1976  {\definereference[#name][page(#target)]}
1977
1978\permanent\protected\def\gotopage#text[#target]%
1979  {\goto{#text}[\v!page(#target)]}
1980
1981%D The previous definitions are somewhat obsolete so we don't use it here.
1982
1983%D We can cross link documents by using:
1984%D
1985%D \showsetup{coupledocument}
1986%D
1987%D like:
1988%D
1989%D \starttyping
1990%D \coupledocument[print][somefile][chapter,section]
1991%D \stoptyping
1992%D
1993%D After which when applicable, we have available the references:
1994%D
1995%D \starttyping
1996%D \goto{print version}[print::chapter]
1997%D \stoptyping
1998%D
1999%D and alike. The title placement definition macros have a key \type {file}, which
2000%D is interpreted as the file to jump to, that is, when one clicks on the title.
2001
2002\permanent\tolerant\protected\def\coupledocument[#name]#spacer[#file]#spacer[#sections]#spacer[#description]%
2003  {} % this will be done differently (when it's needed)
2004
2005%D \macros
2006%D   {dotextprefix}
2007%D
2008%D In previous macros we used \type {\dotextprefix} to generate a space between
2009%D a label and a number.
2010%D
2011%D \starttyping
2012%D \dotextprefix{text}
2013%D \stoptyping
2014%D
2015%D Only when \type {text} is not empty, a space is inserted.
2016
2017\permanent\protected\def\dotextprefix#text%
2018  {\begingroup
2019   \setbox\scratchbox\hbox{#text}% to be solved some day
2020   \ifdim\wd\scratchbox>\zeropoint
2021     \unhbox\scratchbox
2022     \edef\p_separator{\referencingparameter\c!separator}%
2023     \ifempty\p_separator \else
2024        \removeunwantedspaces % remove is new
2025        \p_separator
2026     \fi
2027   \else
2028     \unhbox\scratchbox
2029   \fi
2030   \endgroup}
2031
2032%D In the next settings we see some variables that were not used here and that
2033%D concern the way the pagenumbers refered to are typeset.
2034
2035\setupreferencing
2036  [\c!state=\v!start,
2037   \c!autofile=\v!no,
2038   \v!part\c!number=\v!yes,
2039   \v!chapter\c!number=\v!no,
2040   \c!interaction=\v!all,
2041   \c!convertfile=\v!no,
2042  %\c!strut=\v!no, % some day an option
2043   \c!prefix=,
2044   \c!width=.75\makeupwidth,
2045   \c!left=\quotation\bgroup,
2046   \c!right=\egroup,
2047   \c!global=\v!no,
2048   \c!expansion=\v!no,
2049   \c!separator=\nonbreakablespace,
2050   \c!export=\v!no]
2051
2052\setupprograms
2053  [\c!directory=,
2054   \c!style=\v!type,
2055   \c!color=]
2056
2057\definereference [\v!CloseDocument    ] [action(close)]
2058\definereference [\v!ExitViewer       ] [action(exit)]
2059\definereference [\v!FirstPage        ] [action(first)]
2060\definereference [\v!LastPage         ] [action(last)]
2061\definereference [\v!NextJump         ] [action(forward)]
2062\definereference [\v!NextPage         ] [action(next)]
2063\definereference [\v!PauseRendering   ] [action(pauserendering)]
2064\definereference [\v!PreviousJump     ] [action(backward)]
2065\definereference [\v!PreviousPage     ] [action(previous)]
2066\definereference [\v!PrintDocument    ] [action(print)]
2067\definereference [\v!SaveForm         ] [action(exportform)]
2068\definereference [\v!LoadForm         ] [action(importform)]
2069\definereference [\v!ResetForm        ] [action(resetform)]
2070\definereference [\v!ResumeRendering  ] [action(resumerendering)]
2071\definereference [\v!SaveDocument     ] [action(save)]
2072\definereference [\v!SaveNamedDocument] [action(savenamed)]
2073\definereference [\v!OpenNamedDocument] [action(opennamed)]
2074\definereference [\v!SearchDocument   ] [action(search)]
2075\definereference [\v!SearchAgain      ] [action(searchagain)]
2076\definereference [\v!StartRendering   ] [action(startrendering)]
2077\definereference [\v!StopRendering    ] [action(stoprendering)]
2078\definereference [\v!SubmitForm       ] [action(submitform)]
2079\definereference [\v!ToggleViewer     ] [action(toggle)]
2080\definereference [\v!ViewerHelp       ] [action(help)]
2081\definereference [\v!HideField        ] [action(hide)]
2082\definereference [\v!ShowField        ] [action(show)]
2083\definereference [\v!GotoPage         ] [action(gotopage)]
2084\definereference [\v!Query            ] [action(query)]
2085\definereference [\v!QueryAgain       ] [action(queryagain)]
2086\definereference [\v!FitWidth         ] [action(fitwidth)]
2087\definereference [\v!FitHeight        ] [action(fitheight)]
2088\definereference [\v!ShowThumbs       ] [action(thumbnails)]
2089\definereference [\v!ShowBookmarks    ] [action(bookmarks)]
2090
2091\definereference [\v!HideLayer        ] [action(hidelayer)]
2092\definereference [\v!VideLayer        ] [action(videlayer)]
2093\definereference [\v!ToggleLayer      ] [action(togglelayer)]
2094
2095\definereference [\v!firstpage]       [page(firstpage)]
2096\definereference [\v!previouspage]    [page(previouspage)]
2097\definereference [\v!nextpage]        [page(nextpage)]
2098\definereference [\v!lastpage]        [page(lastpage)]
2099\definereference [\v!forward]         [page(forward)]
2100\definereference [\v!backward]        [page(backward)]
2101\definereference [\v!firstsubpage]    [page(firstsubpage)]
2102\definereference [\v!previoussubpage] [page(previoussubpage)]
2103\definereference [\v!nextsubpage]     [page(nextsubpage)]
2104\definereference [\v!lastsubpage]     [page(lastsubpage)]
2105
2106% we can do this but only when later in resolve (else problems with \chapter[first]{...}
2107%
2108% \definereference [\v!first]           [page(firstpage)]
2109% \definereference [\v!previous]        [page(prevpage)]
2110% \definereference [\v!next]            [page(nextpage)]
2111% \definereference [\v!last]            [page(lastpage)]
2112% \definereference [\v!first\v!sub]     [page(firstsubpage)]
2113% \definereference [\v!previous\v!sub]  [page(prevsubpage)]
2114% \definereference [\v!next\v!sub]      [page(nextsubpage)]
2115% \definereference [\v!last\v!sub]      [page(lastsubpage)]
2116
2117%D We cannot set up buttons (not yet, this one calls a menu macro):
2118
2119%D New (and experimental):
2120
2121% \starttext
2122%     \chapter{test}
2123%     \placefigure[here][xx:1]{}{\framed{one}} \placefigure[here][xx:2]{}{\framed{three}}
2124%     \placetable [here][xx:3]{}{\framed{two}} \placetable [here][xx:4]{}{\framed{four}}
2125%     \start
2126%         \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4]
2127%     \stop \blank \start
2128%         \setupreferencestructureprefix[default][prefix=no]
2129%         \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4]
2130%     \stop \blank \start
2131%         \setupreferencestructureprefix[float][default][prefix=no]
2132%         \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4]
2133%     \stop \blank \start
2134%         \setupreferencestructureprefix[figure][default][prefix=no]
2135%         \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4]
2136%     \stop \blank
2137% \stoptext
2138
2139% todo: parameterhandler
2140
2141\installcorenamespace{referencingprefix}
2142
2143\permanent\def\getreferencestructureprefix#kind#name#category% name will change
2144  {{%
2145        prefix        {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefix}%
2146        separatorset  {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixseparatorset}%
2147        conversion    {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconversion}%
2148        conversionset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconversionset}%
2149        starter       {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixstarter}%
2150        stopper       {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixstopper}%
2151        set           {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixset}%
2152        segments      {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixsegments}%
2153        connector     {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconnector}%
2154  }%
2155  {%
2156        separatorset  {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberseparatorset}%
2157        conversion    {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberconversion}%
2158        conversionset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberconversionset}%
2159        starter       {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberstarter}%
2160        stopper       {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberstopper}%
2161        segments      {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numbersegments}%
2162  }}
2163
2164\permanent\tolerant\protected\def\setupreferencestructureprefix[#kind]#spacer[#category]#spacer[#S#settings]%
2165  {\ifarguments\or\or
2166     \getparameters[\??referencingprefix:#kind][#category]%
2167   \else
2168     \getparameters[\??referencingprefix#kind:#category][#settings]%
2169   \fi}
2170
2171\permanent\def\referencestructureprefixparameter#kind#name#category#parameter%
2172  {\ifcsname\??referencingprefix#name:#category#parameter\endcsname
2173     \lastnamedcs
2174   \orelse\ifcsname\??referencingprefix#kind:#category#parameter\endcsname
2175     \lastnamedcs
2176   \orelse\ifcsname\??referencingprefix:#category#parameter\endcsname
2177     \lastnamedcs
2178   \fi}
2179
2180\permanent\def\currentreferencedefault % for some reason we need to explicitly expand
2181  {\normalexpanded{\noexpand\clf_filterdefaultreference
2182     {\s!default}%
2183     \noexpand\getreferencestructureprefix\clf_getcurrentprefixspec{\s!default}% returns #kind#name#category
2184   \relax}}
2185
2186%D Not all support is visible by looking at the \TEX\ code; here is one of those:^
2187%D
2188%D \starttyping
2189%D \startinteractionmenu[right]
2190%D   \startbut [section(first   {chapter})]    first chapter \stopbut
2191%D   \startbut [section(previous{chapter})] previous chapter \stopbut
2192%D   \startbut [section(next    {chapter})]     next chapter \stopbut
2193%D   \startbut [section(last    {chapter})]     last chapter \stopbut
2194%D   \blank[2*big]
2195%D   \startbut [section(first   {section})]    first section \stopbut
2196%D   \startbut [section(previous{section})] previous section \stopbut
2197%D   \startbut [section(next    {section})]     next section \stopbut
2198%D   \startbut [section(last    {section})]     last section \stopbut
2199%D \stopinteractionmenu
2200%D \stoptyping
2201
2202%D Relatively new:
2203%D
2204%D \starttyping
2205%D \chapter{The never ending story}
2206%D
2207%D \section{An ending story}
2208%D
2209%D \in{chapter}[match(complex bibliographies)]
2210%D \in{chapter}[match(never ending)]
2211%D \in{chapter}[match(ending)]
2212%D \in{chapter}[match(chapter:never ending)]
2213%D \in{chapter}[match(chapter:ending)]
2214%D \in{section}[match(section:ending)]
2215%D \in{figure}[match(float:mess)]
2216%D \in{figure}[match(figure:mess)]
2217%D \in{figure (not found)}[match(section:mess)]
2218%D \in{figure (not found)}[match(section:xxxx)]
2219%D \in{figure}[match(mess)]
2220%D
2221%D \placefigure{What a mess}{}
2222%D
2223%D \chapter{About complex bibliographies}
2224%D
2225%D \in{chapter}[match(complex bibliographies)]
2226%D \in{chapter}[match(never ending)]
2227%D \in{figure}[match(mess)]
2228%D \stoptyping
2229
2230\protect \endinput
2231
2232% tricky:
2233%
2234% \enabletrackers[nodes.references]
2235% \setupinteraction[state=start]
2236% \def\KnuthTest{\input knuth }
2237% \def\KnuthTest{\input tufte }
2238% \def\TufteTest{\input tufte }
2239% \defineoverlay[xxx][\overlaybutton{page(3)}]
2240% \setupbackgrounds[text][background=xxx]
2241% \starttext
2242% test {\red \KnuthTest} test \par
2243% \button{test}[page(1)] \par
2244% \goto{page 2 \TeX}[page(2)] \goto{page 2 \TeX}[page(2)] \goto{\TufteTest}[page(2)] test \page
2245% test \goto{page 3}[page(3)] \goto{\TufteTest\space\par\TufteTest}[page(4)] test \page
2246% \goto{page 1}[page(1)] \goto{\TufteTest\space test}[page(1)] \page
2247% \goto{page 1}[page(1)] \goto{\KnuthTest\space test}[page(1)] \page
2248% test \goto{page 1}[page(1)] {\goto{\KnuthTest\space test}[page(1)]} test
2249% \goto{page 1}[page(1)] \goto{\TufteTest}[page(1)] test \page
2250% \stoptext
2251