3

In Making broken references extra-visible, I asked how to make LaTex's normal ?? and [?] markers for broken references instead render as some super-annoying, colored text, so that in skimming a long book-class document, I can know instantly what needs fixing.

I have been instructed now how to do this for broken \refs, but the MWE I provided was too minimal: I'd also like to know how to similarly mark broken \cites.

Here is an MWE in case there is any doubt what I mean by this.

 \documentclass{article}
 \usepackage{amsthm,hyperref}
 \bibliographystyle{amsalpha}
 \newtheorem{theorem}{Theorem}
 \begin{document}
 \begin{theorem}\label{catfish}
 \end{theorem}
 Theorem \ref{catfish} implies the truth of Theorem \ref{god}, 
 as explained in \cite{what}.
 \bibliography{bibshort}{}
 \end{document}.

I was encouraged to use BibLaTeX, but in creating this MWE found that don't seem to be able to use BibLaTeX on my computer, so for the moment I am asking about BibTex. (I would have asked the other question first, but because I started this one first, it seems the site's software requires me to either post it or delete it before I can ask a different question.)

jdc
  • 1,245
  • This will be a lot easier with BibLaTeX - in part because the missing stuff is more visible by default (bold bibkeys are easier to spot than a couple of question marks, typically). You do know that LaTeX gives you this information on the console and in the log, right? So you can easily get a list of all the unresolved things with their locations in the document? – cfr Jan 25 '15 at 03:08
  • Okay, I'm trying to figure out BibLaTeX, but my computer and I guess my computer literacy are against me. I know about the existence of the log, and often watch it slowly generate while my files compile, but I'm not great at searching through and interpreting the output. Most of it, I just don't understand. – jdc Jan 25 '15 at 03:42
  • 2
    grep -i undefined <filename>.log will give you a list of lines like LaTeX Warning: Citation 'bibkey' on page 134 undefined on input line 234. With similar things for unresolved cross references etc. With a little sed, sort and uniq you can parse this further if you wish to e.g. give you a simple list of all undefined bibkeys, or a list of all unresolved references to figures. Or whatever. That is, you have *your computer* filter the bits you are interested in so that *you* don't have to. For long documents, obviously - not for a couple of pages. – cfr Jan 25 '15 at 03:47
  • But you don't need any of that just to use biblatex and biber ;). – cfr Jan 25 '15 at 03:48
  • That's really helpful, actually. But I'm really committed to getting the original thing to work now, though, because I've sunk time into it now. I don't know what I need to use biblatex and biber, apparently. =| – jdc Jan 25 '15 at 04:14
  • 2
    I somewhat feel that achieving this with cleveref and biblatex are two completely unrelated (safe for the goal, of course); so you might benefit from splitting this question in two. – moewe Jan 25 '15 at 08:16
  • I agree about the split. However, although tagged biblatex, the question is actually about bibtex. But that is again different from cleveref. – cfr Jan 25 '15 at 13:58
  • All right, I'm doing it. I feel like I've asked way too many questions about this now, but thanks for the suggestion. – jdc Jan 27 '15 at 00:47
  • Due entirely to the heroics of other people, I've finally gotten biblatex and biber to work, so feel free to tell me what I should do with biblatex. My idea was to use \@setcite in analogy with the other answers, but that doesn't seem to do it. – jdc Jan 27 '15 at 20:50
  • 1
    @moewe: do you have advice on how to achieve these highly visible reference errors with BibLaTeX? I worry that because this question isn't new anymore, it won't get answered, because it took me so long to get BibLaTeX working. – jdc Feb 05 '15 at 05:11
  • @cfr: "[with BibLaTeX,] the missing stuff is more visible by default (bold bibkeys are easier to spot than a couple of question marks, typically)" - I vehemently disagree, at least when applying a wider definition of "visible". I just came to this question while searching for a way to make BibLaTeX behave the same as BibTeX by inserting question marks instead of the bolded bibkeys for broken citation references. Using full text search in a large document to find question marks is a great way to find broken citations, but how do I possibly search for arbitrary bolded text? – O. R. Mapper Sep 24 '15 at 12:49
  • @O.R.Mapper I don't think there is any need for vehement disagreement. I agree that if you want to search the output for strings, clearly ?? are easier to find. I wouldn't call this visibility but, hey, maybe your eyes work differently from mine. (Actually, this is overwhelmingly likely since my eyes do not work in the normal human fashion.) But if I'm searching rather than visually scanning, I wouldn't search for ?? or bibkeys. I wouldn't search the output at all. Plain text is so much easier to search and parse, I don't see the point in searching the DVI/PDF/PS. – cfr Sep 24 '15 at 21:48

1 Answers1

1

Update

With newer biblatex versions we can simply redefine the macro \abx@missing@entry to change what is shown when a citation is not found.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber, style=numeric]{biblatex}
\usepackage{xcolor}
\addbibresource{biblatex-examples.bib}

\makeatletter \def\abx@missing@entry#1{% {\bfseries\color{red} undefined Label: #1}} \makeatother

\begin{document} \cite{cicero}

\cite{lorem} \end{document}


Old answer

With biblatex, we have to modify \blx@citation@entry, a command called for each citation item:

\makeatletter
\def\blx@citation@entry#1#2{%
  \blx@bibreq{#1}%
  \ifinlist{#1}{\blx@cites}
    {}
    {\listgadd{\blx@cites}{#1}%
     \blx@auxwrite\@mainaux{}{\string\abx@aux@cite{#1}}}%
  \ifinlistcs{#1}{blx@segm@\the\c@refsection @\the\c@refsegment}
    {}
    {\listcsgadd{blx@segm@\the\c@refsection @\the\c@refsegment}{#1}}%
  \blx@ifdata{#1}
    {}
    {\ifcsdef{blx@miss@\the\c@refsection}
       {\ifinlistcs{#1}{blx@miss@\the\c@refsection}
          {{\bfseries\color{red} undefined Label:} }
          {\blx@logreq@active{#2{#1}}}}
       {\blx@logreq@active{#2{#1}}}}}
\makeatother

To get rid of a spurious space, we can also redefine (this has to be placed within a \makeatletter ... \makeatother group)

\def\blx@citeadd#1{%
  \ifcsdef{blx@keyalias@\the\c@refsection @#1}
    {\edef\blx@realkey{\csuse{blx@keyalias@\the\c@refsection @#1}}}
    {\def\blx@realkey{#1}}%
  \expandafter\blx@citation\expandafter{\blx@realkey}\blx@msg@cundefon
  \expandafter\blx@ifdata\expandafter{\blx@realkey}
    {\advance\blx@tempcnta\@ne
     \listeadd\blx@tempa{\blx@realkey}}
    {\ifnum\blx@tempcntb>\z@\multicitedelim\fi
     \expandafter\abx@missing\expandafter{\blx@realkey}%
     \advance\blx@tempcntb\@ne}}

Where we added a % at the end of the second-to-last line.

MWE

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[backend=biber, style=numeric]{biblatex}
\usepackage{xcolor}
\addbibresource{biblatex-examples.bib}

\makeatletter \def\blx@citation@entry#1#2{% \blx@bibreq{#1}% \ifinlist{#1}{\blx@cites} {} {\listgadd{\blx@cites}{#1}% \blx@auxwrite@mainaux{}{\string\abx@aux@cite{#1}}}% \ifinlistcs{#1}{blx@segm@\the\c@refsection @\the\c@refsegment} {} {\listcsgadd{blx@segm@\the\c@refsection @\the\c@refsegment}{#1}}% \blx@ifdata{#1} {} {\ifcsdef{blx@miss@\the\c@refsection} {\ifinlistcs{#1}{blx@miss@\the\c@refsection} {{\bfseries\color{red} undefined Label:} } {\blx@logreq@active{#2{#1}}}} {\blx@logreq@active{#2{#1}}}}}

\def\blx@citeadd#1{% \ifcsdef{blx@keyalias@\the\c@refsection @#1} {\edef\blx@realkey{\csuse{blx@keyalias@\the\c@refsection @#1}}} {\def\blx@realkey{#1}}% \expandafter\blx@citation\expandafter{\blx@realkey}\blx@msg@cundefon \expandafter\blx@ifdata\expandafter{\blx@realkey} {\advance\blx@tempcnta@ne \listeadd\blx@tempa{\blx@realkey}} {\ifnum\blx@tempcntb>\z@\multicitedelim\fi \expandafter\abx@missing\expandafter{\blx@realkey}% \advance\blx@tempcntb@ne}} \makeatother

\begin{document} \cite{cicero}

\cite{lorem} \end{document}

enter image description here

moewe
  • 175,683
  • Is "lorem" in your bib document then? I've just inserted the code in with the other replacement commands, and so far it looks the same as before. My preamble contains all the packages in yours, so I wonder if something's clashing with it. – jdc Feb 06 '15 at 06:43
  • @jdc Of, course not, that was the point ;-). You can try the MWE on your machine (biblatex-example.bib is a file that comes with every biblatex installation) and tell me whether or not it works. If it does work as expected, the clash is probably caused by some other package you load (though that would be really weird). – moewe Feb 06 '15 at 06:47
  • Right, I meant "Cicero"; he is. Sorry. It works! I just needed to run biber again, and forgot for some stupid reason. Thanks! One difference: my undefined label is encased with a bracket, when I run it in my real document, with one extra space after the undefined thing; e.g., "[undefined Label: lorem ]". Any idea how I could rid myself of this space? – jdc Feb 07 '15 at 21:20
  • @jdc The square brackets are probably only there in numerical citations. I think getting rid of the space is quite involved and not really worth the hassle. After all, this kind of typographical glitch makes you notice and want to fix the missing reference even more :-). – moewe Feb 08 '15 at 07:34
  • 1
    @jdc Scrap my earlier comment, it was not that hard to get rid of the space after all. This is probably a bug in biblatex. See the edit for a work-around. – moewe Feb 08 '15 at 08:43
  • 1
    Thanks! What should I read to understand what you've done here? – jdc Feb 09 '15 at 09:18
  • 1
    @jdc These are all internal macros and commands (mostly from biblatex2.sty), so they are sparsely (if at all) documented. Mostly I try to understand the internal structure of the code by examining it and playing around with the code. Note that a work-around for the space problem has been incorporated into biblatex (bug report #296) and will (probably) be available with the next release. (At which point it would be advisable to get rid of my work-around - the \def\blx@citeadd#1{% part - to avoid complications.) – moewe Feb 09 '15 at 17:31