Skip to content

Commit

Permalink
Improve syntax highlighting (#150)
Browse files Browse the repository at this point in the history
* Add failing test

* Use extended syntax definitions

* Add failing test

* Allow for comma as an info string delimiter
  • Loading branch information
CosmicHorrorDev authored Jul 11, 2023
1 parent 312c9ee commit cc3ae7f
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 3 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ twox-hash = "1.6.3"
taffy = { git = "https://github.com/DioxusLabs/taffy", rev = "d338f3731da519d182bbc074de46382984ab7c4a" }
syntect = "5.0.0"

[dependencies.two-face]
version = "0.1.1"
default-features = false
features = ["extra-syntax"]

[dependencies.glyphon]
version = "0.2"
git = "https://github.com/trimental/glyphon"
Expand Down
3 changes: 3 additions & 0 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ impl PartialEq for Theme {
}
}

// TODO: the error message here degraded when switching this to allow for custom themes. It'd be
// good to still list all the default themes when passing in something else. Add a test for
// the error message
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(untagged)]
pub enum SyntaxTheme {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
source: src/interpreter/tests.rs
description: " --- md\n\n```rust,ignore\nlet v = 1;\n```\n\n\n --- html\n\n<pre style=\"background-color:#f6f8fa;\"><code class=\"language-rust,ignore\"><span style=\"font-weight:bold;color:#a71d5d;\">let</span><span style=\"color:#323232;\"> v </span><span style=\"font-weight:bold;color:#a71d5d;\">= </span><span style=\"color:#0086b3;\">1</span><span style=\"color:#323232;\">;\n</span></code></pre>\n"
expression: interpret_md(text)
---
[
TextBox(
TextBox {
background_color: Some(Color { r: 0.92, g: 0.94, b: 0.96 }),
is_code_block: true,
texts: [
Text {
text: "let",
font_family: Monospace,
color: Some(Color { r: 0.39, g: 0.01, b: 0.11 }),
style: BOLD ,
..
},
Text {
text: " v ",
font_family: Monospace,
color: Some(Color { r: 0.03, g: 0.03, b: 0.03 }),
..
},
Text {
text: "= ",
font_family: Monospace,
color: Some(Color { r: 0.39, g: 0.01, b: 0.11 }),
style: BOLD ,
..
},
Text {
text: "1",
font_family: Monospace,
color: Some(Color { r: 0.00, g: 0.24, b: 0.45 }),
..
},
Text {
text: ";",
font_family: Monospace,
color: Some(Color { r: 0.03, g: 0.03, b: 0.03 }),
..
},
Text {
text: "\n",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
source: src/interpreter/tests.rs
description: " --- md\n\n```toml\nkey = 123\n```\n\n\n --- html\n\n<pre style=\"background-color:#f6f8fa;\"><code class=\"language-toml\"><span style=\"color:#63a35c;\">key </span><span style=\"color:#323232;\">= </span><span style=\"color:#0086b3;\">123\n</span></code></pre>\n"
expression: interpret_md(text)
---
[
TextBox(
TextBox {
background_color: Some(Color { r: 0.92, g: 0.94, b: 0.96 }),
is_code_block: true,
texts: [
Text {
text: "key ",
font_family: Monospace,
color: Some(Color { r: 0.12, g: 0.37, b: 0.11 }),
..
},
Text {
text: "= ",
font_family: Monospace,
color: Some(Color { r: 0.03, g: 0.03, b: 0.03 }),
..
},
Text {
text: "123",
font_family: Monospace,
color: Some(Color { r: 0.00, g: 0.24, b: 0.45 }),
..
},
Text {
text: "\n",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
]
14 changes: 14 additions & 0 deletions src/interpreter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,25 @@ In a paragraph https://example.org
- In a list https://example.org
";

const TOML_GETS_HIGHLIGHTED: &str = "\
```toml
key = 123
```
";

const HANDLES_COMMA_IN_INFO_STR: &str = "\
```rust,ignore
let v = 1;
```
";

snapshot_interpreted_elements!(
(footnotes_list_prefix, FOOTNOTES_LIST_PREFIX),
(checklist_has_no_text_prefix, CHECKLIST_HAS_NO_TEXT_PREFIX),
(code_block_bg_color, CODE_BLOCK_BG_COLOR),
(bare_link_gets_autolinked, BARE_LINK_GETS_AUTOLINKED),
(toml_gets_highlighted, TOML_GETS_HIGHLIGHTED),
(handles_comma_in_info_str, HANDLES_COMMA_IN_INFO_STR),
);

/// Spin up a server, so we can test network requests without external services
Expand Down
45 changes: 42 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use std::{
collections::HashMap,
io,
sync::{Arc, Mutex},
};

use comrak::{
markdown_to_html_with_plugins, plugins::syntect::SyntectAdapterBuilder, ComrakOptions,
adapters::SyntaxHighlighterAdapter,
markdown_to_html_with_plugins,
plugins::syntect::{SyntectAdapter, SyntectAdapterBuilder},
ComrakOptions,
};
use indexmap::IndexMap;
use serde::Deserialize;
Expand Down Expand Up @@ -77,6 +81,39 @@ impl From<CursorIcon> for HoverInfo {
}
}

// TODO(cosmic): Remove after `comrak` supports code block info strings that have a comma
// (like ```rust,ignore)
// https://github.com/kivikakk/comrak/issues/246
struct CustomSyntectAdapter(SyntectAdapter);

impl SyntaxHighlighterAdapter for CustomSyntectAdapter {
fn write_highlighted(
&self,
output: &mut dyn io::Write,
lang: Option<&str>,
code: &str,
) -> io::Result<()> {
let norm_lang = lang.map(|l| l.split_once(',').map(|(lang, _)| lang).unwrap_or(l));
self.0.write_highlighted(output, norm_lang, code)
}

fn write_pre_tag(
&self,
output: &mut dyn io::Write,
attributes: HashMap<String, String>,
) -> io::Result<()> {
self.0.write_pre_tag(output, attributes)
}

fn write_code_tag(
&self,
output: &mut dyn io::Write,
attributes: HashMap<String, String>,
) -> io::Result<()> {
self.0.write_code_tag(output, attributes)
}
}

pub fn markdown_to_html(md: &str, syntax_theme: SyntectTheme) -> String {
let mut options = ComrakOptions::default();
options.extension.autolink = true;
Expand All @@ -95,14 +132,16 @@ pub fn markdown_to_html(md: &str, syntax_theme: SyntectTheme) -> String {
theme_set
.themes
.insert(String::from(dummy_name), syntax_theme);
let syn_set = two_face::syntax::extra();
let adapter = SyntectAdapterBuilder::new()
.syntax_set(syn_set)
.theme_set(theme_set)
// .theme(syntax_theme.as_syntect_name())
.theme(dummy_name)
.build();

let mut plugins = comrak::ComrakPlugins::default();
plugins.render.codefence_syntax_highlighter = Some(&adapter);
let custom = CustomSyntectAdapter(adapter);
plugins.render.codefence_syntax_highlighter = Some(&custom);

let htmlified = markdown_to_html_with_plugins(md, &options, &plugins);

Expand Down

0 comments on commit cc3ae7f

Please sign in to comment.