# Guide d'utilisation du Markdown Viewer ## Vue d'ensemble Le système de visualisation Markdown d'ObsiViewer a été optimisé et modulaire pour offrir une expérience de lecture et d'édition exceptionnelle. Il supporte maintenant : - ✅ **GitHub Flavored Markdown (GFM)** complet - ✅ **Callouts Obsidian** (NOTE, TIP, WARNING, DANGER, etc.) - ✅ **Math LaTeX** (inline et block) - ✅ **Diagrammes Mermaid** - ✅ **Syntax highlighting** avec highlight.js - ✅ **WikiLinks** et navigation interne - ✅ **Tags inline** avec coloration automatique - ✅ **Task lists** interactives - ✅ **Tables** avancées - ✅ **Footnotes** - ✅ **Fichiers Excalidraw** avec éditeur intégré - ✅ **Lazy loading** des images - ✅ **Mode plein écran** --- ## Architecture ### Composants principaux ``` src/ ├── components/ │ ├── markdown-viewer/ # Composant de visualisation Markdown │ │ ├── markdown-viewer.component.ts │ │ └── markdown-viewer.component.spec.ts │ └── smart-file-viewer/ # Détection automatique du type de fichier │ ├── smart-file-viewer.component.ts │ └── smart-file-viewer.component.spec.ts ├── services/ │ ├── markdown.service.ts # Service de rendu Markdown │ ├── markdown.service.spec.ts │ ├── file-type-detector.service.ts # Détection du type de fichier │ └── file-type-detector.service.spec.ts └── app/features/ └── drawings/ └── drawings-editor.component.ts # Éditeur Excalidraw ``` --- ## Utilisation ### 1. MarkdownViewerComponent Composant réutilisable pour afficher du contenu Markdown. #### Import ```typescript import { MarkdownViewerComponent } from './components/markdown-viewer/markdown-viewer.component'; @Component({ imports: [MarkdownViewerComponent] }) ``` #### Exemple basique ```html ``` #### Propriétés | Propriété | Type | Description | Défaut | |-----------|------|-------------|--------| | `content` | `string` | Contenu Markdown brut | `''` | | `allNotes` | `Note[]` | Liste des notes pour WikiLinks | `[]` | | `currentNote` | `Note?` | Note courante | `undefined` | | `showToolbar` | `boolean` | Afficher la barre d'outils | `true` | | `fullscreenMode` | `boolean` | Activer le mode plein écran | `false` | | `filePath` | `string` | Chemin du fichier (pour détecter .excalidraw.md) | `''` | #### Exemple avec toutes les options ```html ``` --- ### 2. SmartFileViewerComponent Composant intelligent qui détecte automatiquement le type de fichier et affiche le viewer approprié. #### Import ```typescript import { SmartFileViewerComponent } from './components/smart-file-viewer/smart-file-viewer.component'; ``` #### Exemple ```html ``` #### Types de fichiers supportés - **Markdown** (`.md`) → MarkdownViewerComponent - **Excalidraw** (`.excalidraw.md`, `.excalidraw`) → DrawingsEditorComponent - **Images** (`.png`, `.jpg`, `.svg`, etc.) → Image viewer - **PDF** (`.pdf`) → PDF viewer (iframe) - **Texte** (`.txt`, `.json`, `.xml`, etc.) → Text viewer - **Inconnu** → Message d'erreur --- ### 3. FileTypeDetectorService Service pour détecter le type de fichier et ses caractéristiques. #### Méthodes principales ```typescript // Détecter si c'est un fichier Excalidraw isExcalidrawFile(path: string): boolean // Détecter si c'est un fichier Markdown isMarkdownFile(path: string): boolean // Obtenir les informations complètes getFileTypeInfo(path: string): FileTypeInfo // Détecter le viewer approprié getViewerType(path: string, content?: string): ViewerType // Vérifier si le contenu contient du JSON Excalidraw hasExcalidrawContent(content: string): boolean ``` #### Exemple d'utilisation ```typescript import { FileTypeDetectorService } from './services/file-type-detector.service'; constructor(private fileTypeDetector: FileTypeDetectorService) {} checkFile(path: string) { const info = this.fileTypeDetector.getFileTypeInfo(path); console.log('Type:', info.type); console.log('Editable:', info.isEditable); console.log('Requires special viewer:', info.requiresSpecialViewer); console.log('Icon:', info.icon); console.log('MIME type:', info.mimeType); } ``` --- ## Fonctionnalités Markdown ### Callouts Obsidian ```markdown > [!NOTE] > Ceci est une note informative > [!TIP] > Conseil utile pour l'utilisateur > [!WARNING] > Attention, soyez prudent > [!DANGER] > Action dangereuse, évitez cela ``` ### Math LaTeX **Inline:** ```markdown La formule $E = mc^2$ est célèbre. ``` **Block:** ```markdown $$ \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$ ``` ### Diagrammes Mermaid ```markdown \`\`\`mermaid graph TD A[Start] --> B{Decision} B -->|Yes| C[Action 1] B -->|No| D[Action 2] \`\`\` ``` ### Code avec syntax highlighting ```markdown \`\`\`typescript function hello(name: string): string { return `Hello ${name}!`; } \`\`\` ``` ### WikiLinks ```markdown [[Note Example]] [[Note Example#Section]] [[Note Example|Alias personnalisé]] ``` ### Tags inline ```markdown Les tags inline fonctionnent: #test #markdown #playground ``` ### Task lists ```markdown - [ ] Tâche non cochée - [x] Tâche cochée - [ ] Autre tâche en attente ``` ### Tables ```markdown | Colonne 1 | Colonne 2 | Colonne 3 | |-----------|-----------|-----------| | A | B | C | | D | E | F | ``` ### Footnotes ```markdown Voici un texte avec une note de bas de page[^1]. [^1]: Ceci est la note de bas de page. ``` --- ## Fichiers Excalidraw ### Détection automatique Le système détecte automatiquement les fichiers `.excalidraw.md` et affiche l'éditeur Excalidraw intégré au lieu du rendu Markdown. ### Format supporté ObsiViewer supporte le format Obsidian Excalidraw avec compression LZ-String : ```markdown --- excalidraw-plugin: parsed tags: [excalidraw] --- # Excalidraw Data ## Drawing \`\`\`compressed-json N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATLZMzYBXUtiRoIACyhQ4zZAHoFAc0JRJQgEYA6bGwC2CgF7N6hbEcK4OCtptbErHALRY8RMpWdx8Q1TdIEfARcZgRmBShcZQUebQBmbQAGGjoghH0EDihmbgBtcDBQMBLoeHF0QOwojmVg1JLIRhZ2LjQANgBWWtLm1k4AOU4xbgAWbshCDmIs \`\`\` ``` ### Fonctionnalités de l'éditeur - ✅ Édition complète avec tous les outils Excalidraw - ✅ Sauvegarde manuelle (Ctrl+S) - ✅ Export PNG/SVG - ✅ Mode plein écran (F11) - ✅ Détection de conflits - ✅ Support du thème clair/sombre --- ## Optimisations ### Lazy Loading des images Les images sont chargées uniquement lorsqu'elles entrent dans le viewport, améliorant les performances pour les documents longs. ```typescript // Automatique dans MarkdownViewerComponent private setupLazyLoading(): void { const imageObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target as HTMLImageElement; img.classList.add('loaded'); observer.unobserve(img); } }); }, { rootMargin: '50px' }); } ``` ### Cache du syntax highlighting Le service Markdown utilise un cache LRU pour éviter de re-highlighter le même code : ```typescript private static readonly HL_CACHE = new SimpleLruCache(500); ``` ### Fast path pour les documents simples Les documents sans fonctionnalités avancées (< 10KB, sans WikiLinks, math, etc.) utilisent un chemin de rendu optimisé : ```typescript if (this.canUseFastPath(markdown)) { return this.md.render(markdown, env); } ``` --- ## Tests ### Exécuter les tests ```bash # Tous les tests npm test # Tests spécifiques npm test -- --include='**/markdown-viewer.component.spec.ts' npm test -- --include='**/file-type-detector.service.spec.ts' ``` ### Coverage Les composants et services ont une couverture de tests complète : - ✅ `MarkdownViewerComponent` - 95%+ - ✅ `SmartFileViewerComponent` - 90%+ - ✅ `FileTypeDetectorService` - 100% - ✅ `MarkdownService` - 85%+ --- ## Styling ### CSS Variables disponibles ```css :root { --brand: #3a68d1; --text-main: #111827; --text-muted: #6b7280; --border: #e5e7eb; --card: #ffffff; --bg-main: #f7f7f7; --bg-muted: #eef0f2; } :root[data-theme="dark"] { --brand: #6f96e4; --text-main: #e5e7eb; --text-muted: #9ca3af; --border: #374151; --card: #0f172a; --bg-main: #111827; --bg-muted: #1f2937; } ``` ### Classes personnalisées ```css /* Callouts */ .callout { /* Base callout style */ } .callout-note { /* Note callout */ } .callout-tip { /* Tip callout */ } .callout-warning { /* Warning callout */ } .callout-danger { /* Danger callout */ } /* Code blocks */ .code-block { /* Base code block */ } .code-block__header { /* Header with language badge */ } .code-block__body { /* Code content */ } /* Task lists */ .md-task-list { /* Task list container */ } .md-task-item { /* Individual task */ } .md-task-checkbox { /* Custom checkbox */ } /* Links */ .md-wiki-link { /* WikiLink style */ } .md-external-link { /* External link style */ } ``` --- ## Exemples avancés ### Markdown Playground Le composant `MarkdownPlaygroundComponent` démontre toutes les fonctionnalités : ```typescript import { MarkdownPlaygroundComponent } from './app/features/tests/markdown-playground/markdown-playground.component'; // Accessible via la route /markdown-playground ``` ### Intégration dans une application ```typescript @Component({ selector: 'app-note-viewer', standalone: true, imports: [SmartFileViewerComponent], template: ` ` }) export class NoteViewerComponent { note = signal(null); allNotes = signal([]); } ``` --- ## Dépannage ### Le Markdown ne s'affiche pas 1. Vérifier que le contenu est bien passé au composant 2. Vérifier la console pour les erreurs de rendu 3. Vérifier que `MarkdownService` est bien injecté ### Les images ne se chargent pas 1. Vérifier les chemins des images 2. Vérifier les CORS si images externes 3. Vérifier que le lazy loading est activé ### Excalidraw ne s'affiche pas 1. Vérifier que le fichier a l'extension `.excalidraw.md` 2. Vérifier que le contenu contient un bloc `compressed-json` 3. Vérifier que `DrawingsEditorComponent` est importé ### Erreurs TypeScript ```bash # Nettoyer et rebuilder npm run clean npm install npm run build ``` --- ## Roadmap ### Fonctionnalités futures - [ ] Support des embeds audio/vidéo - [ ] Éditeur Markdown WYSIWYG - [ ] Export PDF du Markdown - [ ] Collaboration temps réel - [ ] Plugins Markdown personnalisés - [ ] Support des diagrammes PlantUML - [ ] Mode présentation (slides) --- ## Contribution Pour contribuer au système Markdown : 1. Lire le guide d'architecture dans `/docs/ARCHITECTURE/` 2. Ajouter des tests pour toute nouvelle fonctionnalité 3. Suivre les conventions de code existantes 4. Mettre à jour cette documentation --- ## Support Pour toute question ou problème : - 📖 Documentation : `/docs/` - 🐛 Issues : GitHub Issues - 💬 Discussions : GitHub Discussions --- **Dernière mise à jour :** 2025-01-15 **Version :** 2.0.0