✨ Add SortBlocksMiddleware for custom block sorting#525
Merged
Conversation
Adds a generic block-sorting middleware taking a sort-key function (as the `key` argument of Python's built-in `sorted`), allowing users to sort blocks by arbitrary criteria, e.g. by field values such as year. The comment-preservation logic is moved from SortBlocksByTypeAndKeyMiddleware into the new class; SortBlocksByTypeAndKeyMiddleware is now a thin subclass of it (fully backwards compatible, existing tests unchanged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
reviewed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #480 (see also #478, where this need came up).
What this does
Adds a generic
SortBlocksMiddlewarethat sorts the blocks of a library by a user-provided sort-key function, working like thekeyargument of Python's built-insorted:reverse=Trueandpreserve_comments_on_topare supported; comment-preservation reuses the existing_BlockJunkgrouping, so custom sorts keep comments attached to their entry for free.Design deviation from the issue body
#480 proposed an abstract class with an unimplemented
compare(block1, block2) -> int. Following the later discussion in the issue (thanks @mirhahn), this PR implements a key-function API instead:key=is the native Python 3 sorting idiom (cmpwas removed fromlist.sortin Python 3); writing a correct, transitive comparator is harder thanlambda e: (e[year], e.key).functools.cmp_to_key(documented in the class docstring); there is no conversion in the other direction.SortBlocksByTypeAndKeyMiddleware, both field-sorting middlewares) already sort via key functions internally — a comparator-based abstract class would have required converting working key functions into comparators.Also, the class is concrete (key passed as constructor argument, mirroring
SortFieldsCustomMiddleware) rather than abstract, so one-off sorts need no subclass; subclassing for reusable named middlewares still works.Backwards compatibility
SortBlocksByTypeAndKeyMiddlewareis now a thin subclass ofSortBlocksMiddlewaresupplying its(type_index, block.key)tuple key. Behavior is unchanged; the pre-existing tests pass unmodified.Review aid
The new unit tests each parse a small literal BibTeX string and assert the resulting order, so the functionality is directly visible: sort by year, reverse, hierarchical
(year, author)keys, sort stability, mixed block types, and both comment-handling modes. Docs (customize.rst) gained an MWE under the Sorting section plus a note pointing custom-sorting users to the new class.🤖 Generated with Claude Code