BIBSORT(1) FreeBSD General Commands Manual BIBSORT(1)

bibsort
reformat bibliography

bibsort [file]

bibsort reformats on standard output the STANDARDS section of the mdoc(7) manual page file or standard input. Bibliographic references are sorted by author last names, and formatted in an item list with macro lines appearing in the order they are formatted by mandoc(1). Additionally, %N macros referencing RFC numbers are rewritten to %R macros.

:%!bibsort
December 15, 2020 FreeBSD 12.2-RELEASE-p1

bibsort.pl in git

#!/usr/bin/env perl
use strict;
use warnings;

while (<>) {
	print;
	last if /^[.]Sh STANDARDS$/;
}

my ($ref, @refs);
while (<>) {
	next if /^[.](Bl|It|$)/;
	last if /^[.]El$/;
	if (/^[.]Rs$/) {
		$ref = {};
	} elsif (/^[.]%(.) (.*)/) {
		$ref->{$1} = [] unless $ref->{$1};
		push @{$ref->{$1}}, $2;
	} elsif (/^[.]Re$/) {
		push @refs, $ref;
	} else {
		print;
	}
}

sub byLast {
	my ($af, $al) = split /\s(\S+)(,.*)?$/, $a;
	my ($bf, $bl) = split /\s(\S+)(,.*)?$/, $b;
	$al cmp $bl || $af cmp $bf;
}

foreach $ref (@refs) {
	@{$ref->{A}} = sort byLast @{$ref->{A}};
	@{$ref->{Q}} = sort @{$ref->{Q}} if $ref->{Q};
	next unless $ref->{N};
	if ($ref->{N}[0] =~ /RFC/) {
		$ref->{R} = $ref->{N};
		delete $ref->{N};
	}
}

sub byAuthor {
	local ($a, $b) = ($a->{A}[0], $b->{A}[0]);
	byLast();
}

{
	local ($,, $\) = (' ', "\n");
	print '.Bl', '-item';
	foreach $ref (sort byAuthor @refs) {
		print '.It';
		print '.Rs';
		foreach my $key (qw(A T B I J R N V U P Q C D O)) {
			next unless $ref->{$key};
			foreach (@{$ref->{$key}}) {
				print ".%${key}", $_;
			}
		}
		print '.Re';
	}
	print '.El';
}

while (<>) {
	print;
}