Created
September 26, 2024 14:36
-
-
Save jerrylususu/73b87819d204836e11e92070b919b4da to your computer and use it in GitHub Desktop.
Render Mermaid diagrams from selected text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Mermaid Diagram Renderer | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Render Mermaid diagrams from selected text | |
// @author Claude | |
// @match *://*/* | |
// @require https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.14.0/mermaid.min.js | |
// @grant GM_addStyle | |
// ==/UserScript== | |
//////// @match *://*/* | |
(function() { | |
'use strict'; | |
// 添加样式 | |
GM_addStyle(` | |
#mermaidRenderBtn { | |
position: fixed; | |
background-color: #4CAF50; | |
color: white; | |
padding: 5px 10px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
display: none; | |
z-index: 10000; | |
} | |
.mermaid-container { | |
position: fixed; | |
top: 10%; | |
left: 10%; | |
width: 80%; | |
height: 80%; | |
background-color: #2d3748; | |
color: white; | |
border: 1px solid #4a5568; | |
padding: 20px; | |
z-index: 10001; | |
overflow: hidden; | |
display: flex; | |
flex-direction: column; | |
} | |
.mermaid-close-btn { | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
background-color: #e53e3e; | |
color: white; | |
border: none; | |
padding: 5px 10px; | |
border-radius: 4px; | |
cursor: pointer; | |
} | |
.mermaid-content { | |
flex-grow: 1; | |
overflow: auto; | |
} | |
.mermaid-code { | |
background-color: #1a202c; | |
color: #e2e8f0; | |
padding: 10px; | |
border-radius: 4px; | |
white-space: pre-wrap; | |
} | |
.mermaid-toggle-buttons { | |
position: absolute; | |
bottom: 10px; | |
right: 10px; | |
display: flex; | |
gap: 10px; | |
} | |
.mermaid-toggle-btn { | |
background-color: #4a5568; | |
color: white; | |
border: none; | |
padding: 5px 10px; | |
border-radius: 4px; | |
cursor: pointer; | |
} | |
.mermaid-toggle-btn.active { | |
background-color: #2b6cb0; | |
} | |
`); | |
// 创建渲染按钮 | |
const renderBtn = document.createElement('button'); | |
renderBtn.id = 'mermaidRenderBtn'; | |
renderBtn.textContent = '渲染图表'; | |
document.body.appendChild(renderBtn); | |
// 检测选中的文本是否可能是Mermaid图表 | |
function isMermaidDiagram(text) { | |
const mermaidKeywords = ['graph', 'sequenceDiagram', 'classDiagram', 'stateDiagram', 'erDiagram', 'gantt', 'pie']; | |
return mermaidKeywords.some(keyword => text.trim().startsWith(keyword)); | |
} | |
// 显示渲染按钮 | |
function showRenderButton(x, y) { | |
renderBtn.style.left = `${x}px`; | |
renderBtn.style.top = `${y}px`; | |
renderBtn.style.display = 'block'; | |
} | |
// 隐藏渲染按钮 | |
function hideRenderButton() { | |
renderBtn.style.display = 'none'; | |
} | |
// 渲染Mermaid图表 | |
function renderMermaidDiagram(text) { | |
const container = document.createElement('div'); | |
container.className = 'mermaid-container'; | |
const closeBtn = document.createElement('button'); | |
closeBtn.className = 'mermaid-close-btn'; | |
closeBtn.textContent = '关闭'; | |
closeBtn.onclick = () => document.body.removeChild(container); | |
const contentDiv = document.createElement('div'); | |
contentDiv.className = 'mermaid-content'; | |
const mermaidDiv = document.createElement('div'); | |
mermaidDiv.className = 'mermaid'; | |
mermaidDiv.textContent = text; | |
const codeDiv = document.createElement('pre'); | |
codeDiv.className = 'mermaid-code'; | |
codeDiv.textContent = text; | |
codeDiv.style.display = 'none'; | |
contentDiv.appendChild(mermaidDiv); | |
contentDiv.appendChild(codeDiv); | |
const toggleButtons = document.createElement('div'); | |
toggleButtons.className = 'mermaid-toggle-buttons'; | |
const diagramBtn = document.createElement('button'); | |
diagramBtn.className = 'mermaid-toggle-btn active'; | |
diagramBtn.textContent = '图表'; | |
const codeBtn = document.createElement('button'); | |
codeBtn.className = 'mermaid-toggle-btn'; | |
codeBtn.textContent = '代码'; | |
toggleButtons.appendChild(diagramBtn); | |
toggleButtons.appendChild(codeBtn); | |
container.appendChild(closeBtn); | |
container.appendChild(contentDiv); | |
container.appendChild(toggleButtons); | |
document.body.appendChild(container); | |
// 配置 Mermaid | |
mermaid.initialize({ | |
theme: 'dark', | |
startOnLoad: false | |
}); | |
// 初始渲染 | |
mermaid.init(undefined, mermaidDiv); | |
// 切换视图 | |
diagramBtn.addEventListener('click', function() { | |
mermaidDiv.style.display = 'block'; | |
codeDiv.style.display = 'none'; | |
diagramBtn.classList.add('active'); | |
codeBtn.classList.remove('active'); | |
}); | |
codeBtn.addEventListener('click', function() { | |
mermaidDiv.style.display = 'none'; | |
codeDiv.style.display = 'block'; | |
codeBtn.classList.add('active'); | |
diagramBtn.classList.remove('active'); | |
}); | |
} | |
// 监听选中文本事件 | |
document.addEventListener('mouseup', function(e) { | |
const selection = window.getSelection().toString(); | |
if (selection && isMermaidDiagram(selection)) { | |
showRenderButton(e.pageX, e.pageY); | |
} else { | |
hideRenderButton(); | |
} | |
}); | |
// 点击渲染按钮时的操作 | |
renderBtn.addEventListener('click', function() { | |
const selection = window.getSelection().toString(); | |
if (selection && isMermaidDiagram(selection)) { | |
renderMermaidDiagram(selection); | |
} | |
hideRenderButton(); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment