kramdown-syntax_tree_sitter 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ba9a8e090021116214ebf5938b8de67856e7aa0054aeb49de5a67041b0683a5
|
|
4
|
+
data.tar.gz: b9d7a9110a29f9abd175ea82c3f54eccb15ca334b69181299f291f43c8c6c35b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ff14f9dff79b8681771b4a0b078e8a1a820489cb2e338f91f5f2ca30d758495a19763f9449585429872c00943c38dca10e88a9465eb7a97cd1c64c298935d528
|
|
7
|
+
data.tar.gz: fc629b06c06b8df3614084dd40ccf8d38747ddc5ab9e096cb85f5976feb0a8f0729615e303a88f256b0bdd9be0c96309ec2cd461bedf472bf7e2f7aa5d4605a5
|
data/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Kramdown Tree-sitter Highlighter
|
|
2
2
|
|
|
3
|
+
[](https://github.com/andrewtbiehl/kramdown-syntax_tree_sitter/actions/workflows/quality-control.yml)
|
|
4
|
+
[](https://rubygems.org/gems/kramdown-syntax_tree_sitter)
|
|
5
|
+
|
|
3
6
|
***Syntax highlight code with [Tree-sitter](https://tree-sitter.github.io/tree-sitter)
|
|
4
7
|
via [Kramdown](https://kramdown.gettalong.org).***
|
|
5
8
|
|
|
@@ -29,14 +32,13 @@ For projects using [Bundler](https://bundler.io) for dependency management, run
|
|
|
29
32
|
following command to both install the gem and add it to the Gemfile:
|
|
30
33
|
|
|
31
34
|
```shell
|
|
32
|
-
bundle add kramdown-syntax_tree_sitter
|
|
35
|
+
bundle add kramdown-syntax_tree_sitter
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
Otherwise,
|
|
36
|
-
within it to build and install the gem:
|
|
38
|
+
Otherwise, install the gem via the following command:
|
|
37
39
|
|
|
38
40
|
```shell
|
|
39
|
-
gem
|
|
41
|
+
gem install kramdown-syntax_tree_sitter
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
## Usage
|
|
@@ -176,14 +178,58 @@ block will only be correctly highlighted if the language identifier provided for
|
|
|
176
178
|
code block is its language's corresponding Tree-sitter scope string. This is illustrated
|
|
177
179
|
by the code block used in the [Quickstart](#quickstart) example.
|
|
178
180
|
|
|
181
|
+
### CSS styling
|
|
182
|
+
|
|
183
|
+
Code highlights can be rendered either via inline CSS styles or via CSS classes, which
|
|
184
|
+
are applied to each token in the parsed code.
|
|
185
|
+
|
|
186
|
+
To use CSS classes for highlighting, set the `css_classes` Kramdown syntax-highlighting
|
|
187
|
+
option to `true`. Otherwise, the plugin will apply highlights via inline CSS styles.
|
|
188
|
+
|
|
189
|
+
The inline CSS styles are derived from Tree-sitter's built-in default highlighting
|
|
190
|
+
theme, repeated here for convenience:
|
|
191
|
+
|
|
192
|
+
| Token name | CSS style |
|
|
193
|
+
| :-- | :-- |
|
|
194
|
+
| attribute | `color: #af0000; font-style: italic;` |
|
|
195
|
+
| comment | `color: #8a8a8a; font-style: italic;` |
|
|
196
|
+
| constant | `color: #875f00;` |
|
|
197
|
+
| function | `color: o#005fd7;` |
|
|
198
|
+
| function.builtin | `color: #005fd7; font-weight: bold;` |
|
|
199
|
+
| keyword | `color: #5f00d7;` |
|
|
200
|
+
| operator | `color: #4e4e4e; font-weight: bold;` |
|
|
201
|
+
| property | `color: #af0000;` |
|
|
202
|
+
| string | `color: #008700;` |
|
|
203
|
+
| string.special | `color: #008787;` |
|
|
204
|
+
| tag | `color: #000087;` |
|
|
205
|
+
| type | `color: #005f5f;` |
|
|
206
|
+
| type.builtin | `color: #005f5f; font-weight: bold;` |
|
|
207
|
+
| variable.builtin | `font-weight: bold;` |
|
|
208
|
+
| variable.parameter | `text-decoration: underline;` |
|
|
209
|
+
| constant.builtin, number | `color: #875f00; font-weight: bold;` |
|
|
210
|
+
| constructor, module | `color: #af8700;` |
|
|
211
|
+
| punctuation.bracket, punctuation.delimiter | `color: #4e4e4e;` |
|
|
212
|
+
|
|
213
|
+
Any and all token types not represented in this default theme are consequently not
|
|
214
|
+
highlighted when using the inline CSS styles option.
|
|
215
|
+
|
|
216
|
+
The CSS class names are derived directly from Tree-sitter token names by replacing all
|
|
217
|
+
full stops ('.') with dashes ('-') and adding the prefix 'ts-'. For example, the CSS
|
|
218
|
+
class for 'function.builtin' tokens is 'ts-function-builtin'. The use of CSS classes
|
|
219
|
+
allows for customization of highlighting styles, including the ability to highlight more
|
|
220
|
+
token types than with the default inline CSS method. Of course, this also requires that
|
|
221
|
+
an externally created CSS stylesheet defining the style for each token type is provided
|
|
222
|
+
whenever the Kramdown-generated HTML is rendered.
|
|
223
|
+
|
|
179
224
|
### Configuration
|
|
180
225
|
|
|
181
226
|
This Kramdown plugin currently supports the following options when provided as sub-keys
|
|
182
227
|
of the Kramdown option `syntax_highlighter_opts`:
|
|
183
228
|
|
|
184
|
-
| Key | Description | Default value |
|
|
185
|
-
| :-- | :-- | :-- |
|
|
186
|
-
| `tree_sitter_parsers_dir` | The path to the Tree-sitter language parsers directory. | `~/tree_sitter_parsers` |
|
|
229
|
+
| Key | Description | Type | Default value |
|
|
230
|
+
| :-- | :-- | :-- | :-- |
|
|
231
|
+
| `tree_sitter_parsers_dir` | The path to the Tree-sitter language parsers directory. | String | `~/tree_sitter_parsers` |
|
|
232
|
+
| `css_classes` | Whether to use CSS classes for highlights. | Boolean | `false` |
|
|
187
233
|
|
|
188
234
|
## Contributing
|
|
189
235
|
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
#[macro_use]
|
|
2
2
|
extern crate rutie;
|
|
3
3
|
|
|
4
|
-
use rutie::{AnyException, Class, Exception, Object, RString, VM};
|
|
4
|
+
use rutie::{AnyException, Boolean, Class, Exception, Object, RString, VM};
|
|
5
5
|
|
|
6
6
|
mod tree_sitter_adapter;
|
|
7
7
|
|
|
8
8
|
class!(TreeSitterAdapter);
|
|
9
9
|
|
|
10
|
+
#[rustfmt::skip]
|
|
10
11
|
methods!(
|
|
11
12
|
TreeSitterAdapter,
|
|
12
13
|
_rtself,
|
|
13
|
-
fn pub_highlight(
|
|
14
|
+
fn pub_highlight(
|
|
15
|
+
raw_code: RString,
|
|
16
|
+
raw_parsers_dir: RString,
|
|
17
|
+
raw_scope: RString,
|
|
18
|
+
css_classes: Boolean
|
|
19
|
+
) -> RString {
|
|
14
20
|
VM::unwrap_or_raise_ex(
|
|
15
21
|
tree_sitter_adapter::highlight(
|
|
16
22
|
&raw_code.unwrap().to_string(),
|
|
17
23
|
&raw_parsers_dir.unwrap().to_string(),
|
|
18
24
|
&raw_scope.unwrap().to_string(),
|
|
25
|
+
css_classes.unwrap().to_bool(),
|
|
19
26
|
)
|
|
20
27
|
.as_ref()
|
|
21
28
|
.map(String::as_str)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
use anyhow::{Context,
|
|
1
|
+
use anyhow::{Context, Result};
|
|
2
|
+
use std::collections::HashMap;
|
|
2
3
|
use std::convert;
|
|
3
4
|
use std::path::PathBuf;
|
|
4
5
|
use tree_sitter::Language;
|
|
6
|
+
use tree_sitter_cli::highlight::Style;
|
|
5
7
|
use tree_sitter_cli::highlight::Theme;
|
|
6
8
|
use tree_sitter_highlight::{Error as TSError, HighlightEvent};
|
|
7
9
|
use tree_sitter_highlight::{Highlight, HighlightConfiguration, Highlighter, HtmlRenderer};
|
|
@@ -9,126 +11,93 @@ use tree_sitter_loader::{Config, LanguageConfiguration, Loader};
|
|
|
9
11
|
|
|
10
12
|
const LOADER_ERROR_MSG: &str = "Error loading Tree-sitter parsers from directory";
|
|
11
13
|
const NO_LANGUAGE_ERROR_MSG: &str = "Error retrieving language configuration for scope";
|
|
14
|
+
const NO_HIGHLIGHT_ERROR_MSG: &str = "Error retrieving highlight configuration for scope";
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let theme = Theme::default();
|
|
16
|
-
let mut loader = Loader::new_from_dir(parsers_dir).map_err(Error::to_formatted_string)?;
|
|
17
|
-
loader.configure_highlights(&theme.highlight_names);
|
|
18
|
-
loader
|
|
19
|
-
.language_configuration_from_scope(scope)
|
|
20
|
-
.and_then(LanguageConfigurationAdapter::highlight_config)
|
|
21
|
-
.and_then(|config| {
|
|
22
|
-
let default_css_style = String::new();
|
|
23
|
-
let css_attribute_callback = get_css_styles(&theme, &default_css_style);
|
|
24
|
-
HighlighterAdapter::new(&loader, config)
|
|
25
|
-
.highlight(code)
|
|
26
|
-
.and_then(|highlights| render_html(highlights, &css_attribute_callback))
|
|
27
|
-
})
|
|
28
|
-
.map_err(Error::to_formatted_string)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
trait LoaderExt {
|
|
32
|
-
fn new_from_dir(parser_directory: PathBuf) -> Result<Loader>;
|
|
33
|
-
|
|
34
|
-
fn language_configuration_from_scope<'a>(
|
|
35
|
-
&'a self,
|
|
36
|
-
scope: &'a str,
|
|
37
|
-
) -> Result<LanguageConfigurationAdapter<'a>>;
|
|
16
|
+
trait ResultExt<T, E> {
|
|
17
|
+
fn flatten_(self) -> Result<T, E>;
|
|
38
18
|
}
|
|
39
19
|
|
|
40
|
-
impl
|
|
41
|
-
fn
|
|
42
|
-
|
|
43
|
-
.and_then(|mut loader| {
|
|
44
|
-
let config = {
|
|
45
|
-
let parser_directory = parser_directory.clone();
|
|
46
|
-
let parser_directories = vec![parser_directory];
|
|
47
|
-
Config { parser_directories }
|
|
48
|
-
};
|
|
49
|
-
loader.find_all_languages(&config)?;
|
|
50
|
-
Ok(loader)
|
|
51
|
-
})
|
|
52
|
-
.with_context(|| {
|
|
53
|
-
let parser_directory_string = parser_directory.display();
|
|
54
|
-
format!("{LOADER_ERROR_MSG} '{parser_directory_string}'")
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
fn language_configuration_from_scope<'a>(
|
|
59
|
-
&'a self,
|
|
60
|
-
scope: &'a str,
|
|
61
|
-
) -> Result<LanguageConfigurationAdapter<'a>> {
|
|
62
|
-
self.language_configuration_for_scope(scope)
|
|
63
|
-
.transpose()
|
|
64
|
-
.context("Language not found")
|
|
65
|
-
.flatten_()
|
|
66
|
-
.map(|(language, config)| LanguageConfigurationAdapter { language, config })
|
|
67
|
-
.with_context(|| format!("{NO_LANGUAGE_ERROR_MSG} '{scope}'"))
|
|
20
|
+
impl<T, E> ResultExt<T, E> for Result<Result<T, E>, E> {
|
|
21
|
+
fn flatten_(self) -> Result<T, E> {
|
|
22
|
+
self.and_then(convert::identity)
|
|
68
23
|
}
|
|
69
24
|
}
|
|
70
25
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
26
|
+
fn loader(parser_directory: PathBuf) -> Result<Loader> {
|
|
27
|
+
Loader::new()
|
|
28
|
+
.and_then(|mut loader| {
|
|
29
|
+
let config = {
|
|
30
|
+
let parser_directory = parser_directory.clone();
|
|
31
|
+
let parser_directories = vec![parser_directory];
|
|
32
|
+
Config { parser_directories }
|
|
33
|
+
};
|
|
34
|
+
loader.find_all_languages(&config)?;
|
|
35
|
+
Ok(loader)
|
|
36
|
+
})
|
|
37
|
+
.with_context(|| {
|
|
38
|
+
let parser_directory_str = parser_directory.display();
|
|
39
|
+
format!("{LOADER_ERROR_MSG} '{parser_directory_str}'")
|
|
40
|
+
})
|
|
74
41
|
}
|
|
75
42
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
43
|
+
fn language_and_configuration<'a>(
|
|
44
|
+
loader: &'a Loader,
|
|
45
|
+
scope: &'a str,
|
|
46
|
+
) -> Result<(Language, &'a LanguageConfiguration<'a>)> {
|
|
47
|
+
loader
|
|
48
|
+
.language_configuration_for_scope(scope)
|
|
49
|
+
.transpose()
|
|
50
|
+
.context("Language not found")
|
|
51
|
+
.flatten_()
|
|
52
|
+
.with_context(|| format!("{NO_LANGUAGE_ERROR_MSG} '{scope}'"))
|
|
84
53
|
}
|
|
85
54
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
55
|
+
fn highlight_configuration<'a>(
|
|
56
|
+
language: Language,
|
|
57
|
+
config: &'a LanguageConfiguration<'a>,
|
|
58
|
+
scope: &'a str,
|
|
59
|
+
) -> Result<&'a HighlightConfiguration> {
|
|
60
|
+
config
|
|
61
|
+
.highlight_config(language)
|
|
62
|
+
.transpose()
|
|
63
|
+
.with_context(|| format!("{NO_HIGHLIGHT_ERROR_MSG} '{scope}'"))
|
|
64
|
+
.flatten_()
|
|
89
65
|
}
|
|
90
66
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
config: &
|
|
94
|
-
|
|
67
|
+
fn highlights(
|
|
68
|
+
code: &str,
|
|
69
|
+
config: &HighlightConfiguration,
|
|
70
|
+
loader: &Loader,
|
|
71
|
+
) -> Result<impl Iterator<Item = Result<HighlightEvent, TSError>>> {
|
|
72
|
+
Highlighter::new()
|
|
73
|
+
.highlight(config, code.as_bytes(), None, |s| {
|
|
74
|
+
loader.highlight_config_for_injection_string(s)
|
|
75
|
+
})
|
|
76
|
+
.map(Iterator::collect)
|
|
77
|
+
.map(Vec::into_iter)
|
|
78
|
+
.map_err(Into::into)
|
|
95
79
|
}
|
|
96
80
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
fn highlight(
|
|
107
|
-
&'a mut self,
|
|
108
|
-
code: &'a str,
|
|
109
|
-
) -> Result<HighlightsAdapter<'a, impl Iterator<Item = Result<HighlightEvent, TSError>> + 'a>>
|
|
110
|
-
{
|
|
111
|
-
let Self {
|
|
112
|
-
loader,
|
|
113
|
-
config,
|
|
114
|
-
highlighter,
|
|
115
|
-
} = self;
|
|
116
|
-
highlighter
|
|
117
|
-
.highlight(config, code.as_bytes(), None, |s| {
|
|
118
|
-
loader.highlight_config_for_injection_string(s)
|
|
119
|
-
})
|
|
120
|
-
.map(|highlights| HighlightsAdapter { code, highlights })
|
|
121
|
-
.map_err(Into::into)
|
|
81
|
+
fn create_html_attribute_callback<'a>(
|
|
82
|
+
html_attributes: &'a [String],
|
|
83
|
+
) -> impl Fn(Highlight) -> &'a [u8] {
|
|
84
|
+
|highlight| {
|
|
85
|
+
html_attributes
|
|
86
|
+
.get(highlight.0)
|
|
87
|
+
.map(String::as_str)
|
|
88
|
+
.unwrap_or_default()
|
|
89
|
+
.as_bytes()
|
|
122
90
|
}
|
|
123
91
|
}
|
|
124
92
|
|
|
125
|
-
fn render_html
|
|
126
|
-
|
|
127
|
-
|
|
93
|
+
fn render_html(
|
|
94
|
+
code: &str,
|
|
95
|
+
highlights: impl Iterator<Item = Result<HighlightEvent, TSError>>,
|
|
96
|
+
html_attributes: &[String],
|
|
128
97
|
) -> Result<String> {
|
|
129
|
-
let
|
|
98
|
+
let html_attribute_callback = create_html_attribute_callback(html_attributes);
|
|
130
99
|
let mut renderer = HtmlRenderer::new();
|
|
131
|
-
renderer.render(highlights, code.as_bytes(),
|
|
100
|
+
renderer.render(highlights, code.as_bytes(), &html_attribute_callback)?;
|
|
132
101
|
// Remove erroneously appended newline
|
|
133
102
|
if renderer.html.ends_with(&[b'\n']) && !code.ends_with('\n') {
|
|
134
103
|
renderer.html.pop();
|
|
@@ -136,36 +105,65 @@ fn render_html<'a, F: Fn(Highlight) -> &'a [u8]>(
|
|
|
136
105
|
Ok(renderer.lines().collect())
|
|
137
106
|
}
|
|
138
107
|
|
|
139
|
-
fn
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
)
|
|
143
|
-
|highlight| {
|
|
144
|
-
theme
|
|
145
|
-
.styles
|
|
146
|
-
.get(highlight.0)
|
|
147
|
-
.and_then(|style| style.css.as_ref())
|
|
148
|
-
.unwrap_or(default_css_style)
|
|
149
|
-
.as_bytes()
|
|
150
|
-
}
|
|
108
|
+
fn highlight_names(scope: &str, loader: &Loader) -> Result<Vec<String>> {
|
|
109
|
+
let (language, config) = language_and_configuration(loader, scope)?;
|
|
110
|
+
let highlight_config = highlight_configuration(language, config, scope)?;
|
|
111
|
+
Ok(highlight_config.names().iter().map(String::from).collect())
|
|
151
112
|
}
|
|
152
113
|
|
|
153
|
-
|
|
154
|
-
|
|
114
|
+
fn highlight_name_styles() -> HashMap<String, Style> {
|
|
115
|
+
let theme = Theme::default();
|
|
116
|
+
theme
|
|
117
|
+
.highlight_names
|
|
118
|
+
.into_iter()
|
|
119
|
+
.zip(theme.styles.into_iter())
|
|
120
|
+
.collect()
|
|
155
121
|
}
|
|
156
122
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
123
|
+
fn inline_css_attributes(highlight_names: &[String]) -> Vec<String> {
|
|
124
|
+
let highlight_name_styles = highlight_name_styles();
|
|
125
|
+
highlight_names
|
|
126
|
+
.iter()
|
|
127
|
+
.map(|n| highlight_name_styles.get(n))
|
|
128
|
+
.map(|o| o.and_then(|style| style.css.as_ref()))
|
|
129
|
+
.map(|o| o.map(String::from))
|
|
130
|
+
.map(Option::unwrap_or_default)
|
|
131
|
+
.collect()
|
|
161
132
|
}
|
|
162
133
|
|
|
163
|
-
|
|
164
|
-
|
|
134
|
+
fn css_class_attributes(highlight_names: &[String]) -> Vec<String> {
|
|
135
|
+
highlight_names
|
|
136
|
+
.iter()
|
|
137
|
+
.map(|s| s.replace('.', "-"))
|
|
138
|
+
.map(|s| format!("class='ts-{s}'"))
|
|
139
|
+
.collect()
|
|
165
140
|
}
|
|
166
141
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
142
|
+
fn highlight_adapter(
|
|
143
|
+
code: &str,
|
|
144
|
+
parsers_dir: &str,
|
|
145
|
+
scope: &str,
|
|
146
|
+
css_classes: bool,
|
|
147
|
+
) -> Result<String> {
|
|
148
|
+
let parsers_dir = PathBuf::from(parsers_dir);
|
|
149
|
+
let mut loader = loader(parsers_dir)?;
|
|
150
|
+
let highlight_names = highlight_names(scope, &loader)?;
|
|
151
|
+
loader.configure_highlights(&highlight_names);
|
|
152
|
+
let (language, config) = language_and_configuration(&loader, scope)?;
|
|
153
|
+
let highlight_config = highlight_configuration(language, config, scope)?;
|
|
154
|
+
let highlights = highlights(code, highlight_config, &loader)?;
|
|
155
|
+
let html_attributes = match css_classes {
|
|
156
|
+
true => css_class_attributes,
|
|
157
|
+
false => inline_css_attributes,
|
|
158
|
+
}(&highlight_names);
|
|
159
|
+
render_html(code, highlights, &html_attributes)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
pub fn highlight(
|
|
163
|
+
code: &str,
|
|
164
|
+
parsers_dir: &str,
|
|
165
|
+
scope: &str,
|
|
166
|
+
css_classes: bool,
|
|
167
|
+
) -> Result<String, String> {
|
|
168
|
+
highlight_adapter(code, parsers_dir, scope, css_classes).map_err(|e| format!("{e:#}"))
|
|
171
169
|
}
|
|
@@ -16,14 +16,26 @@ module Kramdown
|
|
|
16
16
|
def self.call(converter, raw_text, language, type, _)
|
|
17
17
|
return nil unless language
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
rendered_text = TreeSitterAdapter.highlight(
|
|
20
|
+
raw_text,
|
|
21
|
+
get_parsers_dir(converter),
|
|
22
|
+
language,
|
|
23
|
+
get_use_css_classes(converter)
|
|
24
|
+
)
|
|
23
25
|
# Code blocks are additionally wrapped in HTML code tags
|
|
24
26
|
type == :block ? "<pre><code>#{rendered_text}</code></pre>" : rendered_text
|
|
25
27
|
end
|
|
26
28
|
|
|
29
|
+
def self.get_parsers_dir(converter)
|
|
30
|
+
File.expand_path(
|
|
31
|
+
get_option(converter, :tree_sitter_parsers_dir) || DEFAULT_PARSERS_DIR
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.get_use_css_classes(converter)
|
|
36
|
+
get_option(converter, :css_classes) || false
|
|
37
|
+
end
|
|
38
|
+
|
|
27
39
|
def self.get_option(converter, name)
|
|
28
40
|
converter.options[:syntax_highlighter_opts][name]
|
|
29
41
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kramdown-syntax_tree_sitter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew T. Biehl
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-12-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: kramdown
|