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