[Web] Highlight code blocks.
This commit is contained in:
parent
0588e1f2fe
commit
5c60943fab
@ -1,13 +1,17 @@
|
|||||||
use markdown::mdast::Code;
|
use markdown::mdast::Code;
|
||||||
|
|
||||||
|
use crate::highlighter::highlight;
|
||||||
|
|
||||||
use super::Printable;
|
use super::Printable;
|
||||||
|
|
||||||
impl Printable for Code {
|
impl Printable for Code {
|
||||||
fn to_html(&self) -> String {
|
fn to_html(&self) -> String {
|
||||||
|
let code = highlight(&self.value);
|
||||||
|
|
||||||
if let Some(lang) = &self.lang {
|
if let Some(lang) = &self.lang {
|
||||||
format!("<pre class=\"language-{}\">{}</pre>", lang, self.value)
|
format!("<pre class=\"language-{}\">{}</pre>", lang, code)
|
||||||
} else {
|
} else {
|
||||||
format!("<pre class=\"language-none\">{}</pre>", self.value)
|
format!("<pre class=\"language-none\">{}</pre>", code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use markdown::mdast::InlineCode;
|
use markdown::mdast::InlineCode;
|
||||||
|
|
||||||
use super::Printable;
|
use super::Printable;
|
||||||
use misti::TokenType;
|
use crate::highlighter::highlight;
|
||||||
|
|
||||||
impl Printable for InlineCode {
|
impl Printable for InlineCode {
|
||||||
fn to_html(&self) -> String {
|
fn to_html(&self) -> String {
|
||||||
@ -21,110 +21,3 @@ impl Printable for InlineCode {
|
|||||||
self.value.clone()
|
self.value.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn highlight(input: &String) -> String {
|
|
||||||
// The tokens come in order
|
|
||||||
let tokens = misti::tokenize(&input);
|
|
||||||
|
|
||||||
if tokens.is_err() {
|
|
||||||
eprintln!(
|
|
||||||
"Found a lexical error processing an inline-code with input {}",
|
|
||||||
input
|
|
||||||
);
|
|
||||||
return input.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut output = input.clone();
|
|
||||||
// Offset to the position of the tokens in the string, to allow
|
|
||||||
// several tokens to be highlighted
|
|
||||||
let mut offset = 0;
|
|
||||||
|
|
||||||
for token in tokens.unwrap() {
|
|
||||||
match &token.token_type {
|
|
||||||
TokenType::Datatype => {
|
|
||||||
let start_pos = token.position;
|
|
||||||
let end_pos = token.get_end_position();
|
|
||||||
|
|
||||||
let range = (start_pos + offset)..(end_pos + offset);
|
|
||||||
let html = format!("<span class=\"token class-name\">{}</span>", token.value);
|
|
||||||
|
|
||||||
// 38 is the number of extra characters added to the token
|
|
||||||
offset += 38;
|
|
||||||
|
|
||||||
output.replace_range(range, html.as_str());
|
|
||||||
}
|
|
||||||
TokenType::Number => {
|
|
||||||
let start_pos = token.position;
|
|
||||||
let end_pos = token.get_end_position();
|
|
||||||
|
|
||||||
let range = (start_pos + offset)..(end_pos + offset);
|
|
||||||
let html = format!("<span class=\"token number\">{}</span>", token.value);
|
|
||||||
|
|
||||||
offset += 34;
|
|
||||||
|
|
||||||
output.replace_range(range, html.as_str());
|
|
||||||
}
|
|
||||||
TokenType::String => {
|
|
||||||
let start_pos = token.position;
|
|
||||||
let end_pos = token.get_end_position();
|
|
||||||
|
|
||||||
let range = (start_pos + offset)..(end_pos + offset);
|
|
||||||
let html = format!("<span class=\"token string\">\"{}\"</span>", token.value);
|
|
||||||
|
|
||||||
offset += 34;
|
|
||||||
|
|
||||||
output.replace_range(range, html.as_str());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_return_simple_string() {
|
|
||||||
assert_eq!("sample", highlight(&String::from("sample")))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_highlight_datatype() {
|
|
||||||
assert_eq!(
|
|
||||||
"<span class=\"token class-name\">Num</span>",
|
|
||||||
highlight(&String::from("Num"))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_highlight_number() {
|
|
||||||
assert_eq!(
|
|
||||||
"<span class=\"token number\">322</span>",
|
|
||||||
highlight(&String::from("322"))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_highlight_string() {
|
|
||||||
assert_eq!(
|
|
||||||
"<span class=\"token string\">\"Hello\"</span>",
|
|
||||||
highlight(&String::from("\"Hello\""))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_highlight_multiple_tokens() {
|
|
||||||
assert_eq!(
|
|
||||||
"<span class=\"token class-name\">Str</span> x = <span class=\"token number\">322</span>",
|
|
||||||
highlight(&String::from("Str x = 322"))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
"<span class=\"token class-name\">Str</span> x = <span class=\"token string\">\"hello\"</span> <span class=\"token number\">322</span>",
|
|
||||||
highlight(&String::from("Str x = \"hello\" 322"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
108
doc-generator/src/highlighter/mod.rs
Normal file
108
doc-generator/src/highlighter/mod.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
use misti::TokenType;
|
||||||
|
|
||||||
|
pub fn highlight(input: &String) -> String {
|
||||||
|
// The tokens come in order
|
||||||
|
let tokens = misti::tokenize(&input);
|
||||||
|
|
||||||
|
if tokens.is_err() {
|
||||||
|
eprintln!(
|
||||||
|
"Found a lexical error processing code.\n{:?}",
|
||||||
|
tokens
|
||||||
|
);
|
||||||
|
return input.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut output = input.clone();
|
||||||
|
// Offset to the position of the tokens in the string, to allow
|
||||||
|
// several tokens to be highlighted
|
||||||
|
let mut offset = 0;
|
||||||
|
|
||||||
|
for token in tokens.unwrap() {
|
||||||
|
match &token.token_type {
|
||||||
|
TokenType::Datatype => {
|
||||||
|
let start_pos = token.position;
|
||||||
|
let end_pos = token.get_end_position();
|
||||||
|
|
||||||
|
let range = (start_pos + offset)..(end_pos + offset);
|
||||||
|
let html = format!("<span class=\"token class-name\">{}</span>", token.value);
|
||||||
|
|
||||||
|
// 38 is the number of extra characters added to the token
|
||||||
|
offset += 38;
|
||||||
|
|
||||||
|
output.replace_range(range, html.as_str());
|
||||||
|
}
|
||||||
|
TokenType::Number => {
|
||||||
|
let start_pos = token.position;
|
||||||
|
let end_pos = token.get_end_position();
|
||||||
|
|
||||||
|
let range = (start_pos + offset)..(end_pos + offset);
|
||||||
|
let html = format!("<span class=\"token number\">{}</span>", token.value);
|
||||||
|
|
||||||
|
offset += 34;
|
||||||
|
|
||||||
|
output.replace_range(range, html.as_str());
|
||||||
|
}
|
||||||
|
TokenType::String => {
|
||||||
|
let start_pos = token.position;
|
||||||
|
let end_pos = token.get_end_position();
|
||||||
|
|
||||||
|
let range = (start_pos + offset)..(end_pos + offset);
|
||||||
|
let html = format!("<span class=\"token string\">\"{}\"</span>", token.value);
|
||||||
|
|
||||||
|
offset += 34;
|
||||||
|
|
||||||
|
output.replace_range(range, html.as_str());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_return_simple_string() {
|
||||||
|
assert_eq!("sample", highlight(&String::from("sample")))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_highlight_datatype() {
|
||||||
|
assert_eq!(
|
||||||
|
"<span class=\"token class-name\">Num</span>",
|
||||||
|
highlight(&String::from("Num"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_highlight_number() {
|
||||||
|
assert_eq!(
|
||||||
|
"<span class=\"token number\">322</span>",
|
||||||
|
highlight(&String::from("322"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_highlight_string() {
|
||||||
|
assert_eq!(
|
||||||
|
"<span class=\"token string\">\"Hello\"</span>",
|
||||||
|
highlight(&String::from("\"Hello\""))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_highlight_multiple_tokens() {
|
||||||
|
assert_eq!(
|
||||||
|
"<span class=\"token class-name\">Str</span> x = <span class=\"token number\">322</span>",
|
||||||
|
highlight(&String::from("Str x = 322"))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
"<span class=\"token class-name\">Str</span> x = <span class=\"token string\">\"hello\"</span> <span class=\"token number\">322</span>",
|
||||||
|
highlight(&String::from("Str x = \"hello\" 322"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ use std::{fs, path::Path};
|
|||||||
|
|
||||||
mod generator;
|
mod generator;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod highlighter;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
|
Loading…
Reference in New Issue
Block a user