commonmarker 1.0.0.pre-x86_64-linux → 1.0.0.pre7-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
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](#extensions).
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 `render_html` on a string to convert it to HTML:
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
- ## Parse and Render Options
42
+ ## Options and plugins
43
43
 
44
- Commonmarker accepts the same options that comrak does, as a hash dictionary with symbol keys:
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
- | `unsafe_` | Allow rendering of raw HTML and potentially dangerous links. | `false` |
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
- extensions: { footnotes: true, description_lists: true },
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.. | `false` |
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;">&quot;hello&quot;
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
- html = CommonMarker.to_html('*Hello* world!', :DEFAULT)
106
- puts(html)
153
+ puts Commonmarker.to_html('*Hello* world!')
107
154
 
108
155
  # <p><em>Hello</em> world!</p>
109
156
  ```
@@ -4,8 +4,8 @@ version = "1.0.0"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
7
- magnus = { git = "https://github.com/gjtorikian/magnus", branch = "main" } # waiting for release with full rb-sys backend
8
- comrak = "0.14.0"
7
+ magnus = "0.4"
8
+ comrak = { version = "0.16", features = ["shortcodes"] }
9
9
 
10
10
  [lib]
11
11
  name = "commonmarker"
@@ -3,4 +3,4 @@ require "rb_sys/mkmf"
3
3
 
4
4
  require_relative "_util"
5
5
 
6
- create_rust_makefile("commonmarker")
6
+ create_rust_makefile("commonmarker/commonmarker")
@@ -1,27 +1,85 @@
1
1
  extern crate core;
2
2
 
3
- use comrak::{markdown_to_html, ComrakOptions};
4
- use magnus::{define_module, function, r_hash::ForEach, Error, RHash, Symbol};
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 comrak_options;
7
- use comrak_options::iterate_options_hash;
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.foreach(|key: Symbol, value: RHash| {
13
- iterate_options_hash(&mut comrak_options, key, value);
14
- Ok(ForEach::Continue)
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
- markdown_to_html(&rb_commonmark, &comrak_options)
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, 2))?;
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
+ // }
@@ -0,0 +1,8 @@
1
+ use magnus::Value;
2
+
3
+ pub fn try_convert_string(value: Value) -> Option<String> {
4
+ match value.try_convert::<String>() {
5
+ Ok(s) => Some(s),
6
+ Err(_) => None,
7
+ }
8
+ }
Binary file
@@ -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
- OPTS = {
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
- unsafe_: false,
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::OPTS.merge(process_options(options))
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
- BOOLS = [true, false]
49
- ["parse", "render", "extension"].each do |type|
50
- define_singleton_method :"process_#{type}_options" do |options|
51
- Commonmarker::Config::OPTS[type.to_sym].each_with_object({}) do |(key, value), hash|
52
- if options.nil? # option not provided, go for the default
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 options[key].nil?
72
+ next if option[key].nil?
59
73
 
60
- value_klass = value.class
61
- if BOOLS.include?(value) && BOOLS.include?(options[key])
62
- hash[key] = options[key]
63
- elsif options[key].is_a?(value_klass)
64
- hash[key] = options[key]
65
- else
66
- expected_type = BOOLS.include?(value) ? "Boolean" : value_klass.to_s
67
- raise TypeError, "#{type}_options[:#{key}] must be a #{expected_type}; got #{options[key].class}"
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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmarker
4
+ module Constants
5
+ BOOLS = [true, false].freeze
6
+ end
7
+ 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(::RUBY_VERSION)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Commonmarker
4
- VERSION = "1.0.0.pre"
4
+ VERSION = "1.0.0.pre7"
5
5
  end
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
- # option - A {Hash} of render, parse, and extension options to transform the text.
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::OPTS)
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
- commonmark_to_html(text.encode("UTF-8"), opts)
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