1use std::{collections::HashMap, io::Write};
2
3use comrak::adapters::SyntaxHighlighterAdapter;
4use syntect::{
5 html::{ClassStyle, ClassedHTMLGenerator},
6 parsing::SyntaxSet,
7 util::LinesWithEndings,
8};
9
10pub struct ComrakSyntectAdapter<'a> {
11 pub(crate) syntax_set: &'a SyntaxSet,
12}
13
14impl SyntaxHighlighterAdapter for ComrakSyntectAdapter<'_> {
15 fn write_highlighted(
16 &self,
17 output: &mut dyn Write,
18 lang: Option<&str>,
19 code: &str,
20 ) -> std::io::Result<()> {
21 let syntax = lang
22 .and_then(|v| self.syntax_set.find_syntax_by_token(v))
23 .unwrap_or_else(|| self.syntax_set.find_syntax_plain_text());
24
25 let mut html_generator =
26 ClassedHTMLGenerator::new_with_class_style(syntax, self.syntax_set, ClassStyle::Spaced);
27
28 for line in LinesWithEndings::from(code) {
29 let _res = html_generator.parse_html_for_line_which_includes_newline(line);
30 }
31
32 write!(
33 output,
34 "<code>{}</code>",
35 html_generator.finalize().replace('\n', "</code>\n<code>")
36 )
37 }
38
39 fn write_pre_tag(
40 &self,
41 output: &mut dyn Write,
42 _attributes: HashMap<String, String>,
43 ) -> std::io::Result<()> {
44 write!(output, r#"<pre>"#)
45 }
46
47 fn write_code_tag(
48 &self,
49 _output: &mut dyn Write,
50 _attributes: HashMap<String, String>,
51 ) -> std::io::Result<()> {
52 Ok(())
53 }
54}