# Conditional cross references (\in and \at) in ConTeXt?

I am currently in the process of writing a comprehensive theoretical manual for my students. To make it easier to compile texts of varying difficulties for different groups of students, I also make heavy use of modes: These enable me to, say, exclude chapters that are intended for second-year-students from PDFs for first-year-students.

To make reading easier, I'm also using a lot of cross references (\in and \at). Unfortunately, that results in a problem, when a section that I'm referencing is excluded during compilation: Obviously, instead of the reference, the final PDF now shows something like "see chapter ??".

I would like to prevent that. Ideally, I would like to set up a new command that shows the full text of the reference only when the reference exists and is being included. Is that possible?

To make clearer what I'm talking about, here's a MWE (the advanced section might be excluded by compiling with context --mode=firstyear ...):

\defineblock[advanced]

\startmodeset
\stopmodeset

\def\condin#1#2{%
% the text specified by #1 should be hidden,
% when the reference #2 does not exist.
}

\starttext

\chapter{Testing Conditional Cross References}

\input{knuth}

\section[sec:intermediate]{Intermediate Section}

\input{knuth}

\section[sec:beginner]{Beginner Section}

This section explains the topic in beginner's terms
and refers to another chapter for more advanced details:

This whole sentence should be excluded from the PDF,
when the references sec:advanced does not exist.

\stoptext


Any help would be much appreciated.

• What is the desired output when mode firstyear is enabled? Simply omit the reference:Please see for more details. or omit the complete line? Nov 28 '17 at 12:42
• Does \doifreferencefoundelse do what you want?. The other option is to redefine \dummyreference to something other than ??. Nov 28 '17 at 12:45
• Yes, the intended output would be to omit the complete line, which is why I would probably define a new command, like \condin{sentence}{reference}. I didn't know that \doifreferencefoundelse exists, I will need to experiment with that. Thank you! Nov 28 '17 at 13:11
• I now tried \doifreferencefoundelse... what a pity that it's not documented too well. But it does exactly what I needed. Thank you very much! Would you like to post your comment as an answer so that I can accept it? Nov 28 '17 at 13:20
• Possible duplicate of How to test if a label exists Mar 21 '18 at 23:05

ConTeXt provides a command \doifreferenceelse (which is a synonym for \doifelsereference), which has the following syntax:

\doifreferenceelse{name}{yes branch}{no branch}


This is similar to the other \doif...else macros.

Just in case, anybody is looking for a solution to a similar problem, I'm posting the code that I am using here.

First of all, thanks to @Aditya, who made me aware of the command \doifreferencefoundelse: This was the last building block that I needed. In a nutshell, I defined a new command \condref like this:

\startluacode
userdata = userdata or {}

function userdata.findreference(str)
_, _, inreference = string.find(str, "\\in[^%[]*%[([^%]]+)%]")
_, _, atreference = string.find(str, "\\at[^%[]*%[([^%]]+)%]")
if inreference == nil then
context(atreference)
else
context(inreference)
end
end
\stopluacode

\def\condref#1{%
\doifreferencefoundelse{\ctxlua{userdata.findreference([[#1]])}}
{#1}
{}
}


This command calls some Lua code to extract the exact cross reference from argument #1 (as specified by \in{...}[...] or \at{...}[...]). Then \doifreferencefoundelse checks, whether the cross reference exists: If it does, the full code from argument #1 is included; if the cross reference is missing, however, the text is deleted (i.e. nothing is included). (This is the first time I'm writing Lua code, so I'd be happy, if somebody could help me make the code more efficient. E.g. I'm not sure, if there's an or construction available (like (in|at))?)

I can now use the command like this:

She took down a jar from one of the shelves as she passed; it was labelled

If the section that's referenced by sec:marmalade exists, the whole footnote is included; if it doesn't (in my case this could happen due to the section being excluded by a compilation mode) the footnote is left out.