fix: incorrect not md files render
This commit is contained in:
parent
40b877a4d9
commit
29e960eec4
16
src/main.rs
16
src/main.rs
@ -10,6 +10,7 @@ use mime_guess::from_path;
|
|||||||
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
use std::ffi::OsStr;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::net::{SocketAddr, ToSocketAddrs};
|
use std::net::{SocketAddr, ToSocketAddrs};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -30,6 +31,9 @@ use std::io;
|
|||||||
mod markdown;
|
mod markdown;
|
||||||
use markdown::markdown_to_html;
|
use markdown::markdown_to_html;
|
||||||
|
|
||||||
|
mod other;
|
||||||
|
use other::code_to_html;
|
||||||
|
|
||||||
const TEMPLATE_FILE: &str = include_str!("../templates/file.html");
|
const TEMPLATE_FILE: &str = include_str!("../templates/file.html");
|
||||||
const TEMPLATE_DIR: &str = include_str!("../templates/dir.html");
|
const TEMPLATE_DIR: &str = include_str!("../templates/dir.html");
|
||||||
|
|
||||||
@ -246,7 +250,17 @@ async fn serve_file(
|
|||||||
"/".to_string()
|
"/".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() {
|
let filename: String = if let Some(filename) = PathBuf::from(&full_path).file_name() {
|
||||||
filename.to_str().unwrap_or("Markdown Preview").to_string()
|
filename.to_str().unwrap_or("Markdown Preview").to_string()
|
||||||
|
|||||||
90
src/other.rs
Normal file
90
src/other.rs
Normal 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(®ions[..], 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('&', "&")
|
||||||
|
.replace('<', "<")
|
||||||
|
.replace('>', ">")
|
||||||
|
.replace('"', """)
|
||||||
|
.replace('\'', "'")
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user