commonmarker 1.0.0.pre-x86_64-linux → 1.0.0.pre7-x86_64-linux
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 +4 -4
- data/Cargo.lock +1108 -0
- data/README.md +56 -9
- data/ext/commonmarker/Cargo.toml +2 -2
- data/ext/commonmarker/extconf.rb +1 -1
- data/ext/commonmarker/src/lib.rs +69 -11
- data/ext/commonmarker/src/options.rs +134 -0
- data/ext/commonmarker/src/plugins/syntax_highlighting.rs +30 -0
- data/ext/commonmarker/src/plugins.rs +21 -0
- data/ext/commonmarker/src/utils.rs +8 -0
- data/lib/commonmarker/3.1/commonmarker.so +0 -0
- data/lib/commonmarker/3.2/commonmarker.so +0 -0
- data/lib/commonmarker/config.rb +43 -19
- data/lib/commonmarker/constants.rb +7 -0
- data/lib/commonmarker/extension.rb +1 -1
- data/lib/commonmarker/utils.rb +22 -0
- data/lib/commonmarker/version.rb +1 -1
- data/lib/commonmarker.rb +8 -3
- metadata +17 -10
- data/commonmarker.gemspec +0 -41
- data/ext/commonmarker/src/comrak_options.rs +0 -107
data/README.md
CHANGED
@@ -7,7 +7,7 @@ Ruby wrapper for Rust's [comrak](https://github.com/kivikakk/comrak) crate.
|
|
7
7
|
|
8
8
|
It passes all of the CommonMark test suite, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
|
9
9
|
|
10
|
-
For more information on available extensions, see [the documentation below](#
|
10
|
+
For more information on available extensions, see [the documentation below](#extension-options).
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -27,7 +27,7 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
### Converting to HTML
|
29
29
|
|
30
|
-
Call `
|
30
|
+
Call `to_html` on a string to convert it to HTML:
|
31
31
|
|
32
32
|
```ruby
|
33
33
|
require 'commonmarker'
|
@@ -39,9 +39,11 @@ Commonmarker.to_html('"Hi *there*"', options: {
|
|
39
39
|
|
40
40
|
The second argument is optional--[see below](#options) for more information.
|
41
41
|
|
42
|
-
##
|
42
|
+
## Options and plugins
|
43
43
|
|
44
|
-
|
44
|
+
### Options
|
45
|
+
|
46
|
+
Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
|
45
47
|
|
46
48
|
```ruby
|
47
49
|
Commonmarker.to_html('"Hi *there*"', options:{
|
@@ -66,14 +68,14 @@ Note that there is a distinction in comrak for "parse" options and "render" opti
|
|
66
68
|
| `hardbreaks` | [Soft line breaks](http://spec.commonmark.org/0.27/#soft-line-breaks) translate into hard line breaks. | `true` |
|
67
69
|
| `github_pre_lang` | GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags. | `true` |
|
68
70
|
| `width` | The wrap column when outputting CommonMark. | `80` |
|
69
|
-
| `
|
71
|
+
| `unsafe` | Allow rendering of raw HTML and potentially dangerous links. | `false` |
|
70
72
|
| `escape` | Escape raw HTML instead of clobbering it. | `false` |
|
71
73
|
|
72
74
|
As well, there are several extensions which you can toggle in the same manner:
|
73
75
|
|
74
76
|
```ruby
|
75
77
|
Commonmarker.to_html('"Hi *there*"', options: {
|
76
|
-
|
78
|
+
extension: { footnotes: true, description_lists: true },
|
77
79
|
render: { hardbreaks: false}
|
78
80
|
})
|
79
81
|
```
|
@@ -90,11 +92,57 @@ Commonmarker.to_html('"Hi *there*"', options: {
|
|
90
92
|
| `superscript` | Enables the superscript Comrak extension. | `false` |
|
91
93
|
| `header_ids` | Enables the header IDs Comrak extension. from the GFM spec. | `""` |
|
92
94
|
| `footnotes` | Enables the footnotes extension per `cmark-gfm`. | `false` |
|
93
|
-
| `description_lists` | Enables the description lists extension
|
95
|
+
| `description_lists` | Enables the description lists extension. | `false` |
|
94
96
|
| `front_matter_delimiter` | Enables the front matter extension. | `""` |
|
97
|
+
| `shortcodes` | Enables the shortcodes extension. | `true` |
|
95
98
|
|
96
99
|
For more information on these options, see [the comrak documentation](https://github.com/kivikakk/comrak#usage).
|
97
100
|
|
101
|
+
### Plugins
|
102
|
+
|
103
|
+
In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of
|
104
|
+
providing further niceties.
|
105
|
+
|
106
|
+
#### Syntax Highlighter Plugin
|
107
|
+
|
108
|
+
````ruby
|
109
|
+
code = <<~CODE
|
110
|
+
```ruby
|
111
|
+
def hello
|
112
|
+
puts "hello"
|
113
|
+
end
|
114
|
+
CODE
|
115
|
+
|
116
|
+
puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
|
117
|
+
|
118
|
+
# <pre style="background-color:#ffffff;" lang="ruby"><code>
|
119
|
+
# <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
|
120
|
+
# </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"hello"
|
121
|
+
# </span><span style="font-weight:bold;color:#a71d5d;">end
|
122
|
+
# </span>
|
123
|
+
# </code></pre>
|
124
|
+
````
|
125
|
+
|
126
|
+
To disable this plugin, pass `nil`:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
|
130
|
+
# or
|
131
|
+
Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: nil } })
|
132
|
+
```
|
133
|
+
|
134
|
+
##### Available themes
|
135
|
+
|
136
|
+
Here's [a list of available themes](https://docs.rs/syntect/5.0.0/syntect/highlighting/struct.ThemeSet.html#implementations):
|
137
|
+
|
138
|
+
- `"base16-ocean.dark"`
|
139
|
+
- `"base16-eighties.dark"`
|
140
|
+
- `"base16-mocha.dark"`
|
141
|
+
- `"base16-ocean.light"`
|
142
|
+
- `"InspiredGitHub"`
|
143
|
+
- `"Solarized (dark)"`
|
144
|
+
- `"Solarized (light)"`
|
145
|
+
|
98
146
|
## Output formats
|
99
147
|
|
100
148
|
Commonmarker can currently only generate output in one format: HTML.
|
@@ -102,8 +150,7 @@ Commonmarker can currently only generate output in one format: HTML.
|
|
102
150
|
### HTML
|
103
151
|
|
104
152
|
```ruby
|
105
|
-
|
106
|
-
puts(html)
|
153
|
+
puts Commonmarker.to_html('*Hello* world!')
|
107
154
|
|
108
155
|
# <p><em>Hello</em> world!</p>
|
109
156
|
```
|
data/ext/commonmarker/Cargo.toml
CHANGED
@@ -4,8 +4,8 @@ version = "1.0.0"
|
|
4
4
|
edition = "2021"
|
5
5
|
|
6
6
|
[dependencies]
|
7
|
-
magnus =
|
8
|
-
comrak = "0.
|
7
|
+
magnus = "0.4"
|
8
|
+
comrak = { version = "0.16", features = ["shortcodes"] }
|
9
9
|
|
10
10
|
[lib]
|
11
11
|
name = "commonmarker"
|
data/ext/commonmarker/extconf.rb
CHANGED
data/ext/commonmarker/src/lib.rs
CHANGED
@@ -1,27 +1,85 @@
|
|
1
1
|
extern crate core;
|
2
2
|
|
3
|
-
use comrak::{
|
4
|
-
|
3
|
+
use comrak::{
|
4
|
+
adapters::SyntaxHighlighterAdapter, markdown_to_html, markdown_to_html_with_plugins,
|
5
|
+
plugins::syntect::SyntectAdapter, ComrakOptions, ComrakPlugins,
|
6
|
+
};
|
7
|
+
use magnus::{define_module, function, r_hash::ForEach, scan_args, Error, RHash, Symbol, Value};
|
5
8
|
|
6
|
-
mod
|
7
|
-
use
|
9
|
+
mod options;
|
10
|
+
use options::iterate_options_hash;
|
11
|
+
|
12
|
+
mod plugins;
|
13
|
+
use plugins::{
|
14
|
+
syntax_highlighting::{
|
15
|
+
fetch_syntax_highlighter_theme, SYNTAX_HIGHLIGHTER_PLUGIN_DEFAULT_THEME,
|
16
|
+
},
|
17
|
+
SYNTAX_HIGHLIGHTER_PLUGIN,
|
18
|
+
};
|
19
|
+
|
20
|
+
mod utils;
|
21
|
+
|
22
|
+
pub const EMPTY_STR: &str = "";
|
23
|
+
|
24
|
+
fn commonmark_to_html<'a>(args: &[Value]) -> Result<String, magnus::Error> {
|
25
|
+
let args = scan_args::scan_args(args)?;
|
26
|
+
let (rb_commonmark,): (String,) = args.required;
|
27
|
+
let _: () = args.optional;
|
28
|
+
let _: () = args.splat;
|
29
|
+
let _: () = args.trailing;
|
30
|
+
let _: () = args.block;
|
31
|
+
|
32
|
+
let kwargs = scan_args::get_kwargs::<_, (), (Option<RHash>, Option<RHash>), ()>(
|
33
|
+
args.keywords,
|
34
|
+
&[],
|
35
|
+
&["options", "plugins"],
|
36
|
+
)?;
|
37
|
+
let (rb_options, rb_plugins) = kwargs.optional;
|
8
38
|
|
9
|
-
fn commonmark_to_html(rb_commonmark: String, rb_options: magnus::RHash) -> String {
|
10
39
|
let mut comrak_options = ComrakOptions::default();
|
11
40
|
|
12
|
-
rb_options
|
13
|
-
|
14
|
-
|
15
|
-
|
41
|
+
if let Some(rb_options) = rb_options {
|
42
|
+
rb_options.foreach(|key: Symbol, value: RHash| {
|
43
|
+
iterate_options_hash(&mut comrak_options, key, value)?;
|
44
|
+
Ok(ForEach::Continue)
|
45
|
+
})?;
|
46
|
+
}
|
47
|
+
|
48
|
+
if let Some(rb_plugins) = rb_plugins {
|
49
|
+
let mut comrak_plugins = ComrakPlugins::default();
|
50
|
+
|
51
|
+
let syntax_highlighter: Option<&dyn SyntaxHighlighterAdapter>;
|
52
|
+
let adapter: SyntectAdapter;
|
53
|
+
|
54
|
+
let theme = match rb_plugins.get(Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN)) {
|
55
|
+
Some(theme_val) => fetch_syntax_highlighter_theme(theme_val)?,
|
56
|
+
None => SYNTAX_HIGHLIGHTER_PLUGIN_DEFAULT_THEME.to_string(), // no `syntax_highlighter:` defined
|
57
|
+
};
|
58
|
+
|
59
|
+
if theme.is_empty() || theme == "none" {
|
60
|
+
syntax_highlighter = None;
|
61
|
+
} else {
|
62
|
+
adapter = SyntectAdapter::new(&theme);
|
63
|
+
syntax_highlighter = Some(&adapter);
|
64
|
+
}
|
65
|
+
|
66
|
+
comrak_plugins.render.codefence_syntax_highlighter = syntax_highlighter;
|
16
67
|
|
17
|
-
|
68
|
+
Ok(markdown_to_html_with_plugins(
|
69
|
+
&rb_commonmark,
|
70
|
+
&comrak_options,
|
71
|
+
&comrak_plugins,
|
72
|
+
))
|
73
|
+
} else {
|
74
|
+
Ok(markdown_to_html(&rb_commonmark, &comrak_options))
|
75
|
+
}
|
18
76
|
}
|
19
77
|
|
20
78
|
#[magnus::init]
|
21
79
|
fn init() -> Result<(), Error> {
|
22
80
|
let module = define_module("Commonmarker")?;
|
23
81
|
|
24
|
-
module.define_module_function("commonmark_to_html", function!(commonmark_to_html,
|
82
|
+
module.define_module_function("commonmark_to_html", function!(commonmark_to_html, -1))?;
|
25
83
|
|
26
84
|
Ok(())
|
27
85
|
}
|
@@ -0,0 +1,134 @@
|
|
1
|
+
use std::borrow::Cow;
|
2
|
+
|
3
|
+
use comrak::ComrakOptions;
|
4
|
+
|
5
|
+
use magnus::{class, r_hash::ForEach, Error, RHash, Symbol, Value};
|
6
|
+
|
7
|
+
use crate::utils::try_convert_string;
|
8
|
+
|
9
|
+
const PARSE_SMART: &str = "smart";
|
10
|
+
const PARSE_DEFAULT_INFO_STRING: &str = "default_info_string";
|
11
|
+
|
12
|
+
fn iterate_parse_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
|
13
|
+
options_hash
|
14
|
+
.foreach(|key: Symbol, value: Value| {
|
15
|
+
match key.name() {
|
16
|
+
Ok(Cow::Borrowed(PARSE_SMART)) => {
|
17
|
+
comrak_options.parse.smart = value.try_convert::<bool>()?;
|
18
|
+
}
|
19
|
+
Ok(Cow::Borrowed(PARSE_DEFAULT_INFO_STRING)) => {
|
20
|
+
comrak_options.parse.default_info_string = try_convert_string(value);
|
21
|
+
}
|
22
|
+
_ => {}
|
23
|
+
}
|
24
|
+
Ok(ForEach::Continue)
|
25
|
+
})
|
26
|
+
.unwrap();
|
27
|
+
}
|
28
|
+
|
29
|
+
const RENDER_HARDBREAKS: &str = "hardbreaks";
|
30
|
+
const RENDER_GITHUB_PRE_LANG: &str = "github_pre_lang";
|
31
|
+
const RENDER_WIDTH: &str = "width";
|
32
|
+
const RENDER_UNSAFE: &str = "unsafe";
|
33
|
+
const RENDER_ESCAPE: &str = "escape";
|
34
|
+
|
35
|
+
fn iterate_render_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
|
36
|
+
options_hash
|
37
|
+
.foreach(|key: Symbol, value: Value| {
|
38
|
+
match key.name() {
|
39
|
+
Ok(Cow::Borrowed(RENDER_HARDBREAKS)) => {
|
40
|
+
comrak_options.render.hardbreaks = value.try_convert::<bool>()?;
|
41
|
+
}
|
42
|
+
Ok(Cow::Borrowed(RENDER_GITHUB_PRE_LANG)) => {
|
43
|
+
comrak_options.render.github_pre_lang = value.try_convert::<bool>()?;
|
44
|
+
}
|
45
|
+
Ok(Cow::Borrowed(RENDER_WIDTH)) => {
|
46
|
+
comrak_options.render.width = value.try_convert::<usize>()?;
|
47
|
+
}
|
48
|
+
Ok(Cow::Borrowed(RENDER_UNSAFE)) => {
|
49
|
+
comrak_options.render.unsafe_ = value.try_convert::<bool>()?;
|
50
|
+
}
|
51
|
+
Ok(Cow::Borrowed(RENDER_ESCAPE)) => {
|
52
|
+
comrak_options.render.escape = value.try_convert::<bool>()?;
|
53
|
+
}
|
54
|
+
_ => {}
|
55
|
+
}
|
56
|
+
Ok(ForEach::Continue)
|
57
|
+
})
|
58
|
+
.unwrap();
|
59
|
+
}
|
60
|
+
|
61
|
+
const EXTENSION_STRIKETHROUGH: &str = "strikethrough";
|
62
|
+
const EXTENSION_TAGFILTER: &str = "tagfilter";
|
63
|
+
const EXTENSION_TABLE: &str = "table";
|
64
|
+
const EXTENSION_AUTOLINK: &str = "autolink";
|
65
|
+
const EXTENSION_TASKLIST: &str = "tasklist";
|
66
|
+
const EXTENSION_SUPERSCRIPT: &str = "superscript";
|
67
|
+
const EXTENSION_HEADER_IDS: &str = "header_ids";
|
68
|
+
const EXTENSION_FOOTNOTES: &str = "footnotes";
|
69
|
+
const EXTENSION_DESCRIPTION_LISTS: &str = "description_lists";
|
70
|
+
const EXTENSION_FRONT_MATTER_DELIMITER: &str = "front_matter_delimiter";
|
71
|
+
const EXTENSION_SHORTCODES: &str = "shortcodes";
|
72
|
+
|
73
|
+
fn iterate_extension_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
|
74
|
+
options_hash
|
75
|
+
.foreach(|key: Symbol, value: Value| {
|
76
|
+
match key.name() {
|
77
|
+
Ok(Cow::Borrowed(EXTENSION_STRIKETHROUGH)) => {
|
78
|
+
comrak_options.extension.strikethrough = value.try_convert::<bool>()?;
|
79
|
+
}
|
80
|
+
Ok(Cow::Borrowed(EXTENSION_TAGFILTER)) => {
|
81
|
+
comrak_options.extension.tagfilter = value.try_convert::<bool>()?;
|
82
|
+
}
|
83
|
+
Ok(Cow::Borrowed(EXTENSION_TABLE)) => {
|
84
|
+
comrak_options.extension.table = value.try_convert::<bool>()?;
|
85
|
+
}
|
86
|
+
Ok(Cow::Borrowed(EXTENSION_AUTOLINK)) => {
|
87
|
+
comrak_options.extension.autolink = value.try_convert::<bool>()?;
|
88
|
+
}
|
89
|
+
Ok(Cow::Borrowed(EXTENSION_TASKLIST)) => {
|
90
|
+
comrak_options.extension.tasklist = value.try_convert::<bool>()?;
|
91
|
+
}
|
92
|
+
Ok(Cow::Borrowed(EXTENSION_SUPERSCRIPT)) => {
|
93
|
+
comrak_options.extension.superscript = value.try_convert::<bool>()?;
|
94
|
+
}
|
95
|
+
Ok(Cow::Borrowed(EXTENSION_HEADER_IDS)) => {
|
96
|
+
comrak_options.extension.header_ids = try_convert_string(value);
|
97
|
+
}
|
98
|
+
Ok(Cow::Borrowed(EXTENSION_FOOTNOTES)) => {
|
99
|
+
comrak_options.extension.footnotes = value.try_convert::<bool>()?;
|
100
|
+
}
|
101
|
+
Ok(Cow::Borrowed(EXTENSION_DESCRIPTION_LISTS)) => {
|
102
|
+
comrak_options.extension.description_lists = value.try_convert::<bool>()?;
|
103
|
+
}
|
104
|
+
Ok(Cow::Borrowed(EXTENSION_FRONT_MATTER_DELIMITER)) => {
|
105
|
+
comrak_options.extension.front_matter_delimiter = try_convert_string(value);
|
106
|
+
}
|
107
|
+
Ok(Cow::Borrowed(EXTENSION_SHORTCODES)) => {
|
108
|
+
comrak_options.extension.shortcodes = value.try_convert::<bool>()?;
|
109
|
+
}
|
110
|
+
_ => {}
|
111
|
+
}
|
112
|
+
Ok(ForEach::Continue)
|
113
|
+
})
|
114
|
+
.unwrap();
|
115
|
+
}
|
116
|
+
|
117
|
+
pub fn iterate_options_hash(
|
118
|
+
comrak_options: &mut ComrakOptions,
|
119
|
+
key: Symbol,
|
120
|
+
value: RHash,
|
121
|
+
) -> Result<ForEach, Error> {
|
122
|
+
assert!(value.is_kind_of(class::hash()));
|
123
|
+
|
124
|
+
if key.name().unwrap() == "parse" {
|
125
|
+
iterate_parse_options(comrak_options, value);
|
126
|
+
}
|
127
|
+
if key.name().unwrap() == "render" {
|
128
|
+
iterate_render_options(comrak_options, value);
|
129
|
+
}
|
130
|
+
if key.name().unwrap() == "extension" {
|
131
|
+
iterate_extension_options(comrak_options, value);
|
132
|
+
}
|
133
|
+
Ok(ForEach::Continue)
|
134
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
use magnus::{RHash, Symbol, Value};
|
2
|
+
|
3
|
+
use crate::EMPTY_STR;
|
4
|
+
|
5
|
+
pub const SYNTAX_HIGHLIGHTER_PLUGIN_THEME_KEY: &str = "theme";
|
6
|
+
pub const SYNTAX_HIGHLIGHTER_PLUGIN_DEFAULT_THEME: &str = "base16-ocean.dark";
|
7
|
+
|
8
|
+
pub fn fetch_syntax_highlighter_theme(value: Value) -> Result<String, magnus::Error> {
|
9
|
+
if value.is_nil() {
|
10
|
+
// `syntax_highlighter: nil`
|
11
|
+
return Ok(EMPTY_STR.to_string());
|
12
|
+
}
|
13
|
+
|
14
|
+
let syntax_highlighter_plugin = value.try_convert::<RHash>()?;
|
15
|
+
let theme_key = Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN_THEME_KEY);
|
16
|
+
|
17
|
+
match syntax_highlighter_plugin.get(theme_key) {
|
18
|
+
Some(theme) => {
|
19
|
+
if theme.is_nil() {
|
20
|
+
// `syntax_highlighter: { theme: nil }`
|
21
|
+
return Ok(EMPTY_STR.to_string());
|
22
|
+
}
|
23
|
+
Ok(theme.try_convert::<String>()?)
|
24
|
+
}
|
25
|
+
None => {
|
26
|
+
// `syntax_highlighter: { }`
|
27
|
+
Ok(EMPTY_STR.to_string())
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// use comrak::ComrakPlugins;
|
2
|
+
// use magnus::{class, r_hash::ForEach, RHash, Symbol, Value};
|
3
|
+
|
4
|
+
// use crate::plugins::syntax_highlighting::fetch_syntax_highlighter_theme;
|
5
|
+
|
6
|
+
pub mod syntax_highlighting;
|
7
|
+
|
8
|
+
pub const SYNTAX_HIGHLIGHTER_PLUGIN: &str = "syntax_highlighter";
|
9
|
+
|
10
|
+
// pub fn iterate_plugins_hash(
|
11
|
+
// comrak_plugins: &mut ComrakPlugins,
|
12
|
+
// mut theme: String,
|
13
|
+
// key: Symbol,
|
14
|
+
// value: Value,
|
15
|
+
// ) -> Result<ForEach, magnus::Error> {
|
16
|
+
// if key.name().unwrap() == SYNTAX_HIGHLIGHTER_PLUGIN {
|
17
|
+
// theme = fetch_syntax_highlighter_theme(value)?;
|
18
|
+
// }
|
19
|
+
|
20
|
+
// Ok(ForEach::Continue)
|
21
|
+
// }
|
Binary file
|
Binary file
|
data/lib/commonmarker/config.rb
CHANGED
@@ -4,7 +4,7 @@ module Commonmarker
|
|
4
4
|
module Config
|
5
5
|
# For details, see
|
6
6
|
# https://github.com/kivikakk/comrak/blob/162ef9354deb2c9b4a4e05be495aa372ba5bb696/src/main.rs#L201
|
7
|
-
|
7
|
+
OPTIONS = {
|
8
8
|
parse: {
|
9
9
|
smart: false,
|
10
10
|
default_info_string: "",
|
@@ -13,7 +13,7 @@ module Commonmarker
|
|
13
13
|
hardbreaks: true,
|
14
14
|
github_pre_lang: true,
|
15
15
|
width: 80,
|
16
|
-
|
16
|
+
unsafe: false,
|
17
17
|
escape: false,
|
18
18
|
}.freeze,
|
19
19
|
extension: {
|
@@ -26,14 +26,23 @@ module Commonmarker
|
|
26
26
|
header_ids: "",
|
27
27
|
footnotes: false,
|
28
28
|
description_lists: false,
|
29
|
-
front_matter_delimiter:
|
29
|
+
front_matter_delimiter: nil,
|
30
|
+
shortcodes: true,
|
30
31
|
},
|
31
32
|
format: [:html].freeze,
|
32
33
|
}.freeze
|
33
34
|
|
35
|
+
PLUGINS = {
|
36
|
+
syntax_highlighter: {
|
37
|
+
theme: "base16-ocean.dark",
|
38
|
+
},
|
39
|
+
}
|
40
|
+
|
34
41
|
class << self
|
42
|
+
include Commonmarker::Utils
|
43
|
+
|
35
44
|
def merged_with_defaults(options)
|
36
|
-
Commonmarker::Config::
|
45
|
+
Commonmarker::Config::OPTIONS.merge(process_options(options))
|
37
46
|
end
|
38
47
|
|
39
48
|
def process_options(options)
|
@@ -43,29 +52,44 @@ module Commonmarker
|
|
43
52
|
extension: process_extension_options(options[:extension]),
|
44
53
|
}
|
45
54
|
end
|
46
|
-
end
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
56
|
+
def process_plugins(plugins)
|
57
|
+
{
|
58
|
+
syntax_highlighter: process_syntax_highlighter_plugin(plugins&.fetch(:syntax_highlighter, nil)),
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
[:parse, :render, :extension].each do |type|
|
64
|
+
define_singleton_method :"process_#{type}_options" do |option|
|
65
|
+
Commonmarker::Config::OPTIONS[type].each_with_object({}) do |(key, value), hash|
|
66
|
+
if option.nil? # option not provided, go for the default
|
53
67
|
hash[key] = value
|
54
68
|
next
|
55
69
|
end
|
56
70
|
|
57
71
|
# option explicitly not included, remove it
|
58
|
-
next if
|
72
|
+
next if option[key].nil?
|
59
73
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
74
|
+
hash[key] = fetch_kv(option, key, value, type)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
[:syntax_highlighter].each do |type|
|
80
|
+
define_singleton_method :"process_#{type}_plugin" do |plugin|
|
81
|
+
return nil if plugin.nil? # plugin explicitly nil, remove it
|
82
|
+
|
83
|
+
Commonmarker::Config::PLUGINS[type].each_with_object({}) do |(key, value), hash|
|
84
|
+
if plugin.nil? # option not provided, go for the default
|
85
|
+
hash[key] = value
|
86
|
+
next
|
68
87
|
end
|
88
|
+
|
89
|
+
# option explicitly not included, remove it
|
90
|
+
next if plugin[key].nil?
|
91
|
+
|
92
|
+
hash[key] = fetch_kv(plugin, key, value, type)
|
69
93
|
end
|
70
94
|
end
|
71
95
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
begin
|
4
4
|
# native precompiled gems package shared libraries in <gem_dir>/lib/commonmarker/<ruby_version>
|
5
5
|
# load the precompiled extension file
|
6
|
-
ruby_version = /\d+\.\d+/.match(
|
6
|
+
ruby_version = /\d+\.\d+/.match(RUBY_VERSION)
|
7
7
|
require_relative "#{ruby_version}/commonmarker"
|
8
8
|
rescue LoadError
|
9
9
|
# fall back to the extension compiled upon installation.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "commonmarker/constants"
|
4
|
+
|
5
|
+
module Commonmarker
|
6
|
+
module Utils
|
7
|
+
include Commonmarker::Constants
|
8
|
+
|
9
|
+
def fetch_kv(option, key, value, type)
|
10
|
+
value_klass = value.class
|
11
|
+
|
12
|
+
if Constants::BOOLS.include?(value) && BOOLS.include?(option[key])
|
13
|
+
option[key]
|
14
|
+
elsif option[key].is_a?(value_klass)
|
15
|
+
option[key]
|
16
|
+
else
|
17
|
+
expected_type = Constants::BOOLS.include?(value) ? "Boolean" : value_klass.to_s
|
18
|
+
raise TypeError, "#{type} option `:#{key}` must be #{expected_type}; got #{option[key].class}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/commonmarker/version.rb
CHANGED
data/lib/commonmarker.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "commonmarker/extension"
|
4
4
|
|
5
|
+
require "commonmarker/utils"
|
5
6
|
require "commonmarker/config"
|
6
7
|
require "commonmarker/renderer"
|
7
8
|
require "commonmarker/version"
|
@@ -16,15 +17,19 @@ module Commonmarker
|
|
16
17
|
# Public: Parses a CommonMark string into an HTML string.
|
17
18
|
#
|
18
19
|
# text - A {String} of text
|
19
|
-
#
|
20
|
+
# options - A {Hash} of render, parse, and extension options to transform the text.
|
21
|
+
# plugins - A {Hash} of additional plugins.
|
20
22
|
#
|
21
23
|
# Returns a {String} of converted HTML.
|
22
|
-
def to_html(text, options: Commonmarker::Config::
|
24
|
+
def to_html(text, options: Commonmarker::Config::OPTIONS, plugins: Commonmarker::Config::PLUGINS)
|
23
25
|
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
|
26
|
+
raise TypeError, "text must be UTF-8 encoded; got #{text.encoding}!" unless text.encoding.name == "UTF-8"
|
24
27
|
raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
|
25
28
|
|
26
29
|
opts = Config.process_options(options)
|
27
|
-
|
30
|
+
plugins = Config.process_plugins(plugins)
|
31
|
+
|
32
|
+
commonmark_to_html(text, options: opts, plugins: plugins)
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|