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