Skip to content

Instantly share code, notes, and snippets.

@oaustegard
Last active May 4, 2026 15:57
Show Gist options
  • Select an option

  • Save oaustegard/2cca636a9c2b3edbc673f4015c270279 to your computer and use it in GitHub Desktop.

Select an option

Save oaustegard/2cca636a9c2b3edbc673f4015c270279 to your computer and use it in GitHub Desktop.
bsky_limit — Bluesky 300-grapheme post limit utilities (fits, truncate). len() lies on emoji/ZWJ.
"""bsky_limit — Bluesky 300-grapheme limit. len() lies on emoji/ZWJ; use these."""
try:
import grapheme
except ImportError:
import subprocess, sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "grapheme",
"--break-system-packages", "--quiet"])
import grapheme
BSKY_LIMIT = 300
def fits(text: str, limit: int = BSKY_LIMIT) -> bool:
return grapheme.length(text) <= limit
def truncate(text: str, limit: int = BSKY_LIMIT, suffix: str = "…") -> str:
"""Truncate to fit `limit` graphemes, walking back to last whitespace if possible."""
if grapheme.length(text) <= limit:
return text
head = grapheme.slice(text, 0, limit - grapheme.length(suffix))
stripped = head.rstrip()
last_space = max(stripped.rfind(" "), stripped.rfind("\n"), stripped.rfind("\t"))
if last_space > 0:
head = stripped[:last_space].rstrip()
return head + suffix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment