check-undefined: $(BUILDDIR)/$(PN).log
@! grep -i 'undefined' $<
+# Ensure that all labels are actually referenced. There is already a
+# tool for this, but it doesn't support cleverref:
+#
+# https://github.com/jlelong/chklref/issues/2
+#
+# Here we implement our own. The initial sed commands look for any
+# PAIR of lines that contain a label or reference, and then print the
+# pair after replacing the newline with a space and consolidating
+# multiple spaces. This result has all labels or references on a
+# single line, where they can be grepped. We accept any kind of "ref"
+# except hrefs, because those aren't references (they're URLS).
+#
+# The greps are straightforward, and then we sed off the label{} or
+# ref{} leaving only the names. Keeping in mind that multiple labels
+# can be referenced by a single comma-separated ref{}, we split those
+# onto multiple lines.
+#
+# The check-undefined target below already checks for undefined
+# references (missing labels), so we only need to diff the resulting
+# lists in one direction, for labels that have no corresponding
+# reference. There's no need to uniq the labels, because they should
+# only be defined once anyway.
+.PHONY: check-labels
+check-labels: $(BUILDDIR)
+ sed -n 'N; /label{[^}]*}/{s/\n/ /; s/ */ /g; p;}; D;' $(PN).tex \
+ | grep -oP 'label{[^}]*?}' \
+ | sed 's/^label{//; s/}$$//' \
+ | sort \
+ > $(BUILDDIR)/labels.tmp
+ sed -n 'N; /[^h]ref{[^}]*}/{s/\n/ /; s/ */ /g; p;}; D;' $(PN).tex \
+ | grep -oP '[^h]ref{[^}]*?}' \
+ | sed 's/^[^h]ref{//; s/}$$//' \
+ | tr ',' '\n' \
+ | sort \
+ | uniq \
+ > $(BUILDDIR)/refs.tmp
+ diff $(BUILDDIR)/refs.tmp $(BUILDDIR)/labels.tmp
+
# Use SageMath to doctest any \sagelisting{}s in SAGE_LISTING_DSTS.
# The actual command is ifdef'd so that we can comment out the
# definition of SAGE_LISTING_DSTS without breaking the default
# Run a suite of checks.
.PHONY: check
-check: check-boxes check-chktex check-undefined check-sage
+check: check-boxes check-chktex check-undefined check-labels check-sage
# Clean up build artifacts.
.PHONY: clean