mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Repris d'AJEAN (d6136caa, #123) : script, feuille de style, polices woff2 et licence MIT sous internal/loki/ui/katex/, embarqués par le go:embed et par build.rs de la façade. Pas de CDN : l'interface doit marcher hors ligne. Route /katex/ des deux côtés avec les mêmes en-têtes : katex.min.js (application/javascript), katex.min.css (text/css), fonts/*.woff2 (font/woff2), Cache-Control public 1 jour ; script et feuille compressés en gzip, polices non. Contrairement à AJEAN (http.FileServer), le Go (web_katex.go) ne sert que ces fichiers, avec un Content-Type fixe : ni index de dossier, ni type décidé par le registre MIME de l'OS. La façade (ui.rs) rend les mêmes réponses ; le reste de /katex/ part au Go (404). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package loki
|
|
|
|
import (
|
|
"net/http"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// web_katex.go — KaTeX 0.16.11 (formules LaTeX des réponses), repris d'AJEAN.
|
|
//
|
|
// Embarqué sous ui/katex/ et servi sous /katex/ : l'UI ne le charge qu'à la
|
|
// première formule d'une réponse (00-md.js), et il doit marcher hors ligne,
|
|
// sans appeler un CDN. Seuls le script, la feuille de style et les polices
|
|
// woff2 sont servis — pas d'index de dossier — avec un Content-Type fixe : le
|
|
// registre MIME de l'OS (Windows notamment) ne doit pas le décider, et la
|
|
// façade Rust (rust/loki-rs/src/ui.rs) rend exactement les mêmes en-têtes.
|
|
|
|
// katexTypes : extensions servies et leur Content-Type.
|
|
var katexTypes = map[string]string{
|
|
".js": "application/javascript",
|
|
".css": "text/css; charset=utf-8",
|
|
".woff2": "font/woff2",
|
|
}
|
|
|
|
// katexFile : chemin relatif à ui/katex/ d'une ressource servable, ou "" si la
|
|
// demande n'en est pas une (racine, dossier, autre extension, remontée).
|
|
func katexFile(urlPath string) (rel, ctype string) {
|
|
rel = strings.TrimPrefix(urlPath, "/katex/")
|
|
if rel == urlPath || rel == "" || strings.Contains(rel, "..") || path.Clean(rel) != rel {
|
|
return "", ""
|
|
}
|
|
ctype, ok := katexTypes[path.Ext(rel)]
|
|
if !ok {
|
|
return "", ""
|
|
}
|
|
return rel, ctype
|
|
}
|
|
|
|
func handleKatex(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet && r.Method != http.MethodHead {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
rel, ctype := katexFile(r.URL.Path)
|
|
if rel == "" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
b, err := uiFS.ReadFile("ui/katex/" + rel)
|
|
if err != nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", ctype)
|
|
w.Header().Set("Cache-Control", "public, max-age=86400")
|
|
w.Header().Set("Content-Length", strconv.Itoa(len(b)))
|
|
w.Write(b)
|
|
}
|