# /u/sy/beebe/tex/bib/find-superfluous-label-suffixes.awk, Mon Jul 26 14:35:53 1999 # Edit by Nelson H. F. Beebe # ======================================================================== # Find BibTeX citation labels that have superfluous suffix letters a, # b, ..., z, or appear with and without suffix letters, or are duplicate # when lettercase is preserved, or when lettercase is ignored. # # Usage: # gawk -f find-superfluous-label-suffixes.awk BibTeX-file(s) # # [26-Jul-1999] # ======================================================================== FILENAME != LAST_FILENAME { check(); LAST_FILENAME = FILENAME } /^@[A-RT-Za-rt-z][A-Za-z]+ *{[^ ,]*, *$/ { do_label($0) } END { check() } # ======================================================================== function check( sortpipe) { sortpipe = "sort -t: +0 -1 +1n -2 -u" check_superfluous_suffixes(sortpipe) check_suffix_consistency(sortpipe) check_duplicate_labels(sortpipe) check_duplicate_lowercase_labels(sortpipe) clear_array(DuplicateLabel) clear_array(FullLabel) clear_array(LCCount) clear_array(LCWhere) } function check_duplicate_labels(sortpipe, label) { if (count(DuplicateLabel) > 0) { print "\nDuplicate label(s)\n" for (label in DuplicateLabel) print DuplicateLabel[label] | sortpipe close(sortpipe) } } function check_duplicate_lowercase_labels(sortpipe, errors,label) { errors = 0 for (label in LCWhere) { if (LCCount[label] > 1) { if (errors == 0) print "\nDuplicate labels ignoring lettercase\n" errors++ print LCCount[label] | sortpipe } } if (errors > 0) close(sortpipe) } function check_suffix_consistency(sortpipe, errors,label,t) { errors = 0 ## for (label in FullLabel) ## print "DEBUG 0: label=[" label "]" for (label in FullLabel) { t = label gsub("[a-z]+$","",t) if (t != label) { ## print "DEBUG 1: label=[" label "] t = [" t "]" if (t in FullLabel) { ## print "DEBUG 2: label=[" label "] t = [" t "]" if (errors == 0) print "\nLabel(s) with and without suffix(es)\n" errors++ print FullLabel[label] ":" label | sortpipe print FullLabel[t] ":" t | sortpipe } } } if (errors > 0) close(sortpipe) } function check_superfluous_suffixes(sortpipe, errors,label,t) { errors = 0 for (label in FullLabel) { t = label gsub("[a-z]+$","",t) if ((t in BaseCount) && (BaseCount[t] < 2)) { if (errors == 0) print "\nLabel(s) with superfluous suffix(es)\n" errors++ print FullLabel[label] ":" label | sortpipe } } if (errors > 0) close(sortpipe) } function clear_array(array, key) { for (key in array) delete array[key] } function count(array, key,n) { n = 0 for (key in array) n++ return (n) } function do_label(label, t) { label = get_label(label) t = label gsub("[a-z]+ *$","",t) ## print "DEBUG 3: label=[" label "] t = [" t "]" if (label in FullLabel) { if (label in DuplicateLabel) DuplicateLabel[label] = DuplicateLabel[label] "\t" FILENAME ":" FNR else DuplicateLabel[label] = FILENAME ":" FNR ":" label } else FullLabel[label] = FILENAME ":" FNR if (t != label) BaseCount[t]++ label = tolower(label) LCCount[label]++ if (label in LCWhere) { if (label in LCWhere) LCWhere[label] = LCWhere[label] "\t" FILENAME ":" FNR else LCWhere[label] = FILENAME ":" FNR ":" label } } function get_label(s) { sub(/^[^{]*[{]/,"",s) sub(/ *, *$/,"",s) return (s) }