code layout
This commit is contained in:
@ -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;
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user