use strict;

open my $text, '<', 'test.txt';
$/ = $, = '['; # input record separator, output field separator
my %mapping; # existing endnote number --> number in ascendig order
my $endnote_counter = 1;

if (@ARGV && $ARGV[0] eq '--by_endnote_order') {
    while (<$text>) { # skip main text
	last if (/\@footnote:/);
    }
    while (<$text>) { # compute mapping in endnotes section
	if (/^(\d+)]/) {
	    $mapping{$1} //= $endnote_counter++;
	}
    }
}

my @endnotes;
seek($text, 0, 0); # nop if not --by_endnote_order
while (<$text>) { # re-map endnote references in main text
    if (/^(\d+)(].*)$/ms) {
	$mapping{$1} //= $endnote_counter++; # nop if --by_endnote_order
	$_ = $mapping{$1}.$2;
    }
    print;
    last if (/\@footnote:/);
}
while (<$text>) { # re-order endnotes
    chomp;
    if (/^(\d+)(].*)$/ms) {
	$_ = $mapping{$1}.$2;
    }
    $endnotes[$mapping{$1}] .= ($endnotes[$mapping{$1}] ? '[' : q()) . $_;
}
print grep {$_} @endnotes; # omit endnote references without definition
