--- author: malys description: MarkMap mindmap integration. name: "Library/Malys/MarkmapMindmap" tags: meta/library share.uri: "https://github.com/malys/silverbullet-libraries/blob/main/src/MarkmapMindmap.md" share.hash: 65e1843c share.mode: pull --- # Markmap mindmap This library provides a way to preview your [MarkMap](https://markmap.js.org/) mind map in a panel while you are editing your space. With MarkMap Preview, you can: - Preview your slides without leaving the context of your space - See how your slides look in real-time as you modify your markdown - Use the MarkMap Preview panel to navigate through your slides and see them in action  ## Disclaimer & Contributions This code is provided **as-is**, **without any kind of support or warranty**. I do **not** provide user support, bug-fixing on demand, or feature development. If you detect a bug, please **actively participate in debugging it** (analysis, proposed fix, or pull request) **before reporting it**. Bug reports without investigation may be ignored. 🚫 **No new features will be added.** ✅ **All types of contributions are welcome**, including bug fixes, refactoring, documentation improvements, and optimizations. By using or contributing to this project, you acknowledge and accept these conditions. ## Configuration To easily manage JS code source, we use a dynamic introspection mechanism based on md page path. If you don’t install program to default path `Library/Malys/xxx`,we have to set: ```lua config.set("markmap.source ","xxxx") -- ex: config.set("markmap.source ","Library/Malys/MarkmapMindmap") -- where xxx is the path of MarkmapMindmap md page ``` > **warning** Caution > **Depends on** [Utilities.md](https://github.com/malys/silverbullet-libraries/blob/main/src/Utilities.md). It will be installed automatically. ## Code ```space-lua local source=config.get("markmap.source") or "Library/Malys/MarkmapMindmap" local panelSize=config.get("markmap.panelSize") or 4 if library~=nil and (mls == nil or (mls ~=nil and mls.debug == nil)) then library.install("https://github.com/malys/silverbullet-libraries/blob/main/src/Utilities.md") editor.flashNotification("'Utilities' has been installed", "Info") end local function isVisible() local current_panel_id = config.get("markmap.panelPosition") or "rhs" local iframe = js.window.document.querySelector(".sb-panel."..current_panel_id..".is-expanded iframe") if iframe and iframe.contentDocument then local el = iframe.contentDocument.getElementById("mindmap") if el then return true end return false end end local function show() local page_content = editor.getText() local contentBase64=encoding.base64Encode(page_content) local content1= mls.getCodeBlock(source,"innerHTML","@CONTENT@", contentBase64) local js = mls.getCodeBlock(source,"jsInject","@CONTENT@",content1) local panel_html= mls.getCodeBlock(source,"template") local current_panel_id = config.get("markmap.panelPosition") or "rhs" editor.showPanel(current_panel_id,panelSize, panel_html, js) end local function hide() local current_panel_id = config.get("markmap.panelPosition") or "rhs" editor.hidePanel(current_panel_id) end local update = function(mode) if ((not isVisible() and mode) or (not mode and isVisible())) then show() else hide() end end -- Define the command command.define({ name = "Markmap: Toggle preview", description = "Toggle Marp slides render in a panel", run = function(e) update(true) end }) event.listen({ name = "editor:pageSaved", run = function(e) update(false) end }) ``` ## JS templates ```js jsInject const scriptId = "markmap-inject"; // Remove existing script if present const existingScript = document.getElementById(scriptId); if (existingScript) { existingScript.remove(); } // Create and inject the script again const script = document.createElement("script"); script.type = "module"; script.id = scriptId; script.textContent = `@CONTENT@`; document.documentElement.appendChild(script); ``` ```js innerHTML function b64DecodeUnicode(str) { return decodeURIComponent( atob(str) .split("") .map(c => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)) .join("") ); } import { Transformer } from "https://esm.sh/markmap-lib?bundle"; import { Markmap, deriveOptions } from "https://esm.sh/markmap-view?bundle"; import { Toolbar } from "https://esm.sh/markmap-toolbar?bundle"; const transformer = new Transformer(); const { root } = transformer.transform(b64DecodeUnicode("@CONTENT@")); const svg = document.getElementById("mindmap"); const base = deriveOptions(null) || {}; const options = { ...base, duration: 0, autoFit: false }; svg.innerHTML = ""; window.mm = Markmap.create( "svg#mindmap", options, root ); const existing = document.getElementsByClassName("mm-toolbar"); if(existing.length==0){ // 👉 Toolbar const toolbar = new Toolbar(); toolbar.attach(window.mm); const el = toolbar.render(); el.style.position = "absolute"; el.style.bottom = "20px"; el.style.right = "20px"; document.body.appendChild(el); } // 👉 print window.addEventListener("beforeprint", () => { window.mm?.fit(); }); ``` ## HTML template ```html template