home · contact · privacy
For sorting sets by ID, pad to equal widths its ":"/"."-separated parts. master
authorPlom Heller <plom@plomlompom.com>
Sun, 4 Oct 2026 22:24:12 +0000 (00:24 +0200)
committerPlom Heller <plom@plomlompom.com>
Sun, 4 Oct 2026 22:24:12 +0000 (00:24 +0200)
src/bricksplom/misc.py

index 5d8779453a1ceeb4ebdc7d824223dec36329cb51..c08d0e902b83e3a1e6bc765acbf1ad1824c026f9 100644 (file)
@@ -26,6 +26,7 @@ _CHAR_COLL_SEP_COLUMN = '-'
 _CHAR_COLL_SEP_PAGE = '='
 _CHAR_COL_SOLID = '+'
 _CHAR_COL_TRANSPARENT = '-'
+_CHARS_COLL_SEP_ID_TOKS = (':', '.')
 _BOX_PREFIX = 'box:'
 
 ARG_QMARK = '?'
@@ -758,6 +759,39 @@ class _BrickSet(_Textfiled, _Lookupable):
                     lambda item: item.show(to_boxes=True))
                 }
 
+    @classmethod
+    def sorters(
+            cls
+            ) -> dict[str, tuple[str, Callable[['BricksDb', tuple[Self, ...]],
+                                               tuple[Self, ...]]]]:
+        def by_structured_id(
+                _: BricksDb,
+                pre_sorted: tuple[Self, ...]
+                ) -> tuple[Self, ...]:
+            ids_to_items = {item.id_: item for item in pre_sorted}
+            ids_to_splits = {}
+            widths = [0]
+            for id_ in ids_to_items:
+                toks = ['']
+                for c in id_:
+                    toks[-1] = toks[-1] + c
+                    if c in _CHARS_COLL_SEP_ID_TOKS:
+                        toks += ['']
+                ids_to_splits[id_] = toks
+                for idx, width in enumerate([len(tok) for tok in toks]):
+                    widths[idx:idx+1] = [max(width, widths[idx])
+                                         if len(widths) > idx else width]
+            ids_padded_to_items = {}
+            for id_, toks in ids_to_splits.items():
+                id_padded = ''
+                for idx, tok in enumerate(toks):
+                    id_padded = id_padded + ' '*(widths[idx] - len(tok)) + tok
+                ids_padded_to_items[id_padded] = ids_to_items[id_]
+            return tuple(ids_padded_to_items[id_padded]
+                         for id_padded in sorted(ids_padded_to_items))
+        return super().sorters() | {TOK_ID: ('by ID tokens',
+                                             by_structured_id)}
+
 
 class _Box(_Lookupable):
     'Order of designs.'