﻿﻿{"id":1490,"date":"2025-11-04T10:53:36","date_gmt":"2025-11-04T09:53:36","guid":{"rendered":"https:\/\/elearningsamba.com\/index.php\/silverbullet-le-wiki-markdown-dans-lequel-vous-pouvez-tout-coder-en-lua\/"},"modified":"2025-11-04T10:53:36","modified_gmt":"2025-11-04T09:53:36","slug":"silverbullet-le-wiki-markdown-dans-lequel-vous-pouvez-tout-coder-en-lua","status":"publish","type":"page","link":"https:\/\/elearningsamba.com\/index.php\/silverbullet-le-wiki-markdown-dans-lequel-vous-pouvez-tout-coder-en-lua\/","title":{"rendered":"Silverbullet &#8211; Le wiki markdown dans lequel vous pouvez tout coder en LUA"},"content":{"rendered":"<p>En ce magnifique mardi matin, moi et mon mal de cr\u00e2ne, nous avons d\u00e9couvert un truc assez cool qui est un genre de wiki personnel en markdown, comme Obsidian ou Notion, mais avec un super pouvoir qui est que vous pouvez y \u00e9crire du code qui s\u2019ex\u00e9cute directement dans vos notes !! H\u00e9 oui, du vrai code ! Pas des plugins, pas des extensions, mais du code Lua int\u00e9gr\u00e9 dans votre texte comme si vos notes \u00e9taient devenues un environnement de dev \u00e0 part enti\u00e8re.<\/p>\n<p>\u00c7a s\u2019appelle<br \/>\n<a href=\"https:\/\/silverbullet.md\/\">SilverBullet<\/a><br \/>\n, c\u2019est open source (licence MIT), et franchement, si vous avez d\u00e9j\u00e0 bidouill\u00e9 des configs Neovim ou des scripts Redis, vous allez kiffer car c\u2019est beaucoup plus simple ^^.<\/p>\n<p>\u00c7a ressemble \u00e0 n\u2019importe quel wiki markdown moderne. Vous \u00e9crivez vos notes en local, elles sont stock\u00e9es en fichiers statiques .md, vous avez des liens bidirectionnels pour connecter vos id\u00e9es, et l\u2019interface est optimis\u00e9e avec des raccourcis clavier. C\u2019est \u00e9videmment une Progressive Web App qui fonctionne 100% hors ligne (<br \/>\n<a href=\"https:\/\/silverbullet.md\/\">comme expliqu\u00e9 sur leur site<\/a><br \/>\n), et vous gardez le contr\u00f4le total sur vos donn\u00e9es, puisque tout est auto-h\u00e9berg\u00e9 sur votre machine ou votre serveur.<\/p>\n<p>\n<img decoding=\"async\" src=\"https:\/\/korben.info\/cdn-cgi\/image\/width=1200,fit=scale-down,quality=90,f=avif\/silverbullet-wiki-markdown-lua-scripting\/silverbullet-wiki-markdown-lua-scripting-2.png\" alt=\"\" loading=\"lazy\">\n<\/p>\n<p>Ainsi, avec le scripting Lua int\u00e9gr\u00e9, vous pouvez litt\u00e9ralement taper <code>${10 + 2}<\/code> dans une note et le r\u00e9sultat s\u2019affichera en temps r\u00e9el : 12 (vous l\u2019aviez les matheux ?? ^^). Et si vous voulez une liste de vos 5 derni\u00e8res pages modifi\u00e9es qui se met \u00e0 jour automatiquement, suffit d\u2019\u00e9crire un petit bout de Lua, et hop, votre wiki devient \u201cvivant\u201d.<\/p>\n<p>Alors oui, je sais ce que vous allez me dire, Obsidian a Dataview, Logseq a ses requ\u00eates en Datalog\u2026etc donc c\u2019est pareil non ?<\/p>\n<p>Et bien pas vraiment parce que Dataview \u00e7a vous demande quand m\u00eame d\u2019apprendre un DSL (Domain Specific Language) avec une syntaxe bizarro\u00efde et de vous palucher les 50 pages de doc. Logseq quand \u00e0 lui vous balance du Datalog sans trop d\u2019explications. Alors que SilverBullet, lui, vous laisse \u00e9crire du Lua. Et le Lua, c\u2019est simple, c\u2019est dispo partout (Neovim, Redis, les addons World of Warcraft, OSB, etc.), c\u2019est document\u00e9, et c\u2019est fait pour \u00eatre embarqu\u00e9 dans des applications.<\/p>\n<p>Si vous \u00eates data scientist, vous connaissez s\u00fbrement les Jupyter Notebooks qui sont markdown avec du code Python ex\u00e9cutable dedans. H\u00e9 bien SilverBullet fait exactement la m\u00eame chose, mais pour vos notes personnelles. Vos notes ne sont plus des fichiers inertes, mais deviennent des mini-programmes qui peuvent calculer, g\u00e9n\u00e9rer du contenu, r\u00e9agir \u00e0 des \u00e9v\u00e9nements\u2026etc<\/p>\n<p>Tenez par exemple, vous pouvez d\u00e9finir une fonction custom directement dans une page :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">-- Additionner deux nombres\n<\/span><\/span><span class=\"line\"><span class=\"cl\">function adder(a, b)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> return a + b\n<\/span><\/span><span class=\"line\"><span class=\"cl\">end\n<\/span><\/span><\/code><\/pre>\n<p>Et ensuite l\u2019utiliser n\u2019importe o\u00f9 dans votre wiki avec la syntaxe <code>${adder(5, 7)}<\/code>. Vous pouvez cr\u00e9er des commandes personnalis\u00e9es qui apparaissent aussi dans la palette de commandes (Ctrl+K ou Cmd+K) :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">command.define {\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> name = \"Ins\u00e9rer signature\",\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> run = function()\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> local date = os.date(\"%Y-%m-%d\")\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> editor.insertAtCursor(\"---n\u00c9crit le \" .. date, false, true)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> end\n<\/span><\/span><span class=\"line\"><span class=\"cl\">}\n<\/span><\/span><\/code><\/pre>\n<p>Ou m\u00eame des slash commands comme dans Notion, mais que vous codez vous-m\u00eame :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">slashCommand.define {\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> name = \"todo\",\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> run = function()\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> editor.insertAtCursor(\"- [ ] |^|\", false, true)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> end\n<\/span><\/span><span class=\"line\"><span class=\"cl\">}\n<\/span><\/span><\/code><\/pre>\n<p>Tapez <code>\/todo<\/code> dans votre \u00e9diteur, et boum, \u00e7a ins\u00e8re une checkbox markdown avec le curseur au bon endroit. Vous voulez un compteur de mots qui s\u2019affiche \u00e0 chaque sauvegarde ? Un event listener comme ceci suffit :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">event.listen {\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> name = \"page:save\",\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> run = function(e)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> local content = editor.getText()\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> local word_count = select(2, content:gsub(\"%S+\", \"\"))\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> editor.flashNotification(\"Nombre de mots : \" .. word_count)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> end\n<\/span><\/span><span class=\"line\"><span class=\"cl\">}\n<\/span><\/span><\/code><\/pre>\n<p>SilverBullet est d\u00e9velopp\u00e9 en TypeScript (frontend avec Preact et CodeMirror 6) et Go (backend) et<br \/>\n<a href=\"https:\/\/github.com\/silverbulletmd\/silverbullet\">la doc officielle est disponible ici<\/a><br \/>\n.<\/p>\n<p>M\u00eame si \u00e7a fait bient\u00f4t 3 ans que c\u2019est en dev, c\u2019est encore un peu jeune et il y a d\u2019ailleurs quelques limitations \u00e0 conna\u00eetre. Par exemple, y\u2019a pas de gestion d\u2019upload d\u2019images pour l\u2019instant (vous devez linker des images externes ou les placer manuellement dans le dossier), et comme c\u2019est r\u00e9cent, l\u2019\u00e9cosyst\u00e8me de plugins n\u2019est pas aussi fourni qu\u2019Obsidian. Mais bon, quand vous pouvez coder vos propres fonctionnalit\u00e9s en Lua directement dans vos notes, la notion de \u201cplugin\u201d devient un peu inutile.<\/p>\n<p>Alors plut\u00f4t que de vous expliquer encore pendant 10 paragraphes comment \u00e7a fonctionne, voici comment l\u2019installer et tester vous-m\u00eame.<\/p>\n<p>T\u00e9l\u00e9chargez d\u2019abord le binaire qui correspond \u00e0 votre OS (macOS, Linux, Windows)<br \/>\n<a href=\"https:\/\/github.com\/silverbulletmd\/silverbullet\/releases\">en cliquant ici<\/a><br \/>\n.<\/p>\n<p>Pour <strong>macOS<\/strong> et<br \/>\n<a href=\"https:\/\/github.com\/silverbulletmd\/silverbullet\/releases\">Linux<\/a><br \/>\n, ouvrez votre terminal et tapez :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">chmod +x silverbullet\n<\/span><\/span><span class=\"line\"><span class=\"cl\">mkdir mes-notes\n<\/span><\/span><span class=\"line\"><span class=\"cl\">.\/silverbullet mes-notes\n<\/span><\/span><\/code><\/pre>\n<p>Pour <strong>Windows<\/strong>, cr\u00e9ez un dossier <code>mes-notes<\/code>, puis lancez dans PowerShell :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">.silverbullet.exe mes-notes\n<\/span><\/span><\/code><\/pre>\n<p>Le serveur d\u00e9marre alors sur le port 3000 par d\u00e9faut. Ouvrez votre navigateur sur <code>http:\/\/localhost:3000<\/code> et vous y \u00eates. Vous pouvez aussi l\u2019installer en Progressive Web App (PWA) pour l\u2019utiliser comme une vraie application desktop, m\u00eame hors ligne.<\/p>\n<p>\n<img decoding=\"async\" src=\"https:\/\/korben.info\/cdn-cgi\/image\/width=1200,fit=scale-down,quality=90,f=avif\/silverbullet-wiki-markdown-lua-scripting\/silverbullet-wiki-markdown-lua-scripting-3.png\" alt=\"\" loading=\"lazy\">\n<\/p>\n<p>Et si vous pr\u00e9f\u00e9rez Docker, c\u2019est encore plus simple :<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">docker run -p 3000:3000 -v ~\/mes-notes:\/space ghcr.io\/silverbulletmd\/silverbullet\n<\/span><\/span><\/code><\/pre>\n<p>\n<img decoding=\"async\" src=\"https:\/\/korben.info\/cdn-cgi\/image\/width=1200,fit=scale-down,quality=90,f=avif\/silverbullet-wiki-markdown-lua-scripting\/silverbullet-wiki-markdown-lua-scripting-4.png\" alt=\"\" loading=\"lazy\">\n<\/p>\n<p>\u00c7a fonctionne sur Intel et ARM (Raspberry Pi, Apple Silicon), donc vous pouvez l\u2019h\u00e9berger sur \u00e0 peu pr\u00e8s n\u2019importe quoi.<\/p>\n<p>Voil\u00e0, donc si vous voulez une note qui g\u00e9n\u00e8re automatiquement un journal de vos t\u00e2ches incompl\u00e8tes, une page d\u2019accueil qui affiche vos stats d\u2019\u00e9criture du mois ou encore un syst\u00e8me de tags auto-g\u00e9n\u00e9r\u00e9 avec des filtres dynamiques, tout est possible ! Et tout \u00e7a en \u00e9crivant du Lua directement dans le navigateur, sans plugins chelous.<\/p>\n<p>Une fois que vous aurez go\u00fbt\u00e9 \u00e0 \u00e7a, vous verrez que revenir \u00e0 des notes statiques sera tr\u00e8\u00e8\u00e8\u00e8s compliqu\u00e9.<\/p>\n<p>Merci \u00e0 friendly_0day pour m\u2019avoir fait d\u00e9couvrir<br \/>\n<a href=\"https:\/\/github.com\/silverbulletmd\/silverbullet\">SilverBullet<\/a><br \/>\n!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>En ce magnifique mardi matin, moi et mon mal de cr\u00e2ne, nous avons d\u00e9couvert un truc assez cool qui est un genre de wiki personnel en markdown, comme Obsidian ou Notion, mais avec un super pouvoir qui est que vous pouvez y \u00e9crire du code qui s\u2019ex\u00e9cute directement dans vos notes !! H\u00e9 oui, du vrai code ! Pas des plugins, pas des extensions, mais du code Lua int\u00e9gr\u00e9 dans votre texte comme si vos notes \u00e9taient devenues un environnement de dev \u00e0 part enti\u00e8re. \u00c7a s\u2019appelle SilverBullet , c\u2019est open source (licence MIT), et franchement, si vous avez d\u00e9j\u00e0 bidouill\u00e9 des configs Neovim ou des scripts Redis, vous allez kiffer car c\u2019est beaucoup plus simple ^^. \u00c7a ressemble \u00e0 n\u2019importe quel wiki markdown moderne. Vous \u00e9crivez vos notes en local, elles sont stock\u00e9es en fichiers statiques .md, vous avez des liens bidirectionnels pour connecter vos id\u00e9es, et l\u2019interface est optimis\u00e9e avec des raccourcis clavier. C\u2019est \u00e9videmment une Progressive Web App qui fonctionne 100% hors ligne ( comme expliqu\u00e9 sur leur site ), et vous gardez le contr\u00f4le total sur vos donn\u00e9es, puisque tout est auto-h\u00e9berg\u00e9 sur votre machine ou votre serveur. Ainsi, avec le scripting Lua int\u00e9gr\u00e9, vous pouvez litt\u00e9ralement taper ${10 + 2} dans une note et le r\u00e9sultat s\u2019affichera en temps r\u00e9el : 12 (vous l\u2019aviez les matheux ?? ^^). Et si vous voulez une liste de vos 5 derni\u00e8res pages modifi\u00e9es qui se met \u00e0 jour automatiquement, suffit d\u2019\u00e9crire un petit bout de Lua, et hop, votre wiki devient \u201cvivant\u201d. Alors oui, je sais ce que vous allez me dire, Obsidian a Dataview, Logseq a ses requ\u00eates en Datalog\u2026etc donc c\u2019est pareil non ? Et bien pas vraiment parce que Dataview \u00e7a vous demande quand m\u00eame d\u2019apprendre un DSL (Domain Specific Language) avec une syntaxe bizarro\u00efde et de vous palucher les 50 pages de doc. Logseq quand \u00e0 lui vous balance du Datalog sans trop d\u2019explications. Alors que SilverBullet, lui, vous laisse \u00e9crire du Lua. Et le Lua, c\u2019est simple, c\u2019est dispo partout (Neovim, Redis, les addons World of Warcraft, OSB, etc.), c\u2019est document\u00e9, et c\u2019est fait pour \u00eatre embarqu\u00e9 dans des applications. Si vous \u00eates data scientist, vous connaissez s\u00fbrement les Jupyter Notebooks qui sont markdown avec du code Python ex\u00e9cutable dedans. H\u00e9 bien SilverBullet fait exactement la m\u00eame chose, mais pour vos notes personnelles. Vos notes ne sont plus des fichiers inertes, mais deviennent des mini-programmes qui peuvent calculer, g\u00e9n\u00e9rer du contenu, r\u00e9agir \u00e0 des \u00e9v\u00e9nements\u2026etc Tenez par exemple, vous pouvez d\u00e9finir une fonction custom directement dans une page : &#8212; Additionner deux nombres function adder(a, b) return a + b end Et ensuite l\u2019utiliser n\u2019importe o\u00f9 dans votre wiki avec la syntaxe ${adder(5, 7)}. Vous pouvez cr\u00e9er des commandes personnalis\u00e9es qui apparaissent aussi dans la palette de commandes (Ctrl+K ou Cmd+K) : command.define { name = &#8220;Ins\u00e9rer signature&#8221;, run = function() local date = os.date(&#8220;%Y-%m-%d&#8221;) editor.insertAtCursor(&#8220;&#8212;n\u00c9crit le &#8221; .. date, false, true) end } Ou m\u00eame des slash commands comme dans Notion, mais que vous codez vous-m\u00eame : slashCommand.define { name = &#8220;todo&#8221;, run = function() editor.insertAtCursor(&#8220;- [ ] |^|&#8221;, false, true) end } Tapez \/todo dans votre \u00e9diteur, et boum, \u00e7a ins\u00e8re une checkbox markdown avec le curseur au bon endroit. Vous voulez un compteur de mots qui s\u2019affiche \u00e0 chaque sauvegarde ? Un event listener comme ceci suffit : event.listen { name = &#8220;page:save&#8221;, run = function(e) local content = editor.getText() local word_count = select(2, content:gsub(&#8220;%S+&#8221;, &#8220;&#8221;)) editor.flashNotification(&#8220;Nombre de mots : &#8221; .. word_count) end } SilverBullet est d\u00e9velopp\u00e9 en TypeScript (frontend avec Preact et CodeMirror 6) et Go (backend) et la doc officielle est disponible ici . M\u00eame si \u00e7a fait bient\u00f4t 3 ans que c\u2019est en dev, c\u2019est encore un peu jeune et il y a d\u2019ailleurs quelques limitations \u00e0 conna\u00eetre. Par exemple, y\u2019a pas de gestion d\u2019upload d\u2019images pour l\u2019instant (vous devez linker des images externes ou les placer manuellement dans le dossier), et comme c\u2019est r\u00e9cent, l\u2019\u00e9cosyst\u00e8me de plugins n\u2019est pas aussi fourni qu\u2019Obsidian. Mais bon, quand vous pouvez coder vos propres fonctionnalit\u00e9s en Lua directement dans vos notes, la notion de \u201cplugin\u201d devient un peu inutile. Alors plut\u00f4t que de vous expliquer encore pendant 10 paragraphes comment \u00e7a fonctionne, voici comment l\u2019installer et tester vous-m\u00eame. T\u00e9l\u00e9chargez d\u2019abord le binaire qui correspond \u00e0 votre OS (macOS, Linux, Windows) en cliquant ici . Pour macOS et Linux , ouvrez votre terminal et tapez : chmod +x silverbullet mkdir mes-notes .\/silverbullet mes-notes Pour Windows, cr\u00e9ez un dossier mes-notes, puis lancez dans PowerShell : .silverbullet.exe mes-notes Le serveur d\u00e9marre alors sur le port 3000 par d\u00e9faut. Ouvrez votre navigateur sur http:\/\/localhost:3000 et vous y \u00eates. Vous pouvez aussi l\u2019installer en Progressive Web App (PWA) pour l\u2019utiliser comme une vraie application desktop, m\u00eame hors ligne. Et si vous pr\u00e9f\u00e9rez Docker, c\u2019est encore plus simple : docker run -p 3000:3000 -v ~\/mes-notes:\/space ghcr.io\/silverbulletmd\/silverbullet \u00c7a fonctionne sur Intel et ARM (Raspberry Pi, Apple Silicon), donc vous pouvez l\u2019h\u00e9berger sur \u00e0 peu pr\u00e8s n\u2019importe quoi. Voil\u00e0, donc si vous voulez une note qui g\u00e9n\u00e8re automatiquement un journal de vos t\u00e2ches incompl\u00e8tes, une page d\u2019accueil qui affiche vos stats d\u2019\u00e9criture du mois ou encore un syst\u00e8me de tags auto-g\u00e9n\u00e9r\u00e9 avec des filtres dynamiques, tout est possible ! Et tout \u00e7a en \u00e9crivant du Lua directement dans le navigateur, sans plugins chelous. Une fois que vous aurez go\u00fbt\u00e9 \u00e0 \u00e7a, vous verrez que revenir \u00e0 des notes statiques sera tr\u00e8\u00e8\u00e8\u00e8s compliqu\u00e9. Merci \u00e0 friendly_0day pour m\u2019avoir fait d\u00e9couvrir SilverBullet !<\/p>\n","protected":false},"author":1,"featured_media":1491,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"give_campaign_id":0,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_kadence_starter_templates_imported_post":false,"footnotes":""},"class_list":["post-1490","page","type-page","status-publish","has-post-thumbnail","hentry"],"campaignId":"","_links":{"self":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages\/1490","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/comments?post=1490"}],"version-history":[{"count":0,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages\/1490\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/media\/1491"}],"wp:attachment":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/media?parent=1490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}