Archived
37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from functools import cache
|
|
from pathlib import Path
|
|
|
|
from .html_utils import SafeHtml, attr, trusted
|
|
|
|
_ICON_DIR = Path(__file__).parents[1] / "assets" / "lucide"
|
|
_ICON_FILES = {
|
|
"blog": "newspaper",
|
|
"business": "briefcase",
|
|
"docs": "book-open",
|
|
"github": "code",
|
|
"more": "ellipsis-vertical",
|
|
"privacy": "shield-check",
|
|
}
|
|
|
|
|
|
def _svg_icon(name: str, css_class: str = "copy-icon") -> SafeHtml:
|
|
path = _lucide_body(name)
|
|
safe_class = attr(f"lucide-icon {css_class}")
|
|
return trusted(
|
|
f'<svg class="{safe_class}" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" '
|
|
f'fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{path}</svg>'
|
|
)
|
|
|
|
|
|
@cache
|
|
def _lucide_body(name: str) -> str:
|
|
file_stem = _ICON_FILES.get(name, name)
|
|
raw = (_ICON_DIR / f"{file_stem}.svg").read_text(encoding="utf-8")
|
|
match = re.search(r"<svg\b[^>]*>(.*?)</svg>", raw, flags=re.DOTALL)
|
|
if not match:
|
|
raise ValueError(f"Invalid Lucide SVG: {file_stem}")
|
|
return re.sub(r"\s+", " ", match.group(1).strip())
|