Coding 2024-09-21

By Max Woerner Chase

Breaking things down now, very carefully:

There are, fundamentally, three different cases to consider:

For a given block, the unmodified selectors should go before the modified ones, and the descendant tags can go anywhere because they have the highest specificity.

As such, let's try harmonizing ordering with how SCSS or suchlike would do it.

My inclination right now is to do this with a partial ordering where only selectors with the same base block are comparable. To deal with the incompatible orderings, we need to sort them into an unordered collection of ordered bins, or rather, maps where we sort the keys before iterating. Regardless, they must be sorted by base type.

:)

You're bringing back dependent mappings again, aren't you?

To be fair, there's only any actual code there if I bother trying to make it pass type checking.

Anyway, to get ordering working, I could try to coordinate stuff across multiple classes, or I could punt on that and just come up with some slightly strange ordering logic:

@attrs.frozen
class Selector[B]:
    block: B  # Require length of zero or one
    element: Element[B] | None  # Require length of zero or one

    # Define an ordering thus:
    # 0, None (bucket 0)
    # 1, None
    # 1, A0 (bucket 1)
    # 1, A1
    # 1, B0
    # 1, B1
    # 0, A0 (bucket 2)
    # 0, A1
    # 0, B0
    # 0, B1

It's a little funky that the block part has this alternation in the sort order, but I think it makes things work out aesthetically. Sorting happens first by bucket, and within buckets, sorts by tag name.

...

Okay, I did all of that, and maybe a few other things besides. I need to get away from this for a bit, rest and let the dust settle, before I work out if anything I just did actually made sense.

Good night.