"""Page /doc — documentation interne (markdown rendu en HTML côté Python).""" from __future__ import annotations import os import re from pathlib import Path import markdown as md import reflex as rx from ..state import AuthState from ..sidebar import layout from ..components import scan_docs _RE_TITLE = re.compile(r"^#\s+(.+?)\s*$", re.MULTILINE) # Une seule instance de Markdown réutilisée (extensions activées). _MD = md.Markdown(extensions=["tables", "fenced_code", "attr_list", "sane_lists"]) def _render_md(text: str) -> str: _MD.reset() return _MD.convert(text) class DocState(AuthState): sections: list[dict] = [] selected_slug: str = "" selected_title: str = "" selected_html: str = "" def load_data(self): if not self.authenticated: return rx.redirect("/login") self.sections = scan_docs() if not self.sections: self.selected_slug = "" self.selected_title = "" self.selected_html = "
Aucune documentation disponible. Ajoutez des fichiers .md dans data/docs/.
Erreur de lecture : {e}
" return # Retirer le H1 (déjà affiché en titre) m = _RE_TITLE.search(text) if m: text = text[m.end():].lstrip("\n") self.selected_title = section["title"] self.selected_html = _render_md(text) # ── UI ──────────────────────────────────────────────────────────────────────── def _content() -> rx.Component: return rx.box( rx.heading(DocState.selected_title, size="6", margin_bottom="1rem"), rx.html(DocState.selected_html, class_name="doc-content"), padding="1.5rem 2rem", background_color="var(--surface)", border="1px solid var(--gray-5)", border_radius="8px", width="100%", class_name="anim-fade", ) def doc_page() -> rx.Component: return layout( rx.vstack( rx.heading("Documentation", size="7"), rx.text( "Guide d'utilisation et fonctionnement interne de l'application.", size="2", color="#666", ), _content(), spacing="3", width="100%", ) )