fix: incorrect not md files render

This commit is contained in:
thek4n 2026-03-21 22:26:53 +03:00
parent 40b877a4d9
commit 29e960eec4
2 changed files with 105 additions and 1 deletions

View File

@ -10,6 +10,7 @@ use mime_guess::from_path;
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
use rand::seq::SliceRandom;
use std::convert::Infallible;
use std::ffi::OsStr;
use std::fmt::Write;
use std::net::{SocketAddr, ToSocketAddrs};
use std::path::PathBuf;
@ -30,6 +31,9 @@ use std::io;
mod markdown;
use markdown::markdown_to_html;
mod other;
use other::code_to_html;
const TEMPLATE_FILE: &str = include_str!("../templates/file.html");
const TEMPLATE_DIR: &str = include_str!("../templates/dir.html");
@ -246,7 +250,17 @@ async fn serve_file(
"/".to_string()
};
let html_content = markdown_to_html(&content, &state.syntax_set, &state.theme_set, &full_path);
let html_content = if let Some(extension) = safe_path.extension() {
if extension == OsStr::new("md") {
markdown_to_html(&content, &state.syntax_set, &state.theme_set, &full_path)
} else if let Some(ext_str) = extension.to_str() {
code_to_html(&content, ext_str, &state.syntax_set, &state.theme_set)
} else {
markdown_to_html(&content, &state.syntax_set, &state.theme_set, &full_path)
}
} else {
markdown_to_html(&content, &state.syntax_set, &state.theme_set, &full_path)
};
let filename: String = if let Some(filename) = PathBuf::from(&full_path).file_name() {
filename.to_str().unwrap_or("Markdown Preview").to_string()

90
src/other.rs Normal file
View File

@ -0,0 +1,90 @@
use syntect::easy::HighlightLines;
use syntect::highlighting::ThemeSet;
use syntect::html::{IncludeBackground, styled_line_to_highlighted_html};
use syntect::parsing::SyntaxSet;
/// Преобразует исходный код и его язык в подсвеченный HTML.
///
/// # Аргументы
/// * `code` - Исходный код как строка.
/// * `lang` - Идентификатор языка (например, "rust", "python", "mermaid").
/// * `ss` - Набор синтаксисов (SyntaxSet).
/// * `ts` - Набор тем (ThemeSet).
///
/// # Возвращает
/// Строку HTML, содержащую обертку блока кода с заголовком и кнопкой копирования.
pub fn code_to_html(code: &str, lang: &str, ss: &SyntaxSet, ts: &ThemeSet) -> String {
// Используем тему по умолчанию из вашего примера
let theme = &ts.themes["base16-ocean.dark"];
// Проверка на Mermaid диаграммы
if lang == "mermaid" {
let escaped_code = escape_html(code);
return 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;">{escaped_code}</div>
</div>"#
);
}
// Логика подсветки синтаксиса
let lang_display = if lang.is_empty() { "text" } else { lang };
let lang_escaped = escape_html(lang_display);
let highlighted_html = if !lang.is_empty() {
if let Some(syntax) = ss.find_syntax_by_token(lang) {
let mut h = HighlightLines::new(syntax, theme);
let mut result_html = String::new();
// Разбиваем код на строки для построчной подсветки
for line in code.lines() {
// Добавляем перевод строки обратно, так как highlight_line ожидает полную строку
let line_with_newline = format!("{line}\n");
match h.highlight_line(&line_with_newline, ss) {
Ok(regions) => {
// styled_line_to_highlighted_html может вернуть ошибку, если что-то пойдет не так
match styled_line_to_highlighted_html(&regions[..], IncludeBackground::No) {
Ok(html_line) => result_html.push_str(&html_line),
Err(_) => result_html.push_str(&escape_html(&line_with_newline)),
}
}
Err(_) => {
// Если ошибка подсветки, просто экранируем строку
result_html.push_str(&escape_html(&line_with_newline));
}
}
}
result_html
} else {
// Если язык не найден в наборе синтаксисов, просто экранируем весь код
escape_html(code)
}
} else {
// Если язык не указан, просто экранируем
escape_html(code)
};
// Формирование финального HTML контейнера
format!(
r#"<div class="code-block-wrapper">
<div class="code-header">
<span class="code-lang">{lang_escaped}</span>
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<pre style="margin: 0; border-radius: 0 0 6px 6px;"><code>{highlighted_html}</code></pre>
</div>"#
)
}
fn escape_html(text: &str) -> String {
text.replace('&', "&amp;")
.replace('<', "&lt;")
.replace('>', "&gt;")
.replace('"', "&quot;")
.replace('\'', "&#39;")
}