diff options
Diffstat (limited to 'crates/ide/src/syntax_highlighting/html.rs')
-rw-r--r-- | crates/ide/src/syntax_highlighting/html.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs new file mode 100644 index 000000000..249368ff8 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/html.rs | |||
@@ -0,0 +1,97 @@ | |||
1 | //! Renders a bit of code as HTML. | ||
2 | |||
3 | use base_db::SourceDatabase; | ||
4 | use oorandom::Rand32; | ||
5 | use syntax::{AstNode, TextRange, TextSize}; | ||
6 | |||
7 | use crate::{syntax_highlighting::highlight, FileId, RootDatabase}; | ||
8 | |||
9 | pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { | ||
10 | let parse = db.parse(file_id); | ||
11 | |||
12 | fn rainbowify(seed: u64) -> String { | ||
13 | let mut rng = Rand32::new(seed); | ||
14 | format!( | ||
15 | "hsl({h},{s}%,{l}%)", | ||
16 | h = rng.rand_range(0..361), | ||
17 | s = rng.rand_range(42..99), | ||
18 | l = rng.rand_range(40..91), | ||
19 | ) | ||
20 | } | ||
21 | |||
22 | let ranges = highlight(db, file_id, None, false); | ||
23 | let text = parse.tree().syntax().to_string(); | ||
24 | let mut prev_pos = TextSize::from(0); | ||
25 | let mut buf = String::new(); | ||
26 | buf.push_str(&STYLE); | ||
27 | buf.push_str("<pre><code>"); | ||
28 | for range in &ranges { | ||
29 | if range.range.start() > prev_pos { | ||
30 | let curr = &text[TextRange::new(prev_pos, range.range.start())]; | ||
31 | let text = html_escape(curr); | ||
32 | buf.push_str(&text); | ||
33 | } | ||
34 | let curr = &text[TextRange::new(range.range.start(), range.range.end())]; | ||
35 | |||
36 | let class = range.highlight.to_string().replace('.', " "); | ||
37 | let color = match (rainbow, range.binding_hash) { | ||
38 | (true, Some(hash)) => { | ||
39 | format!(" data-binding-hash=\"{}\" style=\"color: {};\"", hash, rainbowify(hash)) | ||
40 | } | ||
41 | _ => "".into(), | ||
42 | }; | ||
43 | buf.push_str(&format!("<span class=\"{}\"{}>{}</span>", class, color, html_escape(curr))); | ||
44 | |||
45 | prev_pos = range.range.end(); | ||
46 | } | ||
47 | // Add the remaining (non-highlighted) text | ||
48 | let curr = &text[TextRange::new(prev_pos, TextSize::of(&text))]; | ||
49 | let text = html_escape(curr); | ||
50 | buf.push_str(&text); | ||
51 | buf.push_str("</code></pre>"); | ||
52 | buf | ||
53 | } | ||
54 | |||
55 | //FIXME: like, real html escaping | ||
56 | fn html_escape(text: &str) -> String { | ||
57 | text.replace("<", "<").replace(">", ">") | ||
58 | } | ||
59 | |||
60 | const STYLE: &str = " | ||
61 | <style> | ||
62 | body { margin: 0; } | ||
63 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | ||
64 | |||
65 | .lifetime { color: #DFAF8F; font-style: italic; } | ||
66 | .comment { color: #7F9F7F; } | ||
67 | .documentation { color: #629755; } | ||
68 | .injected { opacity: 0.65 ; } | ||
69 | .struct, .enum { color: #7CB8BB; } | ||
70 | .enum_variant { color: #BDE0F3; } | ||
71 | .string_literal { color: #CC9393; } | ||
72 | .field { color: #94BFF3; } | ||
73 | .function { color: #93E0E3; } | ||
74 | .function.unsafe { color: #BC8383; } | ||
75 | .operator.unsafe { color: #BC8383; } | ||
76 | .parameter { color: #94BFF3; } | ||
77 | .text { color: #DCDCCC; } | ||
78 | .type { color: #7CB8BB; } | ||
79 | .builtin_type { color: #8CD0D3; } | ||
80 | .type_param { color: #DFAF8F; } | ||
81 | .attribute { color: #94BFF3; } | ||
82 | .numeric_literal { color: #BFEBBF; } | ||
83 | .bool_literal { color: #BFE6EB; } | ||
84 | .macro { color: #94BFF3; } | ||
85 | .module { color: #AFD8AF; } | ||
86 | .value_param { color: #DCDCCC; } | ||
87 | .variable { color: #DCDCCC; } | ||
88 | .format_specifier { color: #CC696B; } | ||
89 | .mutable { text-decoration: underline; } | ||
90 | .escape_sequence { color: #94BFF3; } | ||
91 | .keyword { color: #F0DFAF; font-weight: bold; } | ||
92 | .keyword.unsafe { color: #BC8383; font-weight: bold; } | ||
93 | .control { font-style: italic; } | ||
94 | |||
95 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | ||
96 | </style> | ||
97 | "; | ||