Files
pkm/app/utils/slugs.py
2025-08-18 20:14:56 +02:00

45 lines
1.3 KiB
Python

import re
import unicodedata
def slugify(title: str, max_length: int = 80) -> str:
"""
Convert a title to a filesystem-friendly slug:
- normalize unicode to NFKD and strip accents
- lowercase
- replace non alphanum with hyphens
- collapse duplicate hyphens
- trim hyphens at edges
- limit length (keeping whole segments if possible)
"""
if not title:
return "untitled"
# Normalize accents
normalized = unicodedata.normalize("NFKD", title)
ascii_str = normalized.encode("ascii", "ignore").decode("ascii")
# Lowercase and replace non-alphanum with hyphen
slug = re.sub(r"[^a-z0-9]+", "-", ascii_str.lower()).strip("-")
if not slug:
slug = "untitled"
# Collapse multiple hyphens
slug = re.sub(r"-{2,}", "-", slug)
# Respect max length, try not to cut segments
if len(slug) > max_length:
parts = slug.split("-")
cut = []
total = 0
for p in parts:
# +1 for the hyphen when joining (except first)
add = len(p) + (1 if cut else 0)
if total + add > max_length:
break
cut.append(p)
total += add
slug = "-".join(cut) if cut else slug[:max_length].rstrip("-")
return slug