add mermaid

This commit is contained in:
thek4n 2026-02-20 03:14:32 +03:00
parent d6a1a3e67b
commit 700fc80bc5

View File

@ -218,13 +218,29 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
Event::End(Tag::CodeBlock(_)) => {
in_code_block = false;
// Определяем отображаемое имя языка
let lang_display = current_lang.as_deref().unwrap_or("text");
// Проверка на Mermaid
let is_mermaid = current_lang.as_deref() == Some("mermaid");
// Экранируем имя языка для HTML атрибута и текста
if is_mermaid {
// Для Mermaid просто экранируем контент и оборачиваем в div
// Кнопка копирования тоже нужна
let escaped_code = escape_html(&current_code);
let mermaid_html = format!(
r#"<div class="code-block-wrapper mermaid-wrapper">
<div class="code-header">
<span class="code-lang">Mermaid Diagram</span>
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<div class="mermaid" style="background: transparent; padding: 20px; text-align: center;">{}</div>
</div>"#,
escaped_code
);
processed_events.push(Event::Html(mermaid_html.into()));
} else {
// Обычная обработка кода с подсветкой
let lang_display = current_lang.as_deref().unwrap_or("text");
let lang_escaped = escape_html(lang_display);
// Подсветка синтаксиса (построчно)
let highlighted_html = if let Some(lang) = &current_lang {
if let Some(syntax) = ss.find_syntax_by_token(lang) {
let mut h = HighlightLines::new(syntax, theme);
@ -249,8 +265,6 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
escape_html(&current_code)
};
// Формируем HTML с заголовком и кнопкой копирования
// Мы экранируем current_code еще раз для data-атрибута, хотя для копирования будем брать текст из pre
let code_container = format!(
r#"<div class="code-block-wrapper">
<div class="code-header">
@ -264,6 +278,7 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
);
processed_events.push(Event::Html(code_container.into()));
}
},
Event::Text(text) if in_code_block => {
current_code.push_str(&text);
@ -288,6 +303,8 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Markdown Preview</title>
<!-- Подключаем Mermaid JS -->
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<style>
body {{ background-color: #121212; color: #e0e0e0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 40px 20px; display: flex; justify-content: center; line-height: 1.6; }}
.content {{ max-width: 800px; width: 100%; background-color: #1e1e1e; padding: 40px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.5); }}
@ -356,6 +373,16 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
color: inherit;
}}
/* Специфичные стили для Mermaid */
.mermaid-wrapper .mermaid {{
background-color: #f9f9f9; /* Светлый фон для контраста диаграммы */
border-radius: 0 0 6px 6px;
display: flex;
justify-content: center;
}}
/* Принудительная темная тема для SVG внутри mermaid, если нужно,
но лучше использовать конфиг mermaid.init ниже */
#status {{ position: fixed; top: 10px; right: 10px; padding: 5px 10px; border-radius: 4px; font-size: 12px; font-weight: bold; }}
.connected {{ background-color: #2ecc71; color: #000; }}
.disconnected {{ background-color: #e74c3c; color: #fff; }}
@ -387,15 +414,14 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
connect();
function copyCode(button) {{
// Находим обертку, затем pre внутри неё
const wrapper = button.closest('.code-block-wrapper');
if (!wrapper) return;
const pre = wrapper.querySelector('pre');
if (!pre) return;
// Для mermaid берем текст из div.mermaid, для кода из pre
const target = wrapper.querySelector('pre') || wrapper.querySelector('.mermaid');
if (!target) return;
// Получаем текстовое содержимое (без HTML тегов подсветки)
const codeText = pre.innerText;
const codeText = target.innerText;
navigator.clipboard.writeText(codeText).then(() => {{
const originalText = button.innerText;
@ -413,6 +439,13 @@ fn markdown_to_html(markdown: &str, ss: &SyntaxSet, ts: &ThemeSet, file_path: &s
button.innerText = 'Error';
}});
}}
// Инициализация Mermaid с темной темой
mermaid.initialize({{
startOnLoad: true,
theme: 'dark',
securityLevel: 'loose',
}});
</script>
</body>
</html>"#,