Skip to content

Instantly share code, notes, and snippets.

@jerrylususu
Created September 26, 2024 14:36
Show Gist options
  • Save jerrylususu/73b87819d204836e11e92070b919b4da to your computer and use it in GitHub Desktop.
Save jerrylususu/73b87819d204836e11e92070b919b4da to your computer and use it in GitHub Desktop.
Render Mermaid diagrams from selected text
// ==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