Skip to content

Commit 5578f45

Browse files
Nemo157syphar
authored andcommitted
Strip off trailing , delimited codeblock info-string attributes
1 parent d523899 commit 5578f45

File tree

3 files changed

+79
-9
lines changed

3 files changed

+79
-9
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ fn-error-context = "0.2.0"
121121
aws-smithy-client = { version = "0.49.0", features = ["test-util"]}
122122
aws-smithy-http = "0.49.0"
123123
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
124+
indoc = "1.0.7"
124125

125126
[build-dependencies]
126127
time = "0.3"

src/web/markdown.rs

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,39 @@ use comrak::{
44
ComrakRenderPlugins,
55
};
66
use once_cell::sync::Lazy;
7-
use std::collections::HashMap;
8-
use std::fmt::Write;
7+
use std::{collections::HashMap, fmt::Write};
98

109
#[derive(Debug)]
11-
struct CodeAdapter;
10+
struct CodeAdapter<F>(F);
1211

13-
impl SyntaxHighlighterAdapter for CodeAdapter {
12+
impl<F: Fn(Option<&str>, &str) -> String> SyntaxHighlighterAdapter for CodeAdapter<F> {
1413
fn highlight(&self, lang: Option<&str>, code: &str) -> String {
15-
highlight_code(lang, code)
14+
// comrak does not treat `,` as an info-string delimiter, so we do that here
15+
// TODO: https://github.com/kivikakk/comrak/issues/246
16+
let lang = lang.and_then(|lang| lang.split(',').next());
17+
(self.0)(lang, code)
1618
}
1719

1820
fn build_pre_tag(&self, attributes: &HashMap<String, String>) -> String {
1921
build_opening_tag("pre", attributes)
2022
}
2123

2224
fn build_code_tag(&self, attributes: &HashMap<String, String>) -> String {
23-
build_opening_tag("code", attributes)
25+
// similarly to above, since comrak does not treat `,` as an info-string delimiter it will
26+
// try to apply `class="language-rust,ignore"` for the info-string `rust,ignore`, so we
27+
// have to detect that case and fixup the class here
28+
// TODO: https://github.com/kivikakk/comrak/issues/246
29+
let mut attributes = attributes.clone();
30+
if let Some(classes) = attributes.get_mut("class") {
31+
*classes = classes
32+
.split(' ')
33+
.flat_map(|class| [class.split(',').next().unwrap_or(class), " "])
34+
.collect();
35+
// remove trailing ' '
36+
// TODO: https://github.com/rust-lang/rust/issues/79524 or itertools
37+
classes.pop();
38+
}
39+
build_opening_tag("code", &attributes)
2440
}
2541
}
2642

@@ -82,8 +98,10 @@ pub fn highlight_code(lang: Option<&str>, code: &str) -> String {
8298
}
8399
}
84100

85-
/// Wrapper around the Markdown parser and renderer to render markdown
86-
pub(crate) fn render(text: &str) -> String {
101+
fn render_with_highlighter(
102+
text: &str,
103+
highlighter: impl Fn(Option<&str>, &str) -> String,
104+
) -> String {
87105
comrak::markdown_to_html_with_plugins(
88106
text,
89107
&ComrakOptions {
@@ -99,8 +117,52 @@ pub(crate) fn render(text: &str) -> String {
99117
},
100118
&ComrakPlugins {
101119
render: ComrakRenderPlugins {
102-
codefence_syntax_highlighter: Some(&CodeAdapter),
120+
codefence_syntax_highlighter: Some(&CodeAdapter(highlighter)),
103121
},
104122
},
105123
)
106124
}
125+
126+
/// Wrapper around the Markdown parser and renderer to render markdown
127+
pub fn render(text: &str) -> String {
128+
render_with_highlighter(text, highlight_code)
129+
}
130+
131+
#[cfg(test)]
132+
mod test {
133+
use super::{highlight_code, render_with_highlighter};
134+
use indoc::indoc;
135+
use std::cell::RefCell;
136+
137+
#[test]
138+
fn ignore_info_string_attributes() {
139+
let highlighted = RefCell::new(vec![]);
140+
141+
let output = render_with_highlighter(
142+
indoc! {"
143+
```rust,ignore
144+
ignore::commas();
145+
```
146+
147+
```rust ignore
148+
ignore::spaces();
149+
```
150+
"},
151+
|lang, code| {
152+
highlighted
153+
.borrow_mut()
154+
.push((lang.map(str::to_owned), code.to_owned()));
155+
highlight_code(lang, code)
156+
},
157+
);
158+
159+
assert!(output.matches(r#"<code class="language-rust">"#).count() == 2);
160+
assert_eq!(
161+
highlighted.borrow().as_slice(),
162+
[
163+
(Some("rust".into()), "ignore::commas();\n".into()),
164+
(Some("rust".into()), "ignore::spaces();\n".into())
165+
]
166+
);
167+
}
168+
}

0 commit comments

Comments
 (0)