diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi | 2296 |
1 files changed, 2296 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi new file mode 100644 index 00000000000..177abd835b7 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/strc-ref.mkvi @@ -0,0 +1,2296 @@ +%D \module +%D [ file=strc-ref, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Cross Referencing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: (1) configure references, (2) rendering => with presets +% +% \defineconversionset[default][Character,number,Romannumerals,Character][number] +% \defineseparatorset [default][.,.,--][.] +% \setuphead[subsection][sectionstopper=),sectionsegments=4:4] +% \setupreferencestructureprefix[default][prefixsegments=2:4] +% \setupreferencestructureprefix[figure][default][prefixsegments=3:4] +% \chapter {One} +% \section {One} +% \subsection[sec:test]{Two} +% See \in[sec:test] and \in[fig:xx] and \in[fig:yy] +% \placefigure[here][fig:xx]{}{} +% \placefigure[here][fig:yy]{}{} + +\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} + +\registerctxluafile{strc-rsc}{1.001} +\registerctxluafile{strc-ref}{1.001} +\registerctxluafile{node-ref}{1.001} + +\unprotect + +%D This module is a (partial) rewrite of core-ref.tex for \MKIV. As +%D such it will be a moving target for a while. + +%D Later we will do a further cleanup and move much of the code to +%D \LUA\ (i.e.\ better backend integration). + +\let\mainreference\gobblefivearguments + +% this will go when we got rid of the tuo file + +\let\currentfolioreference \!!zerocount % only used in xml-fo +\let\resetreferences \relax +\let\setreferences \relax +\let\showcurrentreference \relax +\let\setexecutecommandcheck\gobbletwoarguments + +% todo : unknown/illegal reference no arg +% todo : +n pages check on 'samepage' (contrastcolor) +% todo : multiple text in reference + +% Makes more sense to build action data first, especially now +% openaction etc are supported. +% +% \definespecial\doexecuteactionchain w h +% \definespecial\dosetgotolocation +% \definespecial\dosetexecuteJScode +% ... + +%D This module deals with referencing. In \CONTEXT\ referencing is one of +%D the core features, although at a first glance probably nobody will +%D notice. This is good, because referencing should be as hidden as possible. +%D +%D Before we start implementing functionality we provide a way to set +%D up this mechanism. +%D +%D \showsetup{setupreferencing} +%D +%D In interactive documents verbose references don't always +%D make sense (what is a page number in an unnumbered +%D document). By setting the \type{interaction} variable, one +%D can influences the way interactive references are set. + +\let\referenceprefix\empty + +\installcorenamespace{referencing} + +\installdirectcommandhandler \??referencing {referencing} % \??referencing + +\newif\ifreferencing \referencingtrue + +\appendtoks + \edef\p_state{\referencingparameter\c!state}% + \ifx\p_state\v!start + \referencingtrue + \else + \referencingfalse + \fi +\to \everysetupreferencing + +%D In paper documents, referencing comes down to cross referencing, but in +%D their interactive counterparts, is also involves navigation. Many features +%D implemented here are therefore closely related to navigation. +%D +%D Many \CONTEXT\ commands can optionally be fed with a reference. Such a +%D reference, when called upon, returns the number of a figure, table, chapter +%D etc, a piece of text, or a pagenumber. +%D +%D There are three ways of defining a reference: +%D +%D \starttyping +%D \pagereference[here] +%D \textreference[here]{some text} +%D \stoptyping +%D +%D the third alternative combines them in: +%D +%D \starttyping +%D \reference[here]{some text} +%D \stoptyping + +\unexpanded\def\textreference {\dosingleargument\strc_references_text_reference} % no need for \dosingle +\unexpanded\def\pagereference {\dosingleargument\strc_references_page_reference} % as they're mandate and +\unexpanded\def\reference {\dosingleargument\strc_references_full_reference} % never forgotten +\unexpanded\def\setreference {\dodoubleargument\strc_references_set_reference } % + +% maybe: \let\reference\textreference + +\unexpanded\def\showreferences + {\enabletrackers[nodes.references.show,nodes.destinations.show]} + +%D These are implemented in a low level form as: + +\unexpanded\def\strc_references_text_reference [#labels]{\strc_references_set_named_reference\s!text{#labels}{}} +\unexpanded\def\strc_references_page_reference [#labels]{\strc_references_set_named_reference\s!page{#labels}{}{}} +\unexpanded\def\strc_references_full_reference [#labels]{\strc_references_set_named_reference\s!full{#labels}{}} +\unexpanded\def\strc_references_set_reference[#labels][#settings]{\strc_references_set_named_reference\s!user{#labels}{#settings}{}} + +\unexpanded\def\dosetdirectpagereference#1{\strc_references_set_named_reference\s!page{#1}{}{}} % low level, maybe use _ + +\unexpanded\def\usereferenceparameter#1% faster local variant + {\edef\m_strc_references_asked{#1\c!reference}% + \ifx\m_strc_references_asked\empty\else + \dosetdirectpagereference\m_strc_references_asked + \fi} + +%D Actually there is not much difference between a text and a +%D full reference, but it's the concept that counts. The low +%D level implementation is: + +\newcount\lastreferenceattribute +\newcount\lastdestinationattribute + +\def\strc_references_finish#prefix#reference#internal% + {\normalexpanded{\ctxlatecommand{enhancereference("#prefix","#reference")}}} + +\let\dofinishreference\strc_references_finish % used at lua end + +% This is somewhat tricky: we want to keep the reference with the following word but +% that word should also hyphenate. We need to find a better way. + +% 0 = nothing +% 1 = bind to following word + +\setnewconstant\c_strc_references_bind_state\plusone + +\def\strc_references_inject_before + {} + +\def\strc_references_inject_after + {\ifcase\c_strc_references_bind_state + % nothing + \or + \prewordbreak % to be tested: \removeunwantedspaces\permithyphenation + \fi} + + +\unexpanded\def\strc_references_set_named_reference + {\ifreferencing + \expandafter\strc_references_set_named_reference_indeed + \else + \expandafter\gobblefourarguments + \fi} + +\newbox\b_strc_destination_nodes + +\unexpanded\def\strc_references_flush_destination_nodes + {\ifvoid\b_strc_destination_nodes \else + \unhbox\b_strc_destination_nodes + \fi} + +\unexpanded\def\strc_references_start_destination_nodes % messy but we need the delay + {\setbox\b_strc_destination_nodes\hbox\bgroup} % also sets lastdestinationattribute + +\unexpanded\def\strc_references_stop_destination_nodes + {\normalexpanded{\egroup\lastdestinationattribute\the\lastdestinationattribute\relax}} + +\unexpanded\def\strc_references_set_named_reference_indeed#kind#labels#userdata#text% labels userdata text -> todo: userdata + {\ifreferencing + % we could have a more efficient one for page references but for the moment + % we don't care too much + \edef\currentreferencekind {#kind}% + \edef\currentreferencelabels {#labels}% + \edef\currentreferenceuserdata {#userdata}% + \edef\currentreferenceexpansion{\referencingparameter\c!expansion}% {\referenceparameter\c!expansion} + \ifx\currentreferencelabels\empty + \lastdestinationattribute\attributeunsetvalue + \else + \ifx\currentreferenceexpansion\s!xml + \xmlstartraw + \xdef\currentreferencedata{#text}% data, no text else conflict + \xmlstopraw + \globallet\currentreferencecoding\s!xml + \else + \ifx\currentreferenceexpansion\v!yes + \xdef\currentreferencedata{#text}% + \else + \xdef\currentreferencedata{\detokenize{#text}}% + \fi + \globallet\currentreferencecoding\s!tex + \fi + % beware, the structures.references.set writes a + \setnextinternalreference + \strc_references_start_destination_nodes + \clf_setdestinationattribute + {% + references {% + internal \nextinternalreference + % block {\currentsectionblock}% + view {\interactionparameter\c!focus}% + \ifx\referenceprefix\empty\else + prefix {\referenceprefix}% + \fi + reference {\currentreferencelabels}% + }% + metadata {% + kind {\currentreferencekind}% + \ifx\currentreferencekind\s!page\else + \ifx\currentreferencecoding\s!xml + xmlroot {\xmldocument}% + \fi + catcodes \catcodetable + \fi + }% + \ifx\currentreferencedata\empty\else + entries {% + text {\currentreferencedata}% + }% + \fi + \ifx\currentreferenceuserdata\empty\else + userdata {\detokenize{#userdata}}% + \fi + }% + \relax + \strc_references_stop_destination_nodes + \fi + \else + \setbox\b_strc_destination_nodes\emptyhbox + \lastdestinationattribute\attributeunsetvalue + \fi + % will become obsolete: + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + % will become an option: + \ifnum\lastdestinationattribute>\zerocount + \strc_references_inject_before % new + \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup + \strc_references_flush_destination_nodes + \egroup + \strc_references_inject_after % new + \else\ifvoid\b_strc_destination_nodes\else + \strc_references_inject_before % new + \dontleavehmode\hbox \bgroup + \strc_references_flush_destination_nodes + \egroup + \strc_references_inject_after % new + \fi\fi} + +\def\strc_references_set_page_only_destination_attribute#labels% could in fact be fully expandable + {\ifreferencing + \edef\currentreferencelabels{#labels}% + \ifx\currentreferencelabels\empty + \setbox\b_strc_destination_nodes\emptyhbox + \lastdestinationattribute\attributeunsetvalue + \else + \strc_references_start_destination_nodes + \setnextinternalreference + \clf_setdestinationattribute + {% + references {% + internal \nextinternalreference + % block {\currentsectionblock}% + view {\interactionparameter\c!focus}% + \ifx\referenceprefix\empty\else + prefix {\referenceprefix}% + \fi + reference {\currentreferencelabels}% + }% + metadata {% + kind {page}% + }% + }% + \relax + \strc_references_stop_destination_nodes + \fi + \else + \setbox\b_strc_destination_nodes\emptyhbox + \lastdestinationattribute\attributeunsetvalue + \fi} + +\unexpanded\def\strc_references_direct_full_user#user#labels#text% + {\ifreferencing + \strc_references_start_destination_nodes + \setnextinternalreference + \edef\m_strc_references_user{#user}% + \edef\m_strc_references_text{#text}% + \clf_setdestinationattribute + {% + references {% + internal \nextinternalreference + % block {\currentsectionblock}% + view {\interactionparameter\c!focus}% + \ifx\referenceprefix\empty\else + prefix {\referenceprefix}% + \fi + reference {#labels}% + }% + metadata {% + kind {\s!full}% + }% + \ifx\m_strc_references_text\empty \else + entries {% + text {\m_strc_references_text}% + }% + \fi + \ifx\m_strc_references_user\empty \else + userdata {\m_strc_references_user}% \detokenize\expandafter{\normalexpanded{...}} + \fi + }% + \relax + \strc_references_stop_destination_nodes + \else + \setbox\b_strc_destination_nodes\emptyhbox + \lastdestinationattribute\attributeunsetvalue + \fi + % will become obsolete: + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + % will become an option: + \ifnum\lastdestinationattribute>\zerocount + \strc_references_inject_before % new + \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup + \strc_references_flush_destination_nodes + \egroup + \strc_references_inject_after % new + \else\ifvoid\b_strc_destination_nodes\else + \strc_references_inject_before % new + \dontleavehmode\hbox \bgroup + \strc_references_flush_destination_nodes + \egroup + \strc_references_inject_after % new + \fi\fi} + +\unexpanded\def\strc_references_direct_full + {\strc_references_direct_full_user\empty} + +\let\dodirectfullreference\strc_references_direct_full % for at lua end (no longer) + +\def\strc_references_set_page_only_destination_box_attribute#cs#labels% + {\strc_references_set_page_only_destination_attribute{#labels}% + \ifnum\lastdestinationattribute>\zerocount + \edef#cs{attr \destinationattribute\number\lastdestinationattribute}% + \else + \let#cs\empty + \fi} + +%D It's about time to clean up references .. stable enough now. + +\unexpanded\def\boxreference[#1]% + {\begingroup + \dowithnextbox + {\strc_references_set_page_only_destination_attribute{#1}% + \hbox + \ifnum\lastdestinationattribute=\attributeunsetvalue\else attr \destinationattribute \lastdestinationattribute \fi + {\box\b_strc_destination_nodes\box\nextbox}% + \endgroup}} + +\unexpanded\def\hboxreference[#1]{\boxreference[#1]\hbox} +\unexpanded\def\vboxreference[#1]{\boxreference[#1]\vbox} + +% \ifx\currentdestinationattribute\empty +% \begingroup\attribute\destinationattribute\currentdestinationattribute\emptyhbox\endgroup % todo +% \fi + +\def\defaultreferencepage#text{[[[#text]]]} +\def\defaultreferencetext#text{[[[#text]]]} + +%D For internal usage: + +\def\strc_references_set_simple_reference#label% + {\iflocation + \strc_references_start_destination_nodes + \setnextinternalreference + \clf_setdestinationattribute + {% + references {% + view {\interactionparameter\c!focus}% + \ifx\referenceprefix\empty\else + prefix {\referenceprefix}% + \fi + reference {#label}% + internal \nextinternalreference + }% + metadata {% + kind {\s!page}% + }% + }% + \relax + \strc_references_stop_destination_nodes + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + \else + \setbox\b_strc_destination_nodes\emptyhbox + \xdef\currentdestinationattribute{\number\attributeunsetvalue}% + \fi} + +\def\strc_references_set_simple_internal_reference#label% no prefix + {\iflocation + \strc_references_start_destination_nodes + \setnextinternalreference + \clf_setdestinationattribute + {% + references {% + view {\interactionparameter\c!focus}% + reference {#label}% + internal \nextinternalreference + }% + metadata {% + kind {\s!page}% + }% + }% + \relax + \strc_references_stop_destination_nodes + \xdef\currentdestinationattribute{\number\lastdestinationattribute}% + \else + \setbox\b_strc_destination_nodes\emptyhbox + \xdef\currentdestinationattribute{\number\attributeunsetvalue}% + \fi} + +\def\strc_references_get_simple_reference#label% + {\iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {% + height \ht\strutbox + depth \dp\strutbox + \extrareferencearguments + }% + \relax + \xdef\currentreferenceattribute{\number\lastreferenceattribute}% + \else + \xdef\currentreferenceattribute{\number\attributeunsetvalue}% + \fi} + +%D \macros +%D {contentreference} +%D +%D \starttyping +%D \setupinteraction +%D [state=start, +%D focus=standard] +%D +%D \setupheader +%D [state=stop] +%D +%D See page \goto{page 2}[page2] \page +%D +%D \contentreference +%D [page2] +%D [offset=1cm,toffset=2cm,frame=on] +%D {\externalfigure[cow.pdf][factor=fit]} +%D +%D \stoptyping + +\unexpanded\def\contentreference + {\hbox\bgroup + \dodoubleempty\strc_references_content_pickup} + +\def\strc_references_content_pickup + {\ifsecondargument + \expandafter\strc_references_content_pickup_yes + \else + \expandafter\strc_references_content_pickup_nop + \fi} + +\def\strc_references_content_pickup_yes[#1][#2]% + {\dowithnextbox{\strc_references_content_yes_finish{#1}{#2}}\hbox} + +\def\strc_references_content_pickup_nop[#1][#2]% + {\dowithnextbox{\strc_references_content_nop_finish{#1}{#2}}\hbox} + +\def\strc_references_content_yes_finish#1#2% + {\scratchwidth \wd\nextbox + \scratchheight\ht\nextbox + \scratchdepth \dp\nextbox + \setbox\nextbox\hbox + {\framed[\c!frame=\v!off,#2]{\box\nextbox}}% + \strc_references_set_simple_reference{#1}% + \setbox\nextbox\hbox attr \destinationattribute \currentdestinationattribute + {\strc_references_flush_destination_nodes + \box\nextbox}% + \setbox\nextbox\hbox{\box\nextbox}% + \wd\nextbox\scratchwidth + \ht\nextbox\scratchheight + \dp\nextbox\scratchdepth + \box\nextbox + \egroup} + +\def\strc_references_content_nop_finish#1#2% + {\strc_references_set_simple_reference{#1}% + \hbox attr \destinationattribute \currentdestinationattribute + {\strc_references_flush_destination_nodes + \box\nextbox}% + \egroup} + +%D \macros +%D {everyreference} +%D +%D For rather tricky purposes, one can assign sanitizing +%D macros to \type{\everyreference} (no longer that relevant). + +\newevery \everyreference \relax + +%D This is really needed, since for instance Polish has a +%D different alphabet and needs accented entries in registers. + +\appendtoks + \cleanupfeatures +\to \everyreference + +%D We did not yet discuss prefixing. Especially in interactive +%D documents, it's not always easy to keep track of duplicate +%D references. The prefix mechanism, which we will describe +%D later on, solves this problem. By (automatically) adding a +%D prefix one keeps references local, but the global ones in +%D view. To enable this feature, we explictly split the prefix +%D from the reference. + +\let\referenceprefix\empty + +%D For a long time the only way to access an external file was +%D to use the file prefix (\type {somefile::}. However, when +%D you split up a document, redefining the references may be +%D such a pain, that another approach is feasible. By setting +%D the \type {autofile} variable to \type {yes} or \type +%D {page}, you can access the reference directly. +%D +%D \starttabulate[||||] +%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR +%D \NC $\star$ \NC \NC \NC\NR +%D \NC $\star$ \NC $\star$ \NC $\star$ \NC\NR +%D \NC \NC $\star$ \NC \NC\NR +%D \stoptabulate + +\unexpanded\def\usereferences[#filename]{} % obsolete + +%D As mentioned we will also use the cross reference mechanism +%D for navigational purposes. The main reason for this is that +%D we want to treat both categories alike: +%D +%D \starttyping +%D \goto{go back}[PreviousJump] +%D \goto{colofon}[colofon page] +%D \stoptyping +%D +%D Here \type{PreviousJump} is handled by the viewer, while the +%D \type{colofon page} reference is, apart from hyperlinking, a +%D rather normal reference. +%D +%D We already saw that cross refences are written to and read +%D from a file. The pure navigational ones don't need to be +%D written to file, but both for fast processing and +%D transparant integration, they are saved internally as a sort +%D of reference. We can easily distinguish such system +%D references from real cross reference ones by their tag. +%D +%D We also use the odd/even characteristic to determine the +%D page state. + +\let\currentrealreference \empty +\let\currentpagereference \empty +\let\currenttextreference \empty +\let\currentreferenceorder \empty +\let\currentsubtextreference \empty +\let\currentsubsubtextreference\empty + +\newcount\referencehastexstate % set in backend + +% referencepagestate: +% +% 0 = no page ref, 1=same page, 2=before, 3=after + +%D Cross references appear as numbers (figure~1.1, chapter~2) +%D or pagenumbers (page~2, page 3--2), and are called with +%D \type{\in} and \type{\at}. In interactive documents we also +%D have \type{\goto}, \type{\button} and alike. These are more +%D versatile and look like: +%D +%D \starttyping +%D \goto[reference] +%D \goto[outer reference::] +%D \goto[outer reference::inner reference] +%D \goto[operation(argument)] +%D \goto[operation(action{argument,argument})] +%D \goto[action] +%D \goto[action{argument}] +%D \stoptyping +%D +%D The first one is a normal reference, the second and third +%D are references to a file or \URL. The brace delimited +%D references for instance refer to a \JAVASCRIPT. The last +%D example shows that we can pass arguments to the actions. +%D +%D Now we've come to the testing step. As we can see below, +%D this macro does bit more than testing: it also resolves +%D the reference. This means that whenever we test for the +%D existance of a reference at an outer level, we have all the +%D relevant properties of that reference avaliable inside the +%D true branche~(\type{#2}). +%D +%D The prefix has to do with localizing references. When a +%D prefix is set, looking for a reference comes to looking for +%D the prefixed one, and when not found, looking for the non +%D prefixed one. Consider for instance the prefix set to +%D \type{sidetrack}. +%D +%D \starttyping +%D \pagereference[important] +%D \pagereference[unimportant] +%D \setupreferencing[prefix=sidetrack] +%D \pagereference[important] +%D \stoptyping +%D +%D results in saving (writing) the references +%D +%D \starttyping +%D ...{}{important} +%D ...{}{unimportant} +%D ...{sidetrack}{important}... +%D \stoptyping +%D +%D Now when we call for \type{unimportant}, we will indeed get +%D the pagenumber associated to this reference. But when we +%D call for \type{important}, while the prefix is still set, we +%D will get the pagenumber bound to the prefixed one. +%D +%D {\em Some day, when processing time and memory are no longer +%D performance factors, we will introduce multi||level +%D prefixes.} +%D +%D Before we start analyzing, I introduce a general +%D definition macro. Consider: +%D +%D \starttyping +%D \goto{do}[JS(My_Script{"test",123}),titlepage] +%D \stoptyping +%D +%D This can also be achieved by: +%D +%D \starttyping +%D \definereference[startup][JS(My_Script{"test",123}),titlepage] +%D \goto{do}[startup] +%D \stoptyping +%D +%D Now is this is a handy feature or not? +%D +%D \showsetup{definereference} +%D +%D We can trace references by setting the next switch to +%D true. + +\unexpanded\def\definereference + {\dodoubleempty\strc_references_define_reference} + +\def\strc_references_define_reference[#name][#specification]% + {\clf_definereference{\referenceprefix}{#name}{\detokenize{#specification}}} + +\unexpanded\def\resetreference[#name]% + {\clf_resetreference{\referenceprefix}{#name}} + +\def\setpagereference#name#specification% hm,. low level ? + {\clf_definereference{}{#name}{\v!page(\detokenize{#specification}}} % is detokenize needed here? + +%D Chained references are defined as: +%D +%D \starttyping +%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)] +%D \stoptyping +%D +%D Actually supporting chains is up to the special driver. Here +%D we only provide the hooks. + +%D \macros +%D {highlighthyperlinks} +%D +%D The next switch can be used to make user hyperlinks are +%D not highlighted when clicked on. + +\newconditional\highlighthyperlinks \settrue\highlighthyperlinks + +%D \macros +%D {gotonewwindow} +%D +%D To make the {\em goto previous jump} feature more +%D convenient when using more than one file, it makes sense +%D to force the viewer to open a new window for each file +%D opened. + +\newconditional\gotonewwindow \setfalse\gotonewwindow + +\def\expandtexincurrentreference % will happen in lua some time + {\ifcase\referencehastexstate\else\clf_expandcurrentreference\fi} + +\def\expandreferenceoperation#tag#content{\clf_setreferenceoperation#tag{#content}} +\def\expandreferencearguments#tag#content{\clf_setreferencearguments#tag{#content}} + +\def\doifelsereferencefound#label#yes#nop% + {\clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\expandtexincurrentreference + #yes}% + {#nop}} + +\let\doifreferencefoundelse \doifelsereferencefound + +%D The tester only splits the reference in components but does +%D not look into them. The following macro does a preroll and +%D determines for instance the current real reference pagenumber. +%D The \type {\currentrealreference} macro does the same so unless +%D one wants to use the pagestate the next macro seldom needs to +%D be called. + +%D The inner case is simple. Only two cases have to be taken +%D care of: +%D +%D \starttyping +%D \goto{some text}[reference] +%D \goto{some text}[prefix:reference] +%D \stoptyping +%D +%D References to other files however are treated strict or +%D tolerant, depending on their loading and availability: +%D +%D \starttyping +%D \useexternaldocument[somefile][filename][a nice description] +%D +%D \goto{checked reference}[somefile::reference] +%D \goto{unchecked reference}[somefile::] +%D \goto{unchecked reference}[anotherfile::reference] +%D \stoptyping +%D +%D An unknown reference is reported on the screen, in the log +%D file and, when enabled, in the left margin of the text. + +\let\unknownreference\gobbleoneargument + +%D When a reference is not found, we typeset a placeholder +%D (two glyphs are often enough to represent the reference +%D text). + +\def\dummyreference{{\tttf ??}} +\def\emptyreference{{\tttf !!}} + +%D To prevent repetitive messages concerning a reference +%D being defined, we set such an unknown reference to an empty +%D one after the first encounter. + +%D Apart from cross references supplied by the user, \CONTEXT\ +%D generates cross references itself. Most of them are not +%D saved as a reference, but stored with their source, for +%D instance a list or an index entry. Such automatically +%D generated, for the user invisible, references are called +%D {\em internal references}. The user supplied ones are +%D labeled as {\em external references}. +%D +%D A second important characteristic is that when we want to +%D support different backends (viewers), we need to support +%D named destinations as well as page numbers. I invite readers +%D to take a glance at the special driver modules to understand +%D the fine points of this. As a result we will deal with {\em +%D locations} as well as {\em real page numbers}. We explictly +%D call this pagenumber a real one, because it is independant +%D of the page numbering scheme used in the document. +%D +%D One of the reasons for \CONTEXT\ being the first \TEX\ base +%D macropackage to support sophisticated interactive \PDF\ +%D files, lays in the mere fact that real page numbers are +%D available in most two pass data, like references, list data +%D and index entries. +%D +%D We will speak of \type{thisis...} when we are marking a +%D location, and \type{goto...} when we point to such a +%D location. The latter one can be seen as a hyperlink to the +%D former one. In the next macros one we use constructs like: +%D +%D \starttyping +%D \dostart... +%D \dostop... +%D \stoptyping +%D +%D Such macros are used to invoke the relevant specials from +%D the special driver modules (see \type{spec-ini}). The flag +%D \type{\iflocation} signals if we're in interactive mode. + +\ifdefined\buttonheight \else \newdimen\buttonheight \fi +\ifdefined\buttonwidth \else \newdimen\buttonwidth \fi + +%D Internal references can best be set using the next few +%D macros. Setting such references to unique values is +%D completely up to the macros that call them. +%D +%D \starttyping +%D \thisissomeinternal{tag}{identifier} +%D \gotosomeinternal {tag}{identifier}{pagenumber}{text} +%D \stoptyping + +%D We could do this in lua ... + +\newif \iflocation +\newcount\locationcount +\newcount\locationorder +\newbox \locationbox + +\def\nextinternalreference {\the\locationcount} +\def\nextinternalorderreference{\the\locationorder} + +\def\setnextinternalreference + {\global\advance\locationcount\plusone} + +\def\setnextinternalreferences#kind#name% plural + {\clf_setnextinternalreference{#kind}{#name}} + +\def\getinternalorderreference#kind#name% + {\clf_currentreferenceorder{#kind}{#name}} + +\def\thisissomeinternal#kind#name% only for old time sake, will go away + {\begingroup + \clf_setinternalreference + reference {#kind:#name}% no view + \relax + \hbox attr \destinationattribute\lastdestinationattribute{}% + \endgroup} + +\installcorenamespace{savedinternalreference} + +\letvalue{\??savedinternalreference\s!default}\!!zerocount + +\unexpanded\def\storeinternalreference#1#2% + {\setxvalue{\??savedinternalreference\currentstructurename}{#2}} + +\newconditional\preferpagereferences + +\def\gotosomeinternal#kind#name#target#text% + {\ifconditional\preferpagereferences + \directgoto{#text}[page(#target)]% + \else + \directgoto{#text}[#kind:#name]% + \fi} + +\def\gotonextinternal#text#target% + {\directgoto{#text}[internal(#target)]} + +%D In this module we define three system references: one for +%D handling navigational, viewer specific, commands, another +%D for jumping to special pages, like the first or last one, +%D and a third reference for linking tree like lists, like +%D tables of contents. The latter two adapt themselves to the +%D current state. +%D +%D An example of an action is: +%D +%D \starttyping +%D \goto{some action}[PreviousJump] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[\v!action(PreviousJump] +%D \stoptyping + +%D One can also activate an automatic prefix mechanism. By +%D setting the \type{\prefix} variable to \type{+}, the prefix +%D is incremented, when set to \type{-} or empty, the prefix is +%D reset. Other values become the prefix. + +\newcount\prefixcounter + +\newconditional\autocrossfilereferences + +\appendtoks + \edef\p_autofile{\referencingparameter\c!autofile}% + \ifx\p_autofile\v!yes + \settrue \autocrossfilereferences + \else + \setfalse\autocrossfilereferences + \fi +\to \everysetupreferencing + +\appendtoks + \edef\p_export{\referencingparameter\c!export}% + \ifx\p_export\v!yes + \clf_exportreferences + \fi +\to \everygoodbye + +\unexpanded\def\setupglobalreferenceprefix[#prefix]% + {\xdef\referenceprefix{#prefix}} + +% \unexpanded\def\pushreferenceprefix#prefix% +% {\pushmacro\referenceprefix +% \xdef\referenceprefix{#prefix}} % global + +% \unexpanded\def\popreferenceprefix +% {\popmacro\referenceprefix} + +\unexpanded\def\globalpushreferenceprefix#prefix% + {\xdef\referenceprefix{\clf_pushreferenceprefix{#prefix}}} + +\unexpanded\def\globalpopreferenceprefix + {\xdef\referenceprefix{\clf_popreferenceprefix}} + +\unexpanded\def\pushreferenceprefix#prefix% + {\edef\referenceprefix{\clf_pushreferenceprefix{#prefix}}} + +\unexpanded\def\popreferenceprefix + {\edef\referenceprefix{\clf_popreferenceprefix}} + +\def\m_strc_references_prefix_yes{+} +\def\m_strc_references_prefix_nop{-} + +\unexpanded\def\setupreferenceprefix[#prefix]% + {\edef\p_prefix{#prefix}% + \ifx\p_prefix\empty + \let\referenceprefix\empty + \else\ifx\p_prefix\m_strc_references_prefix_yes + \letreferencingparameter\c!prefix\s!unknown + \global\advance\prefixcounter\plusone + \edef\referenceprefix{\the\prefixcounter}% + \else\ifx\p_prefix\m_strc_references_prefix_nop + \letreferencingparameter\c!prefix\s!unknown + \let\referenceprefix\empty + \else\ifx\p_prefix\s!unknown + % forget about it + \else + \let\referenceprefix\p_prefix + \fi\fi\fi\fi} + +\appendtoks + \setupreferenceprefix[\referencingparameter\c!prefix] +\to \everysetupreferencing + +%D We can typeset a reference using \type{\in}, \type{\at} and +%D \type{\about} and goto specific locations using +%D \type{\goto}. The last one does not make that much sense in +%D a paper document. To complicate things, \PLAIN\ \TEX\ also +%D implements an \type {\in} but fortunately that one only +%D makes sense in math mode. +%D +%D Typesetting the reference is a bit more complicated than one +%D would at first sight expect. This is due to the fact that we +%D distinguish three (five) alternative calls: +%D +%D \placefigure +%D [here][three calls] +%D {Three alternatives reference calls.} +%D {\startcombination[1*3] +%D {\framed{\type{ \in }}} {a} +%D {\framed{\type{ \at }}} {b} +%D {\framed{\type{\goto}}} {c} +%D \stopcombination} +%D +%D \startbuffer +%D \in figure[fig:three calls] +%D \in{figure}[fig:three calls] +%D \in figure a[fig:three calls] +%D \in{figure}{a}[fig:three calls] +%D figure~\in[fig:three calls] +%D \stopbuffer +%D +%D \typebuffer +%D +%D This turns up as: +%D +%D \startlines +%D \getbuffer +%D \stoplines +%D +%D The dual \type{{}} results in a split reference. In a +%D document meant for paper, one is tempted to use the last +%D (most straightforward) alternative. When a document is also +%D meant voor electronic distribution, the former alternatives +%D have preference, because everything between the \type{\in} +%D and~\type{[} becomes active (and when asked for, typeset +%D in a different color and typeface). + +% \unexpanded\def\in {\mathortext\donormalmathin \strc_references_in} +% \unexpanded\def\at {\mathortext\donormalmathat \strc_references_at} +% \unexpanded\def\about{\mathortext\donormalmathabout\strc_references_about} +% \unexpanded\def\from {\mathortext\donormalmathfrom \strc_references_from} +% \unexpanded\def\over {\mathortext\donormalmathover \strc_references_about} + +% \definecommand in {\strc_references_in} +% \definecommand at {\strc_references_at} +% \definecommand about {\strc_references_about} +% \definecommand from {\strc_references_from} +% \definecommand over {\strc_references_about} % needed here, else math problems + +\appendtoks + \ifdefined\in \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \strc_references_in } \else \let\in \strc_references_in \fi + \ifdefined\at \let\normalmathat \at \unexpanded\def\at {\mathortext\normalmathat \strc_references_at } \else \let\at \strc_references_at \fi + \ifdefined\about \let\normalmathabout\about \unexpanded\def\about{\mathortext\normalmathabout\strc_references_about} \else \let\about\strc_references_about \fi + \ifdefined\from \let\normalmathfrom \from \unexpanded\def\from {\mathortext\normalmathfrom \strc_references_from } \else \let\from \strc_references_from \fi + \ifdefined\over \let\normalmathover \over \unexpanded\def\over {\mathortext\normalmathover \strc_references_about} \else \let\over \strc_references_about \fi +\to \everydump + + \def\filterreference #key{\clf_filterreference{#key}} % no checking, expanded +\unexpanded\def\getreferenceentry#key{\clf_filterreference{#key}} % no checking, unexpanded + +\def\currentreferencenumber {\clf_filterreference{number}} +\def\currentreferencepage {\clf_filterreference{page}} +\def\currentreferencetitle {\clf_filterreference{title}} +\def\currentreferencetext {\clf_filterreference{text}} +\def\currentreferencedefault {\clf_filterreference{default}} +\def\currentreferencerealpage{\clf_filterreference{realpage}} + +%D The most straightforward way of retrieving references is +%D using \type{\ref}. + +\unexpanded\def\getreference % checking, unexpanded + {\dodoubleargument\strc_references_get_reference} + +\def\strc_references_get_reference[#key][#label]% #key = number page title text default realpage ... + {\ifsecondargument + \doifelsereferencefound{#label}{\clf_filterreference{#key}}\dummyreference + \else + \dummyreference + \fi} + +\let\ref\getreference + +%D Special cases: + +\unexpanded\def\strc_references_about[#label]% + {\dontleavehmode + \begingroup + \let\crlf\space + \let\\\space + \postponenotes % might go + \referencingparameter\c!left + \doifelsereferencefound{#label} + {\goto{\limitatetext\currentreferencetitle{\referencingparameter\c!width}\unknown}[#label]}% not so efficient (dup lookup) + {}% todo + \flushnotes % might go + \referencingparameter\c!right + \endgroup} + +%D The previously discussed setup macro lets us specify the +%D representation of references. A symbol reference does not +%D show the specific data, like the number of a figure, but +%D shows one of: \hbox {$^\goforwardcharacter$ +%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending +%D on the direction to go. +%D +%D \starttyping +%D ... \somewhere{backward text}{forward text}[someref] ... +%D ... \atpage[someref] ... +%D \stoptyping + +% standard detail +% +% 0 = unknown unknown +% 1 = same on same page +% 2 = before preceding page +% 3 = after following page +% +% 4 = above above on same page +% 5 = below below on same page + +% todo: optimize for use in pagebody +% todo: maybe make it optional + +% \setuppagenumbering[alternative=doublesided] +% \setupreferencing [doublesided=no] % yes is default +% +% \somewhere{backward}{foreward}[label] +% \someplace{preceding}{backward}{current}{foreward}{following}[label] +% \atpage[#label] +% \doifcheckedpagestate{label}{preceding}{backward}{current}{foreward}{following}{otherwise} +% +% \dorecurse {20} { +% \placefigure[here][fig:#1]{}{\externalfigure[dummy]} +% \dorecurse {20} { +% ##1: \atpage[fig:##1] / +% \doifcheckedpagestate +% {fig:##1} +% {preceding}{backward}{current}{foreward}{following} +% {otherwise} +% } +% } + +\newcount \nofreferencestates +\newconditional\pagestatespread + +\appendtoks + \doifelse{\referencingparameter\c!doublesided}\v!yes\settrue\setfalse\pagestatespread +\to \everysetupreferencing + +\setupreferencing + [\c!doublesided=\v!yes] + +\def\referencepagestate + {\numexpr\clf_referencepagestate + {rst::\number\nofreferencestates}% + \relax} + +\def\referencepagedetail + {\numexpr\clf_referencepagestate + {rst::\number\nofreferencestates}% + true % + \ifconditional\pagestatespread false\ifdoublesided true\else false\fi\fi + \relax} + +\def\referencerealpage + {\clf_referencerealpage} + +\unexpanded\def\tracedpagestate + {{\blue\tttf(\ifcase\referencepagedetail unknown\or same\or previous\or next\or above\or below\else unknown\fi)}} + +\unexpanded\def\markreferencepage + {\dontleavehmode\begingroup + \iftrialtypesetting + % issue warning that not stable + \else + % needs checking ... but probably never in trialmode + \global\advance\nofreferencestates\plusone + \xypos{rst::\number\nofreferencestates}% + % \tracedpagestate + \fi + \endgroup} + +\unexpanded\def\doifcheckedpagestate#label% #preceding#backward#current#foreward#following#otherwise% + {\doifelsereferencefound{#label}\strc_references_handle_page_state_yes\strc_references_handle_page_state_nop} + +\let\strc_references_handle_page_state_nop\sixthofsixarguments + +\def\strc_references_handle_page_state_yes + {\markreferencepage + \ifcase\referencepagedetail + \expandafter\sixthofsixarguments \or + \expandafter\thirdofsixarguments \or + \expandafter\firstofsixarguments \or + \expandafter\fifthofsixarguments \or + \expandafter\secondofsixarguments\or + \expandafter\fourthofsixarguments\else + \expandafter\sixthofsixarguments \fi} + +\unexpanded\def\referencesymbol + {\hbox\bgroup + \strut + \markreferencepage + \high + {\setupsymbolset[\interactionparameter\c!symbolset]% + \symbol[\ifcase\referencepagedetail\v!somewhere\or\v!nowhere\or\v!previous\or\v!next\or\v!previous\or\v!next\else\v!somewhere\fi]}% + \egroup} + +%D Hereafter the \type {\ignorespaces} binds the state node to next character (more likely +%D than a preceding one) and one can always add an explicit space. + +\unexpanded\def\somewhere#backward#foreward#dummy[#label]% #dummy gobbles space around #foreward + {\doifcheckedpagestate{#label}% + {\goto{#backward}[#label]}% + {\goto{#backward}[#label]}% + {\ignorespaces}% + {\goto{#foreward}[#label]}% + {\goto{#foreward}[#label]}% + {#label}}% + +\unexpanded\def\someplace#preceding#backward#current#foreward#following#dummy[#label]% #dummy gobbles space around #foreward + {\doifcheckedpagestate{#label}% + {\doifelsenothing{#preceding}{\goto{#preceding}[#label]}\ignorespaces}% + {\doifelsenothing {#backward}{\goto {#backward}[#label]}\ignorespaces}% + {\doifelsenothing {#current}{\goto {#current}[#label]}\ignorespaces}% + {\doifelsenothing {#foreward}{\goto {#foreward}[#label]}\ignorespaces}% + {\doifelsenothing{#following}{\goto{#following}[#label]}\ignorespaces}% + {#label}} + +\unexpanded\def\atpage[#label]% todo + {\doifcheckedpagestate{#label}% + {\goto{\labeltext \v!precedingpage }[#label]}% + {\goto{\labeltext \v!hencefore }[#label]}% + {\ignorespaces}% + {\goto{\labeltext \v!hereafter }[#label]}% + {\goto{\labeltext \v!followingpage }[#label]}% + {\goto{\labeltexts\v!page\dummyreference}[#label]}} + +% Someone requested this but in retrospect didn't need it so we keep it as example. +% Beware: a node is injected which is why we add ignorespaces! +% +% \unexpanded\def\strc_references_conditional#action#text[#condition]#dummy[#label]% +% {\doifcheckedpagestate{#label}% +% {\doifelse{#condition}\v!precedingpage{#action{#text}[#label]}\ignorespaces}% +% {\doifelse{#condition}\v!hencefore {#action{#text}[#label]}\ignorespaces}% +% {\doifelse{#condition}\v!current {#action{#text}[#label]}\ignorespaces}% +% {\doifelse{#condition}\v!hereafter {#action{#text}[#label]}\ignorespaces}% +% {\doifelse{#condition}\v!followingpage{#action{#text}[#label]}\ignorespaces}% +% {#label}} +% +% \unexpanded\def\conditionalat {\strc_references_conditional\at} +% \unexpanded\def\conditionalin {\strc_references_conditional\in} +% \unexpanded\def\conditionalabout{\strc_references_conditional\about} + +%D The other alternatives just conform their names: only the label, only the text, or the +%D label and the text. + +% \dounknownreference -> \dummyreference + +\def\symbolreference[#label]% for old times sake + {\goto{\referencesymbol}[#label]} + +% \referencecontentmode 0=all 1=label 2=text 3=symbol + +\newtoks\leftreferencetoks +\newtoks\rightreferencetoks +\newtoks\defaultleftreferencetoks +\newtoks\defaultrightreferencetoks + +\def\leftofreferencecontent {\nobreakspace} % we cannot do \definereferenceformat[at] .. so we need this +\let\rightofreferencecontent \empty +\let\leftofreference \empty +\let\rightofreference \empty + +\installcorenamespace{referencinginteraction} + +\def\strc_references_interaction_all + {\the\leftreferencetoks + \doifelsesometoks\leftreferencetoks \leftofreferencecontent \donothing + \leftofreference + \currentreferencecontent + \rightofreference + \doifelsesometoks\rightreferencetoks\rightofreferencecontent\donothing + \the\rightreferencetoks} + +\letvalue{\??referencinginteraction\v!all}\strc_references_interaction_all + +\setvalue{\??referencinginteraction\v!label}% + {\leftofreference + \the\leftreferencetoks + \the\rightreferencetoks + \rightofreference} + +\setvalue{\??referencinginteraction\v!text}% + {\leftofreference + \currentreferencecontent + \rightofreference} + +\setvalue{\??referencinginteraction\v!symbol}% + {\referencesymbol} + +% \def\referencesequence +% {\csname\??referencinginteraction +% \ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname +% \referencingparameter\c!interaction +% \else +% \v!all +% \fi +% \endcsname} + +\def\referencesequence + {\ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname + \expandafter\lastnamedcs + \else + \expandafter\strc_references_interaction_all + \fi} + +\newtoks\everyresetinatreference + +\appendtoks + \glet\leftofreference \relax + \glet\rightofreference\relax +\to \everyresetinatreference + +\def\strc_references_start_goto + {\dontleavehmode + \begingroup} + +\def\strc_references_stop_goto + {\the\everyresetinatreference + \endgroup} + +\def\strc_references_pickup_goto + {\dodoublegroupempty\strc_references_pickup_goto_indeed} + +\def\strc_references_pickup_goto_indeed#left#right#dummy[#label]% #dummy gobbles spaces (really needed) + {\leftreferencetoks + \iffirstargument + {#left}% + \else + \defaultleftreferencetoks + \let\leftofreferencecontent\empty + \fi + \rightreferencetoks + \ifsecondargument + {#right}% + \else + \defaultrightreferencetoks + \let\rightofreferencecontent\empty + \fi + % inefficient: double resolve + \doifelsereferencefound{#label} % we need to resolve the text + {\goto{\referencesequence}[#label]} + {\let\currentreferencecontent\dummyreference + \goto{\referencesequence}[#label]}% + \strc_references_stop_goto} + +\unexpanded\def\strc_references_in + {\strc_references_start_goto + \let\currentreferencecontent\currentreferencedefault + \strc_references_pickup_goto} + +\unexpanded\def\strc_references_at + {\strc_references_start_goto + \let\currentreferencecontent\currentreferencepage + \strc_references_pickup_goto} + +%D \macros +%D {definereferenceformat} +%D +%D The next few macros were made for for David Arnold and Taco +%D Hoekwater. They can be used for predefining reference +%D texts, and thereby stimulate efficiency. +%D +%D \starttyping +%D \definereferenceformat[informula] [left=(,right=),text=formula] +%D \definereferenceformat[informulas] [left=(,right=),text=formulas] +%D \definereferenceformat[andformula] [left=(,right=),text=and] +%D \definereferenceformat[andformulas][left=(,right=),text=and] +%D +%D \informula [b] and \informula [for:c] +%D the \informula {formulas}[b] \informula {and} [for:c] +%D the \informulas {formulas}[b] \informula {and} [for:c] +%D the \informulas [b] \informula {en} [for:c] +%D the \informulas [b] \andformula [for:c] +%D \stoptyping +%D +%D Instead of a text, one can specify a label, which should +%D be defined with \type {\setuplabeltext}. +%D +%D Watch out: the second argument is somewhat special and mostly +%D meant for a suffix to a number: +%D +%D \startbuffer +%D \definereferenceformat [intesta] [left=(,right=),text=Whatever~] +%D \definereferenceformat [intestb] [left=(,right=),label=figure] +%D +%D \placeformula[x]\startformula a \stopformula +%D +%D \starttabulate[|||||] +%D \NC \in [x] \NC \in {left}[x] \NC \in {}{right}[x] \NC \in {left}{right}[x] \NC \NR +%D \NC \intesta[x] \NC \intesta{left}[x] \NC \intesta{}{right}[x] \NC \intesta{left}{right}[x] \NC \NR +%D \NC \intestb[x] \NC \intestb{left}[x] \NC \intestb{}{right}[x] \NC \intestb{left}{right}[x] \NC \NR +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +% to be done: interfaced + +\installcorenamespace{referenceformat} + +\installcommandhandler \??referenceformat {referenceformat} \??referenceformat + +\appendtoks + \setuevalue\currentreferenceformat{\strc_references_apply_format{\currentreferenceformat}}% +\to \everydefinereferenceformat + +\setupreferenceformat + [\c!left=, + \c!right=, + \c!text=, + \c!label=, + \c!autocase=\v!no, + \c!style=, + \c!type=default, % to be done: interfaced + \c!setups=, + \c!color=] + +\unexpanded\def\strc_references_apply_format#name% + {\strc_references_start_goto + \edef\currentreferenceformat{#name}% + \gdef\leftofreference {\referenceformatparameter\c!left }% + \gdef\rightofreference {\referenceformatparameter\c!right }% + \edef\currentreferenceformatlabel {\referenceformatparameter\c!label }% + \edef\currentreferenceformattype {\referenceformatparameter\c!type }% + \edef\currentreferenceformatsetups {\referenceformatparameter\c!setups }% + \edef\currentreferenceformatautocase{\referenceformatparameter\c!autocase}% + \usereferenceformatstyleandcolor\c!style\c!color + \ifx\currentstyleparameter\empty \else + \resetinteractionparameter\c!style + \fi + \ifx\currentcolorparameter\empty \else + \resetinteractionparameter\c!contrastcolor + \resetinteractionparameter\c!color + \fi + \ifx\currentreferenceformatlabel\autoreferencelabeltextflag + \edef\currentreferenceformatlabel{\autoreferencelabeltext}% + \fi + \ifx\currentreferenceformatautocase\v!yes + \setcharactercleaning[1]% + \fi + \ifx\currentreferenceformatlabel\empty + \defaultleftreferencetoks {\referenceformatparameter\c!text}% + \defaultrightreferencetoks\emptytoks + \else + \defaultleftreferencetoks {\leftlabeltext \currentreferenceformatlabel}% + \defaultrightreferencetoks{\rightlabeltext\currentreferenceformatlabel}% + \fi + \ifx\currentreferenceformattype\empty + \def\currentreferenceformattype{default}% + \fi + % + \ifx\currentreferenceformatsetups\empty + \def\currentreferencecontent{\filterreference\currentreferenceformattype}% + \else + \def\currentreferencecontent{\directsetup\currentreferenceformatsetups}% + \fi + % + \let\leftofreferencecontent \empty + \let\rightofreferencecontent\empty + \strc_references_pickup_goto} + +\def\autoreferencelabeltextflag{*} % a proper key like 'auto' or 'name' can clash with a label key + +\unexpanded\def\autoreferencelabeltext + {\clf_getcurrentreferencemetadata{name}} + +% \starttext +% \definereferenceformat[inxx] [left=(,right=),text=txt] +% \setupinteraction[state=start] +% \chapter[one]{xx} +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% [\at{page} [one]] +% [\at{page}[one]] +% [\at{page}{okay}[one]] +% [\inxx{a}{b}[one]] +% \stoptext + +% \startsetups referenceformat:numberplustext +% \filterreference{number}, \filterreference{title} +% \stopsetups +% +% \definereferenceformat[hellup][text=Hellup ,setups=referenceformat:numberplustext] + +%D In interactive documents going to a specific location is not +%D bound to cross references. The \type{\goto} commands can be +%D used to let users access another part of the document. In +%D this respect, interactive tables of contents and registers +%D can be considered goto's. Because in fact a \type{\goto} is +%D just a reference without reference specific data, the +%D previous macros are implemented using the goto +%D functionality. +%D +%D \showsetup{goto} +%D +%D One important characteristic is that the first argument of +%D \type{\goto} (and therefore \type{\at} and \type{\in} is +%D split at spaces. This means that, although hyphenation is +%D prevented, long references can cross line endings. + +% \starttext +% \setupinteraction[state=start] +% [\goto{state}[file(mk-last-state)]] +% [\goto{state} [file(mk-last-state)]] +% \stoptext + +\newconditional\uselocationstrut \settrue\uselocationstrut + +\def\extrareferencearguments + {highlight \luaconditional\highlighthyperlinks\space + newwindow \luaconditional\gotonewwindow\space + layer {\currentviewerlayer}} + +\unexpanded\def\directgoto + {\ifconditional\uselocationstrut + \expandafter\strc_references_direct_goto + \else + \expandafter\strc_references_direct_goto_htdp + \fi} + +\unexpanded\def\goto + {\ifconditional\uselocationstrut + \expandafter\strc_references_goto + \else + \expandafter\strc_references_goto_htdp + \fi} + +% The unbox trick is needed in order to permit \par inside a reference. Otherwise +% the reference attribute migrates to the outer boxes. + +\newcount\lastsavedreferenceattribute + +\newbox\referencebox + +\def\revivesavedreferenceattribute % sometimes handy as no test etc needed + {\attribute\referenceattribute\lastsavedreferenceattribute} + +\def\strc_references_direct_goto#content[#label]% no test for valid references + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \global\lastsavedreferenceattribute\attributeunsetvalue + \iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {% + height \ht\strutbox + depth \dp\strutbox + \extrareferencearguments + }% + \relax + \setlocationattributes + \setstrut % can be option + \global\lastsavedreferenceattribute\lastreferenceattribute + \attribute\referenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty % not here + #content% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\def\strc_references_direct_goto_htdp#content[#label]% no test for valid references + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {% + height \dimexpr\interactionparameter\c!height\relax + depth \dimexpr\interactionparameter\c!depth \relax + \extrareferencearguments + }% + \relax + \setlocationattributes + \attribute\referenceattribute\lastreferenceattribute + \global\lastsavedreferenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + #content% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\def\strc_references_goto#content#dummy[#label]% #dummy gobbles spaces + {\dontleavehmode + \begingroup + %\setbox\referencebox\hbox\bgroup % experiment, might change again to non \par support + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\expandtexincurrentreference + \clf_injectcurrentreferencehtdp + \ht\strutbox + \dp\strutbox + \relax + \setlocationattributes + \setstrut % can be option + \global\lastsavedreferenceattribute\lastreferenceattribute + \attribute\referenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + #content% + \dostoptagged}% + {#content}% + \else + #content% + \fi + %\egroup\unhbox\referencebox} + \endgroup} + +\def\strc_references_goto_internal#content#dummy[#internal]% #dummy gobbles spaces + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \setstrut % can be option + \strc_references_get_simple_reference{internal(#internal)}% + \global\lastsavedreferenceattribute\currentreferenceattribute + \attribute\referenceattribute\currentreferenceattribute + \setlocationattributes + \dostarttagged\t!link\empty + #content% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\unexpanded\def\startgoto[#label]% + {\dontleavehmode + \begingroup + \iflocation + \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\expandafter\strc_references_start_goto_yes}% + {\expandafter\strc_references_start_goto_nop}% + \else + \expandafter\strc_references_start_goto_nop + \fi} + +\unexpanded\def\strc_references_start_goto_nop + {\let\stopgoto\strc_references_stop_goto_nop} + +\unexpanded\def\strc_references_stop_goto_nop + {\endgroup} + +\unexpanded\def\strc_references_start_goto_yes + {\expandtexincurrentreference + \clf_injectcurrentreferencehtdp + \ht\strutbox + \dp\strutbox + \relax + \setlocationattributes + \setstrut % can be option + \global\lastsavedreferenceattribute\lastreferenceattribute + \attribute\referenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + \let\stopgoto\strc_references_stop_goto_yes} + +\unexpanded\def\strc_references_stop_goto_yes + {\dostoptagged + \endgroup} + +\def\strc_references_goto_htdp#content#dummy[#label]% dummy gobbles spaces + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\expandtexincurrentreference + \clf_injectcurrentreferencehtdp + \dimexpr\interactionparameter\c!height\relax + \dimexpr\interactionparameter\c!depth \relax + \relax + \setlocationattributes + \global\lastsavedreferenceattribute\lastreferenceattribute + \attribute\referenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + #content% + \dostoptagged}% + {#content}% + \else + #content% + \fi + \endgroup} + +\unexpanded\def\directgotobox#content[#label]% no test for valid references + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {\extrareferencearguments}% + \relax + \setlocationattributes + \global\lastsavedreferenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + \hbox attr \referenceattribute \lastreferenceattribute {#content}% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\unexpanded\def\directgotospecbox#resolver#content[#label]% no test for valid references + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {\extrareferencearguments}% + \relax + \setlocationcolorspec{#resolver}% no consequence for strut + \global\lastsavedreferenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + \hbox attr \referenceattribute \lastreferenceattribute {#content}% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\unexpanded\def\directgotodumbbox#content[#label]% no test for valid references + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_injectreference + {\referenceprefix}% + {#label}% + {\extrareferencearguments}% + \relax + \global\lastsavedreferenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + \hbox attr \referenceattribute \lastreferenceattribute {#content}% + \dostoptagged + \else + #content% + \fi + \endgroup} + +\unexpanded\def\gotobox#content[#label]% + {\dontleavehmode + \begingroup + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \iflocation + \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\expandtexincurrentreference + \clf_injectcurrentreference + \setlocationattributes + \global\lastsavedreferenceattribute\lastreferenceattribute + \dostarttagged\t!link\empty + \hbox attr \referenceattribute \lastreferenceattribute {#content}% + \dostoptagged}% + {#content}% + \else + #content% + \fi + \endgroup} + +\unexpanded\def\gotowdhtbox#width#height[#label]% fast variant for overlays + {\dontleavehmode + \begingroup + \setbox\scratchbox\emptyhbox + \wd\scratchbox#width% + \ht\scratchbox#height% + \global\lastsavedreferenceattribute\attributeunsetvalue + \attribute\referenceattribute\attributeunsetvalue + \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% + {\clf_injectcurrentreference + \global\lastsavedreferenceattribute\lastreferenceattribute + \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}} + {\box\scratchbox}% + \endgroup} + +%D An reference to another document can be specified as a file +%D or as an \URL. Both are handled by the same mechanism and +%D can be issued by saying something like: +%D +%D \starttyping +%D \goto[dictionary::the letter a] +%D \stoptyping +%D +%D One can imagine that many references to such a dictionary +%D are made, so in most cases such a document reference in an +%D indirect one. +%D +%D \showsetup{useexternaldocument} +%D +%D For example: +%D +%D \starttyping +%D \useexternaldocument +%D [dictionary][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D The next macro implements these relations, and also take +%D care of loading the document specific references. +%D +%D The \URL\ alternative takes four arguments: +%D +%D \showsetup{useURL} +%D +%D like: +%D +%D \starttyping +%D \useURL +%D [dictionary][http://www.publisher.com/public][engldict] +%D [The Famous English Dictionary] +%D \stoptyping +%D +%D Several specifications are possible: +%D +%D \starttyping +%D \useURL [id] [url] [file] [description] +%D \useURL [id] [url] [file] +%D \useURL [id] [url] +%D \stoptyping +%D +%D This time we don't load the references when no file is +%D specified. This is logical when one keeps in mind that a +%D valid \URL\ can also be a mail address. + +\unexpanded\def\useurl {\doquadrupleempty\strc_references_use_url } % so that they can be used in expanded arguments +\unexpanded\def\usefile{\dotripleargument\strc_references_use_file} % so that they can be used in expanded arguments + +\let\useURL \useurl +\let\useexternaldocument\usefile + +\def\strc_references_use_url[#label][#url][#file][#description]% + {\clf_useurl{#label}{\detokenize{#url}}{\detokenize{#file}}{\detokenize{#description}}} + +\def\strc_references_use_file[#label][#file][#description]% + {\clf_usefile{#label}{\detokenize{#file}}{\detokenize{#description}}} + +\def\doifelseurldefined #label{\clf_doifelseurldefined {#label}} +\def\doifelsefiledefined#label{\clf_doifelsefiledefined{#label}} + +\let\doifurldefinedelse \doifelseurldefined +\let\doiffiledefinedelse\doifelsefiledefined + +%D \macros +%D {url,setupurl} +%D +%D We also have: \type{\url} for directly calling the +%D description. So we can say: +%D +%D \starttyping +%D \useURL [one] [http://www.test.nl] +%D \useURL [two] [http://www.test.nl] [] [Some Site] +%D +%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)] +%D \stoptyping +%D +%D An \URL\ can be set up with +%D +%D \showsetup{setupurl} + +\installcorenamespace{url} + +\installdirectcommandhandler \??url {url} + +\setupurl + [\c!style=\v!type, + \c!color=] + +\unexpanded\def\url[#label]% move \hyphenatedurl to lua end (is already lua) + {\dontleavehmode + \begingroup + \useurlstyleandcolor\c!style\c!color + \hyphenatedurl{\clf_geturl{#label}}% + \endgroup} + +%D This macro is hooked into a support macro, and thereby +%D \URL's break ok, according to the setting of a switch, +%D +%D \startbuffer +%D \useURL +%D [test] +%D [sentence_sentence~sentence//sentence:sentence.sentence] +%D \stopbuffer +%D +%D \typebuffer +%D +%D Such an \URL\ is, depending on the settings, hyphenated as: +%D +%D \getbuffer + +%D When defining the external source of information, one can +%D also specify a suitable name (the last argument). This name +%D can be called upon with: +%D +%D \showsetup{from} +%D +%D We keep this for compatibility reasons, hence the hackery. + +\unexpanded\def\strc_references_from + {\dosingleempty\strc_references_do_special_from} + +\def\strc_references_do_special_from[#label]% + {\dontleavehmode + \goto{\clf_from{#label}}[fileorurl(#label)]} + +\def\dofromurldescription#content% called at the lua end + {#content} + +\def\dofromurlliteral#content% called at the lua end + {\useurlstyleandcolor\c!style\c!color + \hyphenatedurl{#content}} + +\let\dofromfiledescription\dofromurldescription +\let\dofromfileliteral \dofromurlliteral % maybe some day setupfile that inherits from url + +%D We also support: +%D +%D \starttyping +%D \goto{some text}[file(identifier{location}] +%D \stoptyping +%D +%D which is completely equivalent with +%D +%D \starttyping +%D \goto{some text}[identifier::location] +%D \stoptyping + +%D A special case of references are those to programs. These, +%D very system dependant references are implemented by abusing +%D some of the previous macros. +%D +%D \showsetup{setupprograms} +%D \showsetup{defineprogram} +%D \showsetup{program} % changed functionality ! +%D +%D The latter gives access to the description of the program, +%D being the last argument to the definition command. + +% also lua, like urls and files + +\installcorenamespace{programs} + +\installdirectcommandhandler \??programs {programs} + +\unexpanded\def\defineprogram + {\dotripleargument\strc_references_define_program} + +\def\strc_references_define_program[#name][#program][#description]% + {\clf_defineprogram{#name}{#program}{#description}} + +\def\program[#name]% incompatible, more consistent, hardy used anyway + {\dontleavehmode + \begingroup + \useprogramsstyleandcolor\c!style\c!color + \clf_getprogram{#name}% + \endgroup} + +%D As we can see, we directly use the special reference +%D mechanism, which means that +%D +%D \starttyping +%D \goto{some text}[program(name{args})] +%D \stoptyping +%D +%D is valid. + +%D The next macro provides access to the actual pagenumbers. +%D When documenting and sanitizing the original reference +%D macros, I decided to keep the present meaning as well as to +%D make this meaning available as a special reference method. +%D So now one can use: +%D +%D \starttyping +%D \gotopage{some text}[location] +%D \gotopage{some text}[number] +%D \gotopage{some text}[file::number] +%D \stoptyping +%D +%D as well as: +%D +%D \starttyping +%D \goto{some text}[page(location)] +%D \goto{some text}[page(number)] +%D \goto{some text}[file::page(number)] +%D \stoptyping +%D +%D Here location is a keyword like \type{nextpage}. +%D +%D \showsetup{gotopage} + +\unexpanded\def\definepage + {\dodoubleargument\strc_references_define_page} + +\def\strc_references_define_page[#name][#target]% + {\definereference[#name][page(#target)]} + +\def\gotopage#text[#target]% + {\goto{#text}[\v!page(#target)]} + +%D The previous definitions are somewhat obsolete so we don't +%D use it here. + +%D We can cross link documents by using: +%D +%D \showsetup{coupledocument} +%D +%D like: +%D +%D \starttyping +%D \coupledocument[print][somefile][chapter,section] +%D \stoptyping +%D +%D After which when applicable, we have available the +%D references: +%D +%D \starttyping +%D \goto{print version}[print::chapter] +%D \stoptyping +%D +%D and alike. The title placement definition macros have a +%D key \type{file}, which is interpreted as the file to jump +%D to, that is, when one clicks on the title. + +\def\coupledocument + {\doquadrupleempty\strc_references_couple_document} + +\def\strc_references_couple_document[#name][#file][#sections][#description]% + {\ifthirdargument + % this will be done differently (when it's needed) + \fi} + +%D \macros +%D {dotextprefix} +%D +%D In previous macros we used \type {\dotextprefix} to +%D generate a space between a label and a number. +%D +%D \starttyping +%D \dotextprefix{text} +%D \stoptyping +%D +%D Only when \type {text} is not empty, a space is inserted. + +\unexpanded\def\dotextprefix#text% + {\begingroup + \setbox\scratchbox\hbox{#text}% to be solved some day + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \edef\p_separator{\referencingparameter\c!separator}% + \ifx\p_separator\empty \else + \removeunwantedspaces % remove is new + \p_separator + \fi + \else + \unhbox\scratchbox + \fi + \endgroup} + +%D In the next settings we see some variables that were not +%D used here and that concern the way the pagenumbers refered +%D to are typeset. + +\setupreferencing + [\c!state=\v!start, + \c!autofile=\v!no, + \v!part\c!number=\v!yes, + \v!chapter\c!number=\v!no, + \c!interaction=\v!all, + \c!convertfile=\v!no, + %\c!strut=\v!no, % some day an option + \c!prefix=, + \c!width=.75\makeupwidth, + \c!left=\quotation\bgroup, + \c!right=\egroup, + \c!global=\v!no, + \c!expansion=\v!no, + \c!separator=\nonbreakablespace, + \c!export=\v!no] + +\setupprograms + [\c!directory=, + \c!style=\v!type, + \c!color=] + +\definereference [\v!CloseDocument ] [action(close)] +\definereference [\v!ExitViewer ] [action(exit)] +\definereference [\v!FirstPage ] [action(first)] +\definereference [\v!LastPage ] [action(last)] +\definereference [\v!NextJump ] [action(forward)] +\definereference [\v!NextPage ] [action(next)] +\definereference [\v!PauseMovie ] [action(pausemovie)] +\definereference [\v!PauseSound ] [action(pausesound)] +\definereference [\v!PauseRendering ] [action(pauserendering)] +\definereference [\v!PreviousJump ] [action(backward)] +\definereference [\v!PreviousPage ] [action(previous)] +\definereference [\v!PrintDocument ] [action(print)] +\definereference [\v!SaveForm ] [action(exportform)] +\definereference [\v!LoadForm ] [action(importform)] +\definereference [\v!ResetForm ] [action(resetform)] +\definereference [\v!ResumeMovie ] [action(resumemovie)] +\definereference [\v!ResumeSound ] [action(resumesound)] +\definereference [\v!ResumeRendering ] [action(resumerendering)] +\definereference [\v!SaveDocument ] [action(save)] +\definereference [\v!SaveNamedDocument] [action(savenamed)] +\definereference [\v!OpenNamedDocument] [action(opennamed)] +\definereference [\v!SearchDocument ] [action(search)] +\definereference [\v!SearchAgain ] [action(searchagain)] +\definereference [\v!StartMovie ] [action(startmovie)] +\definereference [\v!StartSound ] [action(startsound)] +\definereference [\v!StartRendering ] [action(startrendering)] +\definereference [\v!StopMovie ] [action(stopmovie)] +\definereference [\v!StopSound ] [action(stopsound)] +\definereference [\v!StopRendering ] [action(stoprendering)] +\definereference [\v!SubmitForm ] [action(submitform)] +\definereference [\v!ToggleViewer ] [action(toggle)] +\definereference [\v!ViewerHelp ] [action(help)] +\definereference [\v!HideField ] [action(hide)] +\definereference [\v!ShowField ] [action(show)] +\definereference [\v!GotoPage ] [action(gotopage)] +\definereference [\v!Query ] [action(query)] +\definereference [\v!QueryAgain ] [action(queryagain)] +\definereference [\v!FitWidth ] [action(fitwidth)] +\definereference [\v!FitHeight ] [action(fitheight)] +\definereference [\v!ShowThumbs ] [action(thumbnails)] +\definereference [\v!ShowBookmarks ] [action(bookmarks)] + +\definereference [\v!HideLayer ] [action(hidelayer)] +\definereference [\v!VideLayer ] [action(videlayer)] +\definereference [\v!ToggleLayer ] [action(togglelayer)] + +\definereference [\v!firstpage] [page(firstpage)] +\definereference [\v!previouspage] [page(previouspage)] +\definereference [\v!nextpage] [page(nextpage)] +\definereference [\v!lastpage] [page(lastpage)] +\definereference [\v!forward] [page(forward)] +\definereference [\v!backward] [page(backward)] +\definereference [\v!firstsubpage] [page(firstsubpage)] +\definereference [\v!previoussubpage] [page(previoussubpage)] +\definereference [\v!nextsubpage] [page(nextsubpage)] +\definereference [\v!lastsubpage] [page(lastsubpage)] + +% we can do this but only when later in resolve (else problems with \chapter[first]{...} +% +% \definereference [\v!first] [page(firstpage)] +% \definereference [\v!previous] [page(prevpage)] +% \definereference [\v!next] [page(nextpage)] +% \definereference [\v!last] [page(lastpage)] +% \definereference [\v!first\v!sub] [page(firstsubpage)] +% \definereference [\v!previous\v!sub] [page(prevsubpage)] +% \definereference [\v!next\v!sub] [page(nextsubpage)] +% \definereference [\v!last\v!sub] [page(lastsubpage)] + +%D We cannot set up buttons (not yet, this one calls a menu macro): + +%D New (and experimental): + +% \starttext +% \chapter{test} +% \placefigure[here][xx:1]{}{\framed{one}} \placefigure[here][xx:2]{}{\framed{three}} +% \placetable [here][xx:3]{}{\framed{two}} \placetable [here][xx:4]{}{\framed{four}} +% \start +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[float][default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank \start +% \setupreferencestructureprefix[figure][default][prefix=no] +% \in{fig}[xx:1] and \in{fig}[xx:2] \in{tab}[xx:3] and \in{tab}[xx:4] +% \stop \blank +% \stoptext + +% todo: parameterhandler + +\installcorenamespace{referencingprefix} + +\def\getreferencestructureprefix#kind#name#category% name will change + {{% + prefix {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefix}% + separatorset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixseparatorset}% + conversion {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconversion}% + conversionset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconversionset}% + starter {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixstarter}% + stopper {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixstopper}% + set {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixset}% + segments {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixsegments}% + connector {\referencestructureprefixparameter{#kind}{#name}{#category}\c!prefixconnector}% + }% + {% + separatorset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberseparatorset}% + conversion {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberconversion}% + conversionset {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberconversionset}% + starter {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberstarter}% + stopper {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numberstopper}% + segments {\referencestructureprefixparameter{#kind}{#name}{#category}\c!numbersegments}% + }} + +\unexpanded\def\setupreferencestructureprefix + {\dotripleempty\strc_references_setup_reference_structure_prefix} + +\def\strc_references_setup_reference_structure_prefix[#kind][#category][#settings]% + {\ifthirdargument + \getparameters[\??referencingprefix#kind:#category][#settings]% + \else\ifsecondargument + \getparameters[\??referencingprefix:#kind][#category]% + \fi\fi} + +\def\referencestructureprefixparameter#kind#name#category#parameter% + {\ifcsname\??referencingprefix#name:#category#parameter\endcsname + \lastnamedcs + \else\ifcsname\??referencingprefix#kind:#category#parameter\endcsname + \lastnamedcs + \else\ifcsname\??referencingprefix:#category#parameter\endcsname + \lastnamedcs + \fi\fi\fi} + +\def\currentreferencedefault % for some reason we need to explicitly expand + {\normalexpanded{\noexpand\clf_filterdefaultreference + {\s!default}% + \noexpand\getreferencestructureprefix\clf_getcurrentprefixspec{\s!default}% returns #kind#name#category + \relax}} + +%D Not all support is visible by looking at the \TEX\ code; here is one of those:^ +%D +%D \starttyping +%D \startinteractionmenu[right] +%D \startbut [section(first {chapter})] first chapter \stopbut +%D \startbut [section(previous{chapter})] previous chapter \stopbut +%D \startbut [section(next {chapter})] next chapter \stopbut +%D \startbut [section(last {chapter})] last chapter \stopbut +%D \blank[2*big] +%D \startbut [section(first {section})] first section \stopbut +%D \startbut [section(previous{section})] previous section \stopbut +%D \startbut [section(next {section})] next section \stopbut +%D \startbut [section(last {section})] last section \stopbut +%D \stopinteractionmenu +%D \stoptyping + +%D Relatively new: +%D +%D \starttyping +%D \chapter{The never ending story} +%D +%D \section{An ending story} +%D +%D \in{chapter}[match(complex bibliographies)] +%D \in{chapter}[match(never ending)] +%D \in{chapter}[match(ending)] +%D \in{chapter}[match(chapter:never ending)] +%D \in{chapter}[match(chapter:ending)] +%D \in{section}[match(section:ending)] +%D \in{figure}[match(float:mess)] +%D \in{figure}[match(figure:mess)] +%D \in{figure (not found)}[match(section:mess)] +%D \in{figure (not found)}[match(section:xxxx)] +%D \in{figure}[match(mess)] +%D +%D \placefigure{What a mess}{} +%D +%D \chapter{About complex bibliographies} +%D +%D \in{chapter}[match(complex bibliographies)] +%D \in{chapter}[match(never ending)] +%D \in{figure}[match(mess)] +%D \stoptyping + +%D Tracing: + +\unexpanded\def\strc_references_tracer#1#2% \csleft csright + {\hbox to \zeropoint \bgroup + \hss + \infofont + \darkblue + \ifx#1\empty\else + \raise\strutht \hbox \s!to \zeropoint \bgroup + \hss#1\hskip.2\emwidth + \egroup + \fi + \vrule \s!height 1.5\strutht \s!depth \strutdp \s!width .1\emwidth + \ifx#2\empty\else + \raise\strutht \hbox \s!to \zeropoint \bgroup + \hskip.2\emwidth#2\hss + \egroup + \fi + \hss + \egroup}% + +\protect \endinput + +% tricky: +% +% \enabletrackers[nodes.references] +% \setupinteraction[state=start] +% \def\KnuthTest{\input knuth } +% \def\KnuthTest{\input tufte } +% \def\TufteTest{\input tufte } +% \defineoverlay[xxx][\overlaybutton{page(3)}] +% \setupbackgrounds[text][background=xxx] +% \starttext +% test {\red \KnuthTest} test \par +% \button{test}[page(1)] \par +% \goto{page 2 \TeX}[page(2)] \goto{page 2 \TeX}[page(2)] \goto{\TufteTest}[page(2)] test \page +% test \goto{page 3}[page(3)] \goto{\TufteTest\space\par\TufteTest}[page(4)] test \page +% \goto{page 1}[page(1)] \goto{\TufteTest\space test}[page(1)] \page +% \goto{page 1}[page(1)] \goto{\KnuthTest\space test}[page(1)] \page +% test \goto{page 1}[page(1)] {\goto{\KnuthTest\space test}[page(1)]} test +% \goto{page 1}[page(1)] \goto{\TufteTest}[page(1)] test \page +% \stoptext |