Architecture¶
MergDown2TeX technical architecture and design.
System overview¶
graph TD
A[Obsidian] --> B[Plugin Layer]
B --> C["WASM Engine (embedded)"]
C --> E[Markdown Parser]
C --> F[LaTeX Generator]
B --> G[Compilation Layer]
G --> H[Pandoc WASM]
G --> I[Typst WASM]
G --> J["pdflatex + Podman (PC)"]
H --> K[DOCX]
I --> L[PDF]
J --> L[PDF]
Components¶
Plugin Layer¶
main.js (~3.7 MB)
├── Obsidian Plugin API
├── Settings Management
├── Command Registration
├── UI Integration
├── WASM Engine (embedded as Base64)
└── Orchestration des pipelines
!!! info "WASM embarqué"
Le moteur de conversion (Markdown → LaTeX) est un module WASM encodé en Base64 directement dans main.js. Une seule release de 2 fichiers (main.js + manifest.json) suffit donc à installer le plugin, sans binaire externe à copier.
Moteurs externes (auto-téléchargés)¶
| Binaire | Emplacement | Rôle |
|---|---|---|
pandoc.wasm (~59 MB) |
wasm/pandoc.wasm |
Conversion .tex → .docx |
typst.wasm (~28 MB) |
wasm/typst.wasm |
Conversion .typ → PDF |
mermaid.min.js (~3.5 MB) |
resources/mermaid.min.js |
Rendu Mermaid client-side |
Ces binaires sont auto-téléchargés au premier export (et via un bouton manuel dans les réglages). Ils ne font pas partie de la release.
Compilation Layer¶
Pandoc WASM
└── .tex → .docx (avec --mathml, --embed-resources, --standalone, --toc)
Typst WASM (PDF pipeline sans Podman)
└── .tex → .typ → PDF
pdflatex + Podman (PC, rendu LaTeX natif)
├── TeX Live (pdflatex, bibtex, LaTeX packages)
└── vlatex-env container
Data flow¶
Markdown → LaTeX (toujours WASM embarqué)¶
sequenceDiagram
participant U as User
participant O as Obsidian
participant W as WASM Engine (embedded)
U->>O: Convert to LaTeX
O->>W: Send markdown content
W->>W: Expand embeds (.expanded.md autonome)
W->>W: Resolve wikilinks
W->>W: Extract citations
W->>W: Convert to LaTeX
W->>O: Return .tex file
O->>U: Open .tex
PDF — pipeline Typst (par défaut mobile, PC optionnel)¶
sequenceDiagram
participant U as User
participant O as Obsidian
participant P as pandoc.wasm
participant T as typst.wasm
U->>O: Compile to PDF
O->>P: .tex content
P->>T: .typ content
T->>T: Compile Typst
T->>O: PDF bytes
O->>U: Open PDF
PDF — pipeline pdflatex + Podman (PC uniquement)¶
sequenceDiagram
participant U as User
participant O as Obsidian
participant P as Podman container
U->>O: Compile to PDF
O->>P: Send .tex file
P->>P: pdflatex x3 (+ bibtex/biber)
P->>O: Return PDF
O->>U: Open PDF
DOCX¶
sequenceDiagram
participant U as User
participant O as Obsidian
participant P as pandoc.wasm
U->>O: Compile to DOCX
O->>P: .tex content
P->>O: DOCX bytes
O->>O: Post-traitement (numérotation, flèches)
O->>U: Open DOCX
File structure¶
Plugin files (release)¶
mergdowntotex/
├── main.js ~3.7 MB ← Plugin + moteur WASM embarqué (Base64)
└── manifest.json 1.2 KB ← Obsidian metadata
!!! note "Deux emplacements identiques"
La même installation vit à deux endroits, strictement identiques (main.js, manifest.json, wasm/, resources/) :
1. Structure de la release : mergdowntotex/ (au root du dépôt).
2. Vault exemple : dans example_vault/ (dézippé), le plugin est installé à .obsidian/plugins/mergdowntotex/ et se re-déploie automatiquement à l'ouverture du vault.
Au premier lancement (créés automatiquement)¶
mergdowntotex/
├── wasm/
│ ├── pandoc.wasm ~59 MB ← auto-téléchargé (DOCX)
│ └── typst.wasm ~28 MB ← auto-téléchargé (PDF)
└── resources/
├── mermaid.min.js ← rendu Mermaid
└── csl/ ← styles de citation
Generated files¶
vault/
├── note.md ← Source note
├── note.tex ← Generated LaTeX
├── note.pdf ← Compiled PDF (Typst ou pdflatex)
├── note.docx ← Compiled DOCX (Pandoc WASM)
├── note.typ ← Typst intermediare (si "Garder le .typ")
├── note.expanded.md ← Markdown autonome étendu (dans .private/)
├── note_exp.zip ← ZIP des ressources liées
└── figures/
├── diagram_1.png ← Rendered Mermaid
└── image.png ← Copied images
WASM engine¶
embarqué dans main.js¶
Le moteur Rust est compilé en WASM puis encodé en Base64 dans main.js. À l'exécution, initWasmEmbedded() décode et instancie le module :
// extrait de main.js
initWasmEmbedded() {
const bytes = _b64toBytes(WASM_BASE64); // WASM_BASE64 = ...encoded in main.js
// → module WebAssembly, compatible "on-line"
WebAssembly.instantiate(bytes, imports);
}
En mode développement (code source non minifié), le fallback initWasm(path) utilise un fichier WASM externe :
# Build WASM
wasm-pack build --target web --out-dir pkg
# seul le binaire est ensuite encodé en Base64 dans main.js à la compilation de la release
Auto-téléchargement des moteurs¶
Lors du premier export, le plugin vérifie puis télécharge les binaires manquants :
ensurePandocWasm() → wasm/pandoc.wasm (s'il manque → downloadPandocWasm())
ensureTypstWasm() → wasm/typst.wasm (s'il manque → downloadTypstWasm())
- Déclenchés par une commande d'export ou par le bouton de téléchargement manuel des réglages
- Nécessite une connexion internet (59 MB + 28 MB)
Pipeline PDF : le choix du moteur¶
| Contexte | Pipeline utilisé |
|---|---|
| Mobile (iOS/Android) | Pandoc WASM + Typst (recommandé, aucune installation) |
PC, réglage PDF PC via Wasm+Typst désactivé |
pdflatex + Podman (vlatex-env) |
PC, réglage PDF PC via Wasm+Typst activé |
Pandoc WASM + Typst |
Le rendu LaTeX natif (pdflatex) n'est disponible que sur PC, car il repose sur un conteneur Podman/Docker.
Performance¶
Conversion speed¶
| Operation | Time |
|---|---|
| Markdown → LaTeX | 0.24s |
| GUI launch | 1s |
| PDF compilation (Typst) | ~quelques secondes |
| PDF compilation (pdflatex + Podman) | 30-60s |
Memory usage¶
| Component | Memory |
|---|---|
| WASM engine (embedded) | ~50 MB |
| pandoc.wasm / typst.wasm | ~100-200 MB chacun |
| Podman container (pdflatex) | ~500 MB |
| TeX Live | ~2 GB |
Security¶
Sandboxing¶
- WASM runs in browser sandbox
- Podman runs in container sandbox
- No direct filesystem access
Permissions¶
- Read: Vault folder
- Write: Output folder
- Execute: Podman/Docker (mode pdflatex uniquement)
Next steps¶
- Commands - Available commands
- Settings - Configuration options
- Troubleshooting - Common issues