carbon_lib/
highlight.rs

1use crate::{
2    utils::{html_render_line, html_render_line_number, CarbonHTML},
3    CarbonError, Render,
4};
5use carbon_dump::SYNTAX_SET;
6use std::ops::Deref;
7use syntect::{
8    easy::HighlightLines,
9    highlighting::{Color, Style},
10    util::{as_24_bit_terminal_escaped, as_latex_escaped, LinesWithEndings},
11};
12
13impl Render {
14    pub fn render_terminal(&self, input: &str) -> Result<String, CarbonError> {
15        let set = SYNTAX_SET.deref();
16        // The main process of the program
17        let mut h = HighlightLines::new(&self.syntax, &self.theme);
18        let mut out = String::with_capacity(2 * input.len());
19        for line in LinesWithEndings::from(input) {
20            let ranges: Vec<(Style, &str)> = h.highlight(line, set);
21            let escaped = as_24_bit_terminal_escaped(&ranges[..], true);
22            out.push_str(&escaped)
23        }
24        return Ok(out);
25    }
26    pub fn render_latex(&self, input: &str) -> Result<String, CarbonError> {
27        let set = SYNTAX_SET.deref();
28        // The main process of the program
29        let mut h = HighlightLines::new(&self.syntax, &self.theme);
30        let mut out = String::with_capacity(10 * input.len());
31        for line in LinesWithEndings::from(input) {
32            // LinesWithEndings enables use of newlines mode
33            let ranges: Vec<(Style, &str)> = h.highlight(line, set);
34            let escaped = as_latex_escaped(&ranges[..]);
35            out.push_str(&escaped);
36            out.push_str("\n\n")
37        }
38        return Ok(out);
39    }
40    pub fn render_html(&self, input: &str) -> Result<String, CarbonError> {
41        // The main process of the program
42        let mut out = String::with_capacity(25 * input.len());
43        let c = self.theme.settings.background.unwrap_or(Color::WHITE);
44        match self.html_type {
45            CarbonHTML::Inline => {
46                out.push_str("<pre class=\"carbon\">");
47                out.push_str(&self.render_check_line_number(input));
48                out.push_str(&format!("</pre>"));
49            }
50            CarbonHTML::Embedded => match &self.file_title {
51                None => {
52                    out.push_str(&self.render_check_line_number(input));
53                }
54                Some(s) => {
55                    out.push_str(&format!(
56                        "<div class=\"carbon\" style=\"background-color:#{:02x}{:02x}{:02x};\">\n",
57                        c.r, c.g, c.b
58                    ));
59                    out.push_str(&self.render_check_line_number(input));
60                    out.push_str(&format!("</div>"));
61                }
62            },
63            CarbonHTML::Independent => {
64                out.push_str(&format!("<head><style>pre{{{}}}</style></head>", self.html_style));
65                out.push_str(&format!("<body style=\"background-color:#{:02x}{:02x}{:02x};\">\n", c.r, c.g, c.b));
66                out.push_str(&format!("{}", self.render_check_line_number(input)));
67                out.push_str(&format!("</body>"));
68            }
69        };
70        return Ok(out);
71    }
72}
73
74impl Render {
75    fn render_check_line_number(&self, input: &str) -> String {
76        match self.line_number {
77            None => html_render_line(input, &self.syntax, &self.theme),
78            Some(_) => html_render_line_number(input, &self.syntax, &self.theme),
79        }
80    }
81}