Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
24 lines
922 B
Python
24 lines
922 B
Python
"""Session language policy, independent of workspace document content."""
|
|
import re
|
|
|
|
_LANGUAGE_TAG = re.compile(
|
|
r"(?P<language>[A-Za-z]{2,8})(?:-(?P<script>[A-Za-z]{4}))?"
|
|
r"(?:-(?P<region>[A-Za-z]{2}|[0-9]{3}))?"
|
|
r"(?P<rest>(?:-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*"
|
|
r"(?:-[0-9A-WY-Za-wy-z](?:-[A-Za-z0-9]{2,8})+)*"
|
|
r"(?:-[xX](?:-[A-Za-z0-9]{1,8})+)?)"
|
|
)
|
|
|
|
|
|
def validate_language_tag(value: str) -> str:
|
|
"""Validate syntax and normalize casing without depending on UI catalogs."""
|
|
match = _LANGUAGE_TAG.fullmatch(value) if isinstance(value, str) else None
|
|
if match is None:
|
|
raise ValueError("interaction_language must be a BCP-47 language tag")
|
|
parts = [match["language"].lower()]
|
|
if match["script"]:
|
|
parts.append(match["script"].title())
|
|
if match["region"]:
|
|
parts.append(match["region"].upper())
|
|
return "-".join(parts) + match["rest"].lower()
|