aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/grammar/markdown.pest30
-rw-r--r--code/src/markdown/mod.rs27
2 files changed, 43 insertions, 14 deletions
diff --git a/code/grammar/markdown.pest b/code/grammar/markdown.pest
index ebdfcd7..e387182 100644
--- a/code/grammar/markdown.pest
+++ b/code/grammar/markdown.pest
@@ -1,17 +1,27 @@
+// WHITESPACE = _{ " " | "\t" | NEWLINE }
-file = _{ SOI ~ block* ~ EOI }
+file = _{ SOI ~ NEWLINE* ~ (block ~ NEWLINE*)* ~ EOI }
-block = { (code_block | header | list | paragraph | "") ~ NEWLINE }
+block = { code_block | latex_block | header | unordered_list | ordered_list | paragraph }
header = { "#"+ ~ span }
- list = { list_item+ }
- list_item = { "-" ~ span }
+ unordered_list = { unordered_list_item+ }
+ unordered_list_item = { "-" ~ span ~ NEWLINE }
+ ordered_list = { ordered_list_item+ }
+ ordered_list_item = { ASCII_DIGIT+ ~ "." ~ span ~ NEWLINE }
paragraph = { span }
- code_block = { "```" ~ (!"```" ~ ANY) ~ "```" }
+ code_block = { "```" ~ code_block_lang ~ NEWLINE ~ code_block_inner ~ "```" }
+ code_block_lang = { ASCII_ALPHANUMERIC* }
+ code_block_inner = { (!"```" ~ ANY)* }
+ latex_block = { "$$" ~ latex_block_inner ~ "$$" }
+ latex_block_inner = { (!"$$" ~ ANY)* }
-span = { (style_bold | style_italic | style_code | text)+ }
+span = { (style_bold | style_italic | style_code | inline_latex | text)+ }
style_bold = { "**" ~ text ~ "**" }
style_italic = { "_" ~ text ~ "_" }
- style_code = { "`" ~ text ~ "`" }
- text = { (!(NEWLINE | "*" | "_" | "`") ~ ANY)+ }
-
-
+ style_code = { "`" ~ code_inner ~ "`" }
+ code_inner = { (!"`" ~ ANY)+ }
+ inline_latex = { "$" ~ latex_inner ~ "$" }
+ latex_inner = { (!"$" ~ ANY)+ }
+
+ text = { (!("\n" ~ forbidden_span_wrap | "*" | "_" | "`" | "$") ~ ANY)+ }
+ forbidden_span_wrap = _{ "\n" | "-" | ASCII_DIGIT+ ~ "." }
diff --git a/code/src/markdown/mod.rs b/code/src/markdown/mod.rs
index b6dfb55..dee923c 100644
--- a/code/src/markdown/mod.rs
+++ b/code/src/markdown/mod.rs
@@ -4,7 +4,7 @@ use pest::{
};
use pest_derive::Parser;
-use crate::html::escape;
+use crate::{html::escape, syntax_highlight::syntax_highlight};
#[derive(Parser)]
#[grammar = "grammar/markdown.pest"]
@@ -29,11 +29,30 @@ pub fn render_ast(p: Pair<Rule>) -> String {
Rule::block => render_pairs(p.into_inner()),
Rule::header => format!("<h1>{}</h1>", render_pairs(p.into_inner())),
Rule::paragraph => format!("<p>{}</p>", render_pairs(p.into_inner())),
- Rule::list => format!("<ul>{}</ul>", render_pairs(p.into_inner())),
- Rule::list_item => format!("<li>{}</li>", render_pairs(p.into_inner())),
+ Rule::unordered_list => format!("<ul>{}</ul>", render_pairs(p.into_inner())),
+ Rule::ordered_list => format!("<ol>{}</ol>", render_pairs(p.into_inner())),
+ Rule::unordered_list_item | Rule::ordered_list_item => {
+ format!("<li>{}</li>", render_pairs(p.into_inner()))
+ }
+ Rule::style_italic => format!("<i>{}</i>", render_pairs(p.into_inner())),
+ Rule::style_bold => format!("<b>{}</b>", render_pairs(p.into_inner())),
+ Rule::style_code => format!("<code>{}</code>", p.into_inner().next().unwrap().as_str()),
Rule::span => render_pairs(p.into_inner()),
- Rule::text => escape(p.as_str()),
Rule::EOI => "".to_string(),
+ Rule::code_block => {
+ let k = p.into_inner().collect::<Vec<_>>();
+ let lang = k[0].as_str();
+ let inner = k[1].as_str();
+ format!(
+ "<pre>{}</pre>",
+ syntax_highlight(lang, &inner).unwrap_or_else(|| escape(&inner))
+ )
+ }
+ Rule::inline_latex => format!("<span>TODO: Inline latex</span>"),
+ Rule::latex_block => format!("<p>TODO: Latex block</p>"),
+
+ Rule::text => escape(p.as_str()),
+
_ => todo!("{:?}", p.as_rule()),
}
}