diff --git a/my-blog/static/css/style.css b/my-blog/static/css/style.css index d20ec7d..c4af2a7 100644 --- a/my-blog/static/css/style.css +++ b/my-blog/static/css/style.css @@ -479,29 +479,63 @@ body { color: #656d76; } +/* Molokai-inspired code blocks */ .article-body pre { - background: #f6f8fa; - border: 1px solid #d1d9e0; - border-radius: 6px; - padding: 16px; - overflow-x: auto; + background: #1B1D1E; + border: 1px solid #3E3D32; + border-radius: 8px; + padding: 0; + overflow: hidden; margin: 16px 0; font-size: 14px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } -.article-body code { - background: #f6f8fa; - padding: 2px 4px; - border-radius: 4px; +/* Code filename header */ +.article-body pre[data-filename]::before { + content: attr(data-filename); + display: block; + background: #272822; + color: #A6E22E; + padding: 8px 16px; + border-bottom: 1px solid #3E3D32; font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace; - font-size: 14px; + font-size: 12px; + font-weight: 500; } .article-body pre code { + display: block; background: none; - padding: 0; + padding: 16px; + color: #F8F8F2; + font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace; + overflow-x: auto; + line-height: 1.4; } +/* Inline code */ +.article-body code { + background: #2F3129; + color: #A6E22E; + padding: 2px 6px; + border-radius: 4px; + font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace; + font-size: 13px; + border: 1px solid #3E3D32; +} + +/* Molokai color scheme for syntax highlighting */ +.article-body pre code .hljs-keyword { color: #F92672; } +.article-body pre code .hljs-string { color: #E6DB74; } +.article-body pre code .hljs-comment { color: #75715E; font-style: italic; } +.article-body pre code .hljs-number { color: #AE81FF; } +.article-body pre code .hljs-variable { color: #FD971F; } +.article-body pre code .hljs-function { color: #A6E22E; } +.article-body pre code .hljs-tag { color: #F92672; } +.article-body pre code .hljs-attr { color: #A6E22E; } +.article-body pre code .hljs-value { color: #E6DB74; } + /* Sidebar styles */ .article-sidebar { position: sticky; diff --git a/src/markdown.rs b/src/markdown.rs index 7126e34..62370cd 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -92,8 +92,8 @@ impl MarkdownProcessor { for event in parser { match event { pulldown_cmark::Event::Start(pulldown_cmark::Tag::CodeBlock(kind)) => { - if let CodeBlockKind::Fenced(lang) = &kind { - code_block = Some((String::new(), lang.to_string())); + if let CodeBlockKind::Fenced(lang_info) = &kind { + code_block = Some((String::new(), lang_info.to_string())); } } pulldown_cmark::Event::Text(text) => { @@ -104,8 +104,8 @@ impl MarkdownProcessor { } } pulldown_cmark::Event::End(pulldown_cmark::TagEnd::CodeBlock) => { - if let Some((code, lang)) = code_block.take() { - let highlighted = self.highlight_code_block(&code, &lang, theme); + if let Some((code, lang_info)) = code_block.take() { + let highlighted = self.highlight_code_block(&code, &lang_info, theme); events.push(pulldown_cmark::Event::Html(highlighted.into())); } } @@ -117,13 +117,29 @@ impl MarkdownProcessor { Ok(html_output) } - fn highlight_code_block(&self, code: &str, lang: &str, theme: &syntect::highlighting::Theme) -> String { + fn highlight_code_block(&self, code: &str, lang_info: &str, theme: &syntect::highlighting::Theme) -> String { + // Parse language and filename from lang_info (e.g., "sh:/path/to/file" or "rust:main.rs") + let (lang, filename) = if lang_info.contains(':') { + let parts: Vec<&str> = lang_info.splitn(2, ':').collect(); + (parts[0], Some(parts[1])) + } else { + (lang_info, None) + }; + let syntax = self.syntax_set .find_syntax_by_token(lang) .unwrap_or_else(|| self.syntax_set.find_syntax_plain_text()); let mut highlighter = syntect::easy::HighlightLines::new(syntax, theme); - let mut output = String::from("
");
+
+ // Create pre tag with optional filename attribute
+ let pre_tag = if let Some(filename) = filename {
+ format!("", filename)
+ } else {
+ "".to_string()
+ };
+
+ let mut output = format!("{}", pre_tag);
for line in code.lines() {
let ranges = highlighter.highlight_line(line, &self.syntax_set).unwrap();