code layout

This commit is contained in:
2025-06-14 00:43:12 +09:00
parent 5f4382911b
commit fd223290df
2 changed files with 67 additions and 17 deletions

View File

@ -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;

View File

@ -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("<pre><code>");
// Create pre tag with optional filename attribute
let pre_tag = if let Some(filename) = filename {
format!("<pre data-filename=\"{}\">", filename)
} else {
"<pre>".to_string()
};
let mut output = format!("{}<code>", pre_tag);
for line in code.lines() {
let ranges = highlighter.highlight_line(line, &self.syntax_set).unwrap();