From fad76fa36e07106415e4aab34e4167b75101cf43 Mon Sep 17 00:00:00 2001 From: Saifeddine ALOUI Date: Fri, 13 Sep 2024 12:41:34 +0200 Subject: [PATCH] Update lollms_markdown_renderer.js --- .../libraries/lollms_markdown_renderer.js | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/endpoints/libraries/lollms_markdown_renderer.js b/endpoints/libraries/lollms_markdown_renderer.js index 105fba3c..32274bbd 100644 --- a/endpoints/libraries/lollms_markdown_renderer.js +++ b/endpoints/libraries/lollms_markdown_renderer.js @@ -33,6 +33,9 @@ // // // +// +// +// // Don't forget to get the css too // Make sure there is a global variable called mr that instanciate MarkdownRenderer @@ -94,6 +97,117 @@ class MarkdownRenderer { return text; } + async renderGraphvizDiagrams(text) { + // Check if viz.js is loaded + if (typeof Viz === 'undefined') { + console.warn('Viz.js is not loaded. Graphviz diagrams will not be rendered.'); + return text; + } + + const graphvizCodeRegex = /```graphviz\n([\s\S]*?)```/g; + const matches = text.match(graphvizCodeRegex); + + if (!matches) return text; + + for (const match of matches) { + const graphvizCode = match.replace(/```graphviz\n/, '').replace(/```$/, ''); + const uniqueId = 'graphviz-' + Math.random().toString(36).substr(2, 9); + + try { + const viz = new Viz(); + const result = await viz.renderSVGElement(graphvizCode); + const svgString = new XMLSerializer().serializeToString(result); + + const htmlCode = ` +
+
+
+ ${svgString} +
+
+
+ + + + +
+
+ `; + text = text.replace(match, htmlCode); + } catch (error) { + console.error('Graphviz rendering failed:', error); + text = text.replace(match, ``); + } + } + + return text; + } + + // Helper object for Graphviz operations + gv = { + zoomGraphviz: function(id, factor) { + const element = document.getElementById(id); + if (element) { + const currentScale = element.style.transform ? parseFloat(element.style.transform.replace('scale(', '').replace(')', '')) : 1; + const newScale = currentScale * factor; + element.style.transform = `scale(${newScale})`; + } + }, + + saveGraphvizAsPNG: function(id) { + const svg = document.getElementById(id).querySelector('svg'); + if (svg) { + const svgData = new XMLSerializer().serializeToString(svg); + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + const img = new Image(); + img.onload = function() { + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage(img, 0, 0); + const pngUrl = canvas.toDataURL('image/png'); + const link = document.createElement('a'); + link.href = pngUrl; + link.download = 'graphviz_diagram.png'; + link.click(); + }; + img.src = 'data:image/svg+xml;base64,' + btoa(svgData); + } + }, + + saveGraphvizAsSVG: function(id) { + const svg = document.getElementById(id).querySelector('svg'); + if (svg) { + const svgData = new XMLSerializer().serializeToString(svg); + const blob = new Blob([svgData], {type: 'image/svg+xml;charset=utf-8'}); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = 'graphviz_diagram.svg'; + link.click(); + URL.revokeObjectURL(url); + } + } + }; + + async renderSVG(text) { const svgCodeRegex = /```svg\n([\s\S]*?)```/g; const matches = text.match(svgCodeRegex); @@ -422,6 +536,9 @@ class MarkdownRenderer { // Handle Mermaid graphs first text = await this.renderMermaidDiagrams(text); + text = await this.renderGraphvizDiagrams(text); + + // Handle code blocks with syntax highlighting and copy button text = await this.renderCodeBlocks(text);