]> gitweb.michael.orlitzky.com - mjotex.git/commitdiff
GNUmakefile.mjo: add check-labels target to find unused labels
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 17 May 2026 23:40:39 +0000 (19:40 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 17 May 2026 23:40:39 +0000 (19:40 -0400)
It's a wild heuristic, but it works better than anything else I've
tried so far.

GNUmakefile.mjo

index 3aaf3237c86d3be096246c518f5b971e11502892..5ea1c4fcc04b6268495dc414bb082f7ed19ca77a 100644 (file)
@@ -223,6 +223,44 @@ check-chktex:
 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
@@ -236,7 +274,7 @@ endif
 
 # 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