Almost-minimal filesystem based blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.6 KiB

  1. package App::WRT::Sort;
  2. use strict;
  3. use warnings;
  4. use 5.10.0;
  5. use Carp;
  6. use base qw(Exporter);
  7. our @EXPORT_OK = qw(sort_entries);
  8. =pod
  9. =head1 NAME
  10. App::WRT::Sort - functions for sorting wrt entry lists
  11. =head1 SYNOPSIS
  12. use App::WRT::Sort qw(sort_entries);
  13. my (@sorted) = sort_entries(@unsorted);
  14. =head1 DESCRIPTION
  15. This makes an effort to sort a list of entries, which may include both simple
  16. dates and names, or a combination thereof, reasonably.
  17. The main goal is to have dates sorted in order, followed by alphanumeric names.
  18. =head1 FUNCTIONS
  19. =over
  20. =item sort_entries(@entries)
  21. Sort a list of entries by converting them to an array with an easily sortable
  22. string format as the second value, sorting these arrayrefs by that value, and
  23. then re-mapping them to the original values.
  24. See here: L<https://en.wikipedia.org/wiki/Schwartzian_transform>
  25. =cut
  26. sub sort_entries {
  27. my (@entries) = @_;
  28. return map { $_->[0] }
  29. sort { $a->[1] cmp $b->[1] }
  30. map { [$_, sortable_from_entry($_)] }
  31. @entries;
  32. }
  33. =item sortable_from_entry($entry)
  34. Get a sortable string value that does (more or less) what we want.
  35. In this case, it pads numeric components of the path out to 5 leading 0s and
  36. leaves everything else alone.
  37. =cut
  38. sub sortable_from_entry {
  39. my ($entry) = @_;
  40. my @parts = map {
  41. my $padded;
  42. if (m/^\d+$/) {
  43. # There's a year 100k bug here, but I guess I'll cross that bridge when I
  44. # come to it:
  45. $padded = sprintf("%05d", $_);
  46. } else {
  47. $padded = $_;
  48. }
  49. $padded;
  50. } split '/', $entry;
  51. return join '', @parts;
  52. }
  53. =back
  54. =cut
  55. 1;