Polices libres Noto Sans / Noto Sans Mono, vérifiées et installées par l'assistant
Segoe UI et Consolas (polices Microsoft, non redistribuables) provoquaient des avertissements Typst sous Linux et macOS. Le gabarit utilise désormais Noto Sans et Noto Sans Mono. L'assistant vérifie leur présence (quarto typst fonts) et sinon les installe : paquets système sous Linux, ou téléchargement depuis le dépôt officiel Noto dans le dossier de polices de l'utilisateur (Windows, macOS, et secours Linux). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5b312f7459
commit
503aa66dc0
+80
-3
@@ -159,7 +159,7 @@ def installer_quarto_arch():
|
||||
|
||||
|
||||
def verifier_quarto():
|
||||
titre("1/3 Quarto (outil de mise en page)")
|
||||
titre("1/4 Quarto (outil de mise en page)")
|
||||
quarto = trouver_quarto()
|
||||
if quarto:
|
||||
print(f" Quarto est installé : {quarto}")
|
||||
@@ -179,6 +179,82 @@ def verifier_quarto():
|
||||
return quarto
|
||||
|
||||
|
||||
# --- Polices -----------------------------------------------------------------------
|
||||
|
||||
DEPOT_NOTO = "https://github.com/notofonts/notofonts.github.io/raw/main/fonts"
|
||||
POLICES = { # famille attendue par _quarto.yml -> fichiers à installer si elle manque
|
||||
"Noto Sans": [f"NotoSans/hinted/ttf/NotoSans-{s}.ttf" for s in
|
||||
("Regular", "Italic", "SemiBold", "SemiBoldItalic", "Bold", "BoldItalic")],
|
||||
"Noto Sans Mono": [f"NotoSansMono/hinted/ttf/NotoSansMono-{s}.ttf" for s in ("Regular", "Bold")],
|
||||
}
|
||||
PAQUETS_POLICES = { # gestionnaire Linux -> commande d'installation des deux familles
|
||||
"apt-get": ["sudo", "apt-get", "install", "-y", "fonts-noto-core", "fonts-noto-mono"],
|
||||
"pacman": ["sudo", "pacman", "-S", "--needed", "noto-fonts"],
|
||||
"dnf": ["sudo", "dnf", "install", "-y", "google-noto-sans-fonts", "google-noto-sans-mono-fonts"],
|
||||
"zypper": ["sudo", "zypper", "install", "-y", "noto-sans-fonts", "noto-sans-mono-fonts"],
|
||||
}
|
||||
|
||||
|
||||
def polices_manquantes(quarto):
|
||||
"""Familles absentes, d'après la liste des polices réellement visibles par Typst."""
|
||||
resultat = subprocess.run([quarto, "typst", "fonts"], capture_output=True, text=True,
|
||||
encoding="utf-8", errors="replace")
|
||||
sortie = resultat.stdout + resultat.stderr # Quarto écrit la liste sur la sortie d'erreur
|
||||
familles = {ligne.strip() for ligne in sortie.splitlines()}
|
||||
return [f for f in POLICES if f not in familles]
|
||||
|
||||
|
||||
def dossier_polices_utilisateur():
|
||||
if SYSTEME == "Windows":
|
||||
return Path(os.environ["LOCALAPPDATA"]) / "Microsoft/Windows/Fonts"
|
||||
if SYSTEME == "Darwin":
|
||||
return Path.home() / "Library/Fonts"
|
||||
return Path.home() / ".local/share/fonts"
|
||||
|
||||
|
||||
def telecharger_polices(familles):
|
||||
"""Installe les polices pour l'utilisateur courant (aucun droit administrateur nécessaire)."""
|
||||
dossier = dossier_polices_utilisateur()
|
||||
dossier.mkdir(parents=True, exist_ok=True)
|
||||
for famille in familles:
|
||||
for chemin in POLICES[famille]:
|
||||
cible = dossier / Path(chemin).name
|
||||
print(f" Téléchargement de {cible.name}...")
|
||||
urllib.request.urlretrieve(f"{DEPOT_NOTO}/{chemin}", cible)
|
||||
if SYSTEME == "Windows": # déclarer la police pour l'utilisateur (comme « Installer » dans l'Explorateur)
|
||||
import winreg
|
||||
with winreg.OpenKey(winreg.HKEY_CURRENT_USER,
|
||||
r"Software\Microsoft\Windows NT\CurrentVersion\Fonts", 0,
|
||||
winreg.KEY_SET_VALUE) as cle:
|
||||
winreg.SetValueEx(cle, f"{cible.stem} (TrueType)", 0, winreg.REG_SZ, str(cible))
|
||||
if SYSTEME == "Linux" and shutil.which("fc-cache"):
|
||||
subprocess.run(["fc-cache", "-f", str(dossier)], stdout=subprocess.DEVNULL)
|
||||
|
||||
|
||||
def verifier_polices(quarto):
|
||||
titre("2/4 Polices (Noto Sans et Noto Sans Mono)")
|
||||
manquantes = polices_manquantes(quarto)
|
||||
if not manquantes:
|
||||
print(" Les polices sont installées.")
|
||||
return
|
||||
print(f" Polices manquantes : {', '.join(manquantes)}.")
|
||||
print(" Sans elles, les documents seraient produits avec une police de remplacement.")
|
||||
if not oui_non(" Les installer maintenant ?"):
|
||||
return
|
||||
gestionnaire = next((g for g in PAQUETS_POLICES if SYSTEME == "Linux" and shutil.which(g)), None)
|
||||
try:
|
||||
if gestionnaire:
|
||||
print(" Votre mot de passe peut être demandé (installation système).")
|
||||
subprocess.run(PAQUETS_POLICES[gestionnaire])
|
||||
if not gestionnaire or polices_manquantes(quarto):
|
||||
telecharger_polices(polices_manquantes(quarto))
|
||||
except Exception as erreur:
|
||||
print(f" L'installation des polices a échoué : {erreur}")
|
||||
reste = polices_manquantes(quarto)
|
||||
print(" Polices installées." if not reste else
|
||||
f" Toujours introuvables : {', '.join(reste)} (les documents seront produits quand même).")
|
||||
|
||||
|
||||
# --- Environnement Python des schémas ----------------------------------------------
|
||||
|
||||
def python_du_venv():
|
||||
@@ -186,7 +262,7 @@ def python_du_venv():
|
||||
|
||||
|
||||
def preparer_venv():
|
||||
titre("2/3 Environnement Python (schémas)")
|
||||
titre("3/4 Environnement Python (schémas)")
|
||||
empreinte = hashlib.sha256(EXIGENCES.read_bytes()).hexdigest()
|
||||
temoin = VENV / ".empreinte-requirements"
|
||||
if python_du_venv().exists() and temoin.exists() and temoin.read_text().strip() == empreinte:
|
||||
@@ -231,7 +307,7 @@ def ouvrir_dossier(dossier):
|
||||
|
||||
|
||||
def generer(quarto, venv_ok):
|
||||
titre("3/3 Génération des documents")
|
||||
titre("4/4 Génération des documents")
|
||||
i_format = choisir("Quel format ?", [f[0] for f in FORMATS])
|
||||
libelle, cible, extension = FORMATS[i_format]
|
||||
supports = lister_supports()
|
||||
@@ -268,6 +344,7 @@ def main():
|
||||
print("Python 3.9 ou plus récent est nécessaire.")
|
||||
raise SystemExit(1)
|
||||
quarto = verifier_quarto()
|
||||
verifier_polices(quarto)
|
||||
venv_ok = preparer_venv()
|
||||
while True:
|
||||
generer(quarto, venv_ok)
|
||||
|
||||
Reference in New Issue
Block a user