soapbox/soapbox/slug.py
Ole-Morten Duesund 1218c5d650 Unicode i slugs: «Grønt er skjønt» → grønt-er-skjønt
Bokstaver og tall i alle skriftsystemer beholdes, alt annet blir
bindestrek. NFC-normalisering gir samme slug uansett om ø/å kommer
prekomponert eller som base + kombinerende tegn (macOS). URL-er i
feed.xml percent-encodes siden RSS-lesere krever ASCII.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcEy43fNYpwg6K6oTKakWR
2026-08-26 14:02:07 +02:00

32 lines
999 B
Python

"""Lager URL-vennlige slugs fra titler.
Unicode-bokstaver beholdes ("Grønt er skjønt""grønt-er-skjønt"); moderne
nettlesere og servere håndterer UTF-8 i stier, og det gir penere og mer
lesbare adresser enn translitterering. Teksten NFC-normaliseres slik at
f.eks. «ø» skrevet som base + kombinerende tegn (vanlig fra macOS) gir samme
slug som det prekomponerte tegnet.
"""
from __future__ import annotations
import re
import unicodedata
# Alt som ikke er bokstav eller tall (i alle skriftsystemer) blir skilletegn.
_SEP = re.compile(r"[^\w]+|_+", re.UNICODE)
def slugify(text: str) -> str:
text = unicodedata.normalize("NFC", text).casefold()
text = _SEP.sub("-", text).strip("-")
return text or "post"
def unique_slug(base: str, taken: set[str]) -> str:
"""Returnerer ``base`` eller ``base-2``, ``base-3`` … til den er ledig."""
if base not in taken:
return base
n = 2
while f"{base}-{n}" in taken:
n += 1
return f"{base}-{n}"