commonmarker 0.23.10 → 1.0.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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1049 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +144 -203
  5. data/ext/commonmarker/Cargo.toml +13 -0
  6. data/ext/commonmarker/extconf.rb +3 -6
  7. data/ext/commonmarker/src/lib.rs +153 -0
  8. data/ext/commonmarker/src/options.rs +140 -0
  9. data/ext/commonmarker/src/plugins/syntax_highlighting.rs +74 -0
  10. data/ext/commonmarker/src/plugins.rs +3 -0
  11. data/ext/commonmarker/src/utils.rs +8 -0
  12. data/lib/commonmarker/config.rb +84 -40
  13. data/lib/commonmarker/constants.rb +7 -0
  14. data/lib/commonmarker/extension.rb +14 -0
  15. data/lib/commonmarker/renderer.rb +1 -127
  16. data/lib/commonmarker/utils.rb +22 -0
  17. data/lib/commonmarker/version.rb +2 -2
  18. data/lib/commonmarker.rb +14 -29
  19. metadata +36 -188
  20. data/Rakefile +0 -109
  21. data/bin/commonmarker +0 -118
  22. data/commonmarker.gemspec +0 -38
  23. data/ext/commonmarker/arena.c +0 -104
  24. data/ext/commonmarker/autolink.c +0 -508
  25. data/ext/commonmarker/autolink.h +0 -8
  26. data/ext/commonmarker/blocks.c +0 -1622
  27. data/ext/commonmarker/buffer.c +0 -278
  28. data/ext/commonmarker/buffer.h +0 -116
  29. data/ext/commonmarker/case_fold_switch.inc +0 -4327
  30. data/ext/commonmarker/chunk.h +0 -135
  31. data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
  32. data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
  33. data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
  34. data/ext/commonmarker/cmark-gfm.h +0 -833
  35. data/ext/commonmarker/cmark-gfm_export.h +0 -42
  36. data/ext/commonmarker/cmark-gfm_version.h +0 -7
  37. data/ext/commonmarker/cmark.c +0 -55
  38. data/ext/commonmarker/cmark_ctype.c +0 -44
  39. data/ext/commonmarker/cmark_ctype.h +0 -33
  40. data/ext/commonmarker/commonmark.c +0 -514
  41. data/ext/commonmarker/commonmarker.c +0 -1308
  42. data/ext/commonmarker/commonmarker.h +0 -16
  43. data/ext/commonmarker/config.h +0 -76
  44. data/ext/commonmarker/core-extensions.c +0 -27
  45. data/ext/commonmarker/entities.inc +0 -2138
  46. data/ext/commonmarker/ext_scanners.c +0 -879
  47. data/ext/commonmarker/ext_scanners.h +0 -24
  48. data/ext/commonmarker/footnotes.c +0 -63
  49. data/ext/commonmarker/footnotes.h +0 -27
  50. data/ext/commonmarker/houdini.h +0 -57
  51. data/ext/commonmarker/houdini_href_e.c +0 -100
  52. data/ext/commonmarker/houdini_html_e.c +0 -66
  53. data/ext/commonmarker/houdini_html_u.c +0 -149
  54. data/ext/commonmarker/html.c +0 -502
  55. data/ext/commonmarker/html.h +0 -27
  56. data/ext/commonmarker/inlines.c +0 -1788
  57. data/ext/commonmarker/inlines.h +0 -29
  58. data/ext/commonmarker/iterator.c +0 -159
  59. data/ext/commonmarker/iterator.h +0 -26
  60. data/ext/commonmarker/latex.c +0 -468
  61. data/ext/commonmarker/linked_list.c +0 -37
  62. data/ext/commonmarker/man.c +0 -274
  63. data/ext/commonmarker/map.c +0 -129
  64. data/ext/commonmarker/map.h +0 -44
  65. data/ext/commonmarker/node.c +0 -1045
  66. data/ext/commonmarker/node.h +0 -167
  67. data/ext/commonmarker/parser.h +0 -59
  68. data/ext/commonmarker/plaintext.c +0 -218
  69. data/ext/commonmarker/plugin.c +0 -36
  70. data/ext/commonmarker/plugin.h +0 -34
  71. data/ext/commonmarker/references.c +0 -43
  72. data/ext/commonmarker/references.h +0 -26
  73. data/ext/commonmarker/registry.c +0 -63
  74. data/ext/commonmarker/registry.h +0 -24
  75. data/ext/commonmarker/render.c +0 -213
  76. data/ext/commonmarker/render.h +0 -62
  77. data/ext/commonmarker/scanners.c +0 -14056
  78. data/ext/commonmarker/scanners.h +0 -70
  79. data/ext/commonmarker/scanners.re +0 -341
  80. data/ext/commonmarker/strikethrough.c +0 -167
  81. data/ext/commonmarker/strikethrough.h +0 -9
  82. data/ext/commonmarker/syntax_extension.c +0 -149
  83. data/ext/commonmarker/syntax_extension.h +0 -34
  84. data/ext/commonmarker/table.c +0 -917
  85. data/ext/commonmarker/table.h +0 -12
  86. data/ext/commonmarker/tagfilter.c +0 -60
  87. data/ext/commonmarker/tagfilter.h +0 -8
  88. data/ext/commonmarker/tasklist.c +0 -156
  89. data/ext/commonmarker/tasklist.h +0 -8
  90. data/ext/commonmarker/utf8.c +0 -317
  91. data/ext/commonmarker/utf8.h +0 -35
  92. data/ext/commonmarker/xml.c +0 -182
  93. data/lib/commonmarker/node/inspect.rb +0 -47
  94. data/lib/commonmarker/node.rb +0 -83
  95. data/lib/commonmarker/renderer/html_renderer.rb +0 -256
@@ -0,0 +1,140 @@
1
+ use std::borrow::Cow;
2
+
3
+ use comrak::ComrakOptions;
4
+
5
+ use magnus::value::ReprValue;
6
+ use magnus::TryConvert;
7
+ use magnus::{class, r_hash::ForEach, Error, RHash, Symbol, Value};
8
+
9
+ use crate::utils::try_convert_string;
10
+
11
+ const PARSE_SMART: &str = "smart";
12
+ const PARSE_DEFAULT_INFO_STRING: &str = "default_info_string";
13
+
14
+ fn iterate_parse_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
15
+ options_hash
16
+ .foreach(|key: Symbol, value: Value| {
17
+ match key.name() {
18
+ Ok(Cow::Borrowed(PARSE_SMART)) => {
19
+ comrak_options.parse.smart = TryConvert::try_convert(value)?;
20
+ }
21
+ Ok(Cow::Borrowed(PARSE_DEFAULT_INFO_STRING)) => {
22
+ comrak_options.parse.default_info_string = try_convert_string(value);
23
+ }
24
+ _ => {}
25
+ }
26
+ Ok(ForEach::Continue)
27
+ })
28
+ .unwrap();
29
+ }
30
+
31
+ const RENDER_HARDBREAKS: &str = "hardbreaks";
32
+ const RENDER_GITHUB_PRE_LANG: &str = "github_pre_lang";
33
+ const RENDER_WIDTH: &str = "width";
34
+ const RENDER_UNSAFE: &str = "unsafe";
35
+ const RENDER_ESCAPE: &str = "escape";
36
+
37
+ fn iterate_render_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
38
+ options_hash
39
+ .foreach(|key: Symbol, value: Value| {
40
+ match key.name() {
41
+ Ok(Cow::Borrowed(RENDER_HARDBREAKS)) => {
42
+ comrak_options.render.hardbreaks = TryConvert::try_convert(value)?;
43
+ }
44
+ Ok(Cow::Borrowed(RENDER_GITHUB_PRE_LANG)) => {
45
+ comrak_options.render.github_pre_lang = TryConvert::try_convert(value)?;
46
+ }
47
+ Ok(Cow::Borrowed(RENDER_WIDTH)) => {
48
+ comrak_options.render.width = TryConvert::try_convert(value)?;
49
+ }
50
+ Ok(Cow::Borrowed(RENDER_UNSAFE)) => {
51
+ comrak_options.render.unsafe_ = TryConvert::try_convert(value)?;
52
+ }
53
+ Ok(Cow::Borrowed(RENDER_ESCAPE)) => {
54
+ comrak_options.render.escape = TryConvert::try_convert(value)?;
55
+ }
56
+ _ => {}
57
+ }
58
+ Ok(ForEach::Continue)
59
+ })
60
+ .unwrap();
61
+ }
62
+
63
+ const EXTENSION_STRIKETHROUGH: &str = "strikethrough";
64
+ const EXTENSION_TAGFILTER: &str = "tagfilter";
65
+ const EXTENSION_TABLE: &str = "table";
66
+ const EXTENSION_AUTOLINK: &str = "autolink";
67
+ const EXTENSION_TASKLIST: &str = "tasklist";
68
+ const EXTENSION_SUPERSCRIPT: &str = "superscript";
69
+ const EXTENSION_HEADER_IDS: &str = "header_ids";
70
+ const EXTENSION_FOOTNOTES: &str = "footnotes";
71
+ const EXTENSION_DESCRIPTION_LISTS: &str = "description_lists";
72
+ const EXTENSION_FRONT_MATTER_DELIMITER: &str = "front_matter_delimiter";
73
+ const EXTENSION_SHORTCODES: &str = "shortcodes";
74
+
75
+ fn iterate_extension_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
76
+ options_hash
77
+ .foreach(|key: Symbol, value: Value| {
78
+ match key.name() {
79
+ Ok(Cow::Borrowed(EXTENSION_STRIKETHROUGH)) => {
80
+ comrak_options.extension.strikethrough = TryConvert::try_convert(value)?;
81
+ }
82
+ Ok(Cow::Borrowed(EXTENSION_TAGFILTER)) => {
83
+ comrak_options.extension.tagfilter = TryConvert::try_convert(value)?;
84
+ }
85
+ Ok(Cow::Borrowed(EXTENSION_TABLE)) => {
86
+ comrak_options.extension.table = TryConvert::try_convert(value)?;
87
+ }
88
+ Ok(Cow::Borrowed(EXTENSION_AUTOLINK)) => {
89
+ comrak_options.extension.autolink = TryConvert::try_convert(value)?;
90
+ }
91
+ Ok(Cow::Borrowed(EXTENSION_TASKLIST)) => {
92
+ comrak_options.extension.tasklist = TryConvert::try_convert(value)?;
93
+ }
94
+ Ok(Cow::Borrowed(EXTENSION_SUPERSCRIPT)) => {
95
+ comrak_options.extension.superscript = TryConvert::try_convert(value)?;
96
+ }
97
+ Ok(Cow::Borrowed(EXTENSION_HEADER_IDS)) => {
98
+ comrak_options.extension.header_ids = try_convert_string(value);
99
+ }
100
+ Ok(Cow::Borrowed(EXTENSION_FOOTNOTES)) => {
101
+ comrak_options.extension.footnotes = TryConvert::try_convert(value)?;
102
+ }
103
+ Ok(Cow::Borrowed(EXTENSION_DESCRIPTION_LISTS)) => {
104
+ comrak_options.extension.description_lists = TryConvert::try_convert(value)?;
105
+ }
106
+ Ok(Cow::Borrowed(EXTENSION_FRONT_MATTER_DELIMITER)) => {
107
+ if let Some(option) = try_convert_string(value) {
108
+ if !option.is_empty() {
109
+ comrak_options.extension.front_matter_delimiter = Some(option);
110
+ }
111
+ }
112
+ }
113
+ Ok(Cow::Borrowed(EXTENSION_SHORTCODES)) => {
114
+ comrak_options.extension.shortcodes = TryConvert::try_convert(value)?;
115
+ }
116
+ _ => {}
117
+ }
118
+ Ok(ForEach::Continue)
119
+ })
120
+ .unwrap();
121
+ }
122
+
123
+ pub fn iterate_options_hash(
124
+ comrak_options: &mut ComrakOptions,
125
+ key: Symbol,
126
+ value: RHash,
127
+ ) -> Result<ForEach, Error> {
128
+ assert!(value.is_kind_of(class::hash()));
129
+
130
+ if key.name().unwrap() == "parse" {
131
+ iterate_parse_options(comrak_options, value);
132
+ }
133
+ if key.name().unwrap() == "render" {
134
+ iterate_render_options(comrak_options, value);
135
+ }
136
+ if key.name().unwrap() == "extension" {
137
+ iterate_extension_options(comrak_options, value);
138
+ }
139
+ Ok(ForEach::Continue)
140
+ }
@@ -0,0 +1,74 @@
1
+ use std::path::PathBuf;
2
+
3
+ use magnus::value::ReprValue;
4
+ use magnus::{RHash, Symbol, TryConvert, Value};
5
+
6
+ use crate::EMPTY_STR;
7
+
8
+ pub const SYNTAX_HIGHLIGHTER_PLUGIN_THEME_KEY: &str = "theme";
9
+ pub const SYNTAX_HIGHLIGHTER_PLUGIN_PATH_KEY: &str = "path";
10
+
11
+ pub fn fetch_syntax_highlighter_theme(value: Value) -> Result<Option<String>, magnus::Error> {
12
+ if value.is_nil() {
13
+ // `syntax_highlighter: nil`
14
+ return Ok(None);
15
+ }
16
+
17
+ let syntax_highlighter_plugin: RHash = match TryConvert::try_convert(value) {
18
+ Ok(plugin) => plugin, // `syntax_highlighter: { theme: "<something>" }`
19
+ Err(e) => {
20
+ // not a hash!
21
+ return Err(e);
22
+ }
23
+ };
24
+
25
+ if syntax_highlighter_plugin.is_nil() || syntax_highlighter_plugin.is_empty() {
26
+ return Err(magnus::Error::new(
27
+ magnus::exception::type_error(),
28
+ "theme cannot be blank hash",
29
+ ));
30
+ }
31
+
32
+ let theme_key = Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN_THEME_KEY);
33
+
34
+ match syntax_highlighter_plugin.get(theme_key) {
35
+ Some(theme) => {
36
+ if theme.is_nil() {
37
+ return Err(magnus::Error::new(
38
+ magnus::exception::type_error(),
39
+ "theme cannot be nil",
40
+ ));
41
+ }
42
+ Ok(TryConvert::try_convert(theme)?)
43
+ }
44
+ None => {
45
+ // `syntax_highlighter: { theme: nil }`
46
+ Ok(None)
47
+ }
48
+ }
49
+ }
50
+
51
+ pub fn fetch_syntax_highlighter_path(value: Value) -> Result<PathBuf, magnus::Error> {
52
+ if value.is_nil() {
53
+ // `syntax_highlighter: nil`
54
+ return Ok(PathBuf::from(EMPTY_STR));
55
+ }
56
+
57
+ let syntax_highlighter_plugin: RHash = TryConvert::try_convert(value)?;
58
+ let path_key = Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN_PATH_KEY);
59
+
60
+ match syntax_highlighter_plugin.get(path_key) {
61
+ Some(path) => {
62
+ if path.is_nil() {
63
+ // `syntax_highlighter: { path: nil }`
64
+ return Ok(PathBuf::from(EMPTY_STR));
65
+ }
66
+ let val: String = TryConvert::try_convert(path)?;
67
+ Ok(PathBuf::from(val))
68
+ }
69
+ None => {
70
+ // `syntax_highlighter: { }`
71
+ Ok(PathBuf::from(EMPTY_STR))
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,3 @@
1
+ pub mod syntax_highlighting;
2
+
3
+ pub const SYNTAX_HIGHLIGHTER_PLUGIN: &str = "syntax_highlighter";
@@ -0,0 +1,8 @@
1
+ use magnus::{TryConvert, Value};
2
+
3
+ pub fn try_convert_string(value: Value) -> Option<String> {
4
+ match TryConvert::try_convert(value) {
5
+ Ok(s) => Some(s),
6
+ Err(_) => None,
7
+ }
8
+ }
@@ -1,54 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module CommonMarker
4
- # For Ruby::Enum, these must be classes, not modules
3
+ module Commonmarker
5
4
  module Config
6
- # See https://github.com/github/cmark-gfm/blob/master/src/cmark-gfm.h#L673
7
- OPTS = {
5
+ # For details, see
6
+ # https://github.com/kivikakk/comrak/blob/162ef9354deb2c9b4a4e05be495aa372ba5bb696/src/main.rs#L201
7
+ OPTIONS = {
8
8
  parse: {
9
- DEFAULT: 0,
10
- SOURCEPOS: (1 << 1),
11
- UNSAFE: (1 << 17),
12
- VALIDATE_UTF8: (1 << 9),
13
- SMART: (1 << 10),
14
- LIBERAL_HTML_TAG: (1 << 12),
15
- FOOTNOTES: (1 << 13),
16
- STRIKETHROUGH_DOUBLE_TILDE: (1 << 14),
9
+ smart: false,
10
+ default_info_string: "",
17
11
  }.freeze,
18
12
  render: {
19
- DEFAULT: 0,
20
- SOURCEPOS: (1 << 1),
21
- HARDBREAKS: (1 << 2),
22
- UNSAFE: (1 << 17),
23
- NOBREAKS: (1 << 4),
24
- VALIDATE_UTF8: (1 << 9),
25
- SMART: (1 << 10),
26
- GITHUB_PRE_LANG: (1 << 11),
27
- LIBERAL_HTML_TAG: (1 << 12),
28
- FOOTNOTES: (1 << 13),
29
- STRIKETHROUGH_DOUBLE_TILDE: (1 << 14),
30
- TABLE_PREFER_STYLE_ATTRIBUTES: (1 << 15),
31
- FULL_INFO_STRING: (1 << 16),
13
+ hardbreaks: true,
14
+ github_pre_lang: true,
15
+ width: 80,
16
+ unsafe: false,
17
+ escape: false,
32
18
  }.freeze,
33
- format: [:html, :xml, :commonmark, :plaintext].freeze,
19
+ extension: {
20
+ strikethrough: true,
21
+ tagfilter: true,
22
+ table: true,
23
+ autolink: true,
24
+ tasklist: true,
25
+ superscript: false,
26
+ header_ids: "",
27
+ footnotes: false,
28
+ description_lists: false,
29
+ front_matter_delimiter: "",
30
+ shortcodes: true,
31
+ },
32
+ format: [:html].freeze,
34
33
  }.freeze
35
34
 
35
+ PLUGINS = {
36
+ syntax_highlighter: {
37
+ theme: "base16-ocean.dark",
38
+ path: "",
39
+ },
40
+ }
41
+
36
42
  class << self
37
- def process_options(option, type)
38
- case option
39
- when Symbol
40
- OPTS.fetch(type).fetch(option)
41
- when Array
42
- raise TypeError if option.none?
43
-
44
- # neckbearding around. the map will both check the opts and then bitwise-OR it
45
- OPTS.fetch(type).fetch_values(*option).inject(0, :|)
46
- else
47
- raise TypeError, "option type must be a valid symbol or array of symbols within the #{name}::OPTS[:#{type}] context"
43
+ include Commonmarker::Utils
44
+
45
+ def merged_with_defaults(options)
46
+ Commonmarker::Config::OPTIONS.merge(process_options(options))
47
+ end
48
+
49
+ def process_options(options)
50
+ {
51
+ parse: process_parse_options(options[:parse]),
52
+ render: process_render_options(options[:render]),
53
+ extension: process_extension_options(options[:extension]),
54
+ }
55
+ end
56
+
57
+ def process_plugins(plugins)
58
+ {
59
+ syntax_highlighter: process_syntax_highlighter_plugin(plugins&.fetch(:syntax_highlighter, nil)),
60
+ }
61
+ end
62
+ end
63
+
64
+ [:parse, :render, :extension].each do |type|
65
+ define_singleton_method :"process_#{type}_options" do |option|
66
+ Commonmarker::Config::OPTIONS[type].each_with_object({}) do |(key, value), hash|
67
+ if option.nil? # option not provided, go for the default
68
+ hash[key] = value
69
+ next
70
+ end
71
+
72
+ # option explicitly not included, remove it
73
+ next if option[key].nil?
74
+
75
+ hash[key] = fetch_kv(option, key, value, type)
48
76
  end
49
- rescue KeyError => e
50
- raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
51
77
  end
52
- end
78
+ end
79
+
80
+ [:syntax_highlighter].each do |type|
81
+ define_singleton_method :"process_#{type}_plugin" do |plugin|
82
+ return if plugin.nil? # plugin explicitly nil, remove it
83
+
84
+ Commonmarker::Config::PLUGINS[type].each_with_object({}) do |(key, value), hash|
85
+ if plugin.nil? # option not provided, go for the default
86
+ hash[key] = value
87
+ next
88
+ end
89
+
90
+ # option explicitly not included, remove it
91
+ next if plugin[key].nil?
92
+
93
+ hash[key] = fetch_kv(plugin, key, value, type)
94
+ end
95
+ end
96
+ end
53
97
  end
54
98
  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
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ # native precompiled gems package shared libraries in <gem_dir>/lib/commonmarker/<ruby_version>
5
+ # load the precompiled extension file
6
+ ruby_version = /\d+\.\d+/.match(RUBY_VERSION)
7
+ require_relative "#{ruby_version}/commonmarker"
8
+ rescue LoadError
9
+ # fall back to the extension compiled upon installation.
10
+ # use "require" instead of "require_relative" because non-native gems will place C extension files
11
+ # in Gem::BasicSpecification#extension_dir after compilation (during normal installation), which
12
+ # is in $LOAD_PATH but not necessarily relative to this file (see nokogiri#2300)
13
+ require "commonmarker/commonmarker"
14
+ end
@@ -3,133 +3,7 @@
3
3
  require "set"
4
4
  require "stringio"
5
5
 
6
- module CommonMarker
6
+ module Commonmarker
7
7
  class Renderer
8
- attr_accessor :in_tight, :warnings, :in_plain
9
-
10
- def initialize(options: :DEFAULT, extensions: [])
11
- @opts = Config.process_options(options, :render)
12
- @stream = StringIO.new(+"")
13
- @need_blocksep = false
14
- @warnings = Set.new([])
15
- @in_tight = false
16
- @in_plain = false
17
- @tagfilter = extensions.include?(:tagfilter)
18
- end
19
-
20
- def out(*args)
21
- args.each do |arg|
22
- case arg
23
- when :children
24
- @node.each { |child| out(child) }
25
- when Array
26
- arg.each { |x| render(x) }
27
- when Node
28
- render(arg)
29
- else
30
- @stream.write(arg)
31
- end
32
- end
33
- end
34
-
35
- def render(node)
36
- @node = node
37
- if node.type == :document
38
- document(node)
39
- @stream.string
40
- elsif @in_plain && node.type != :text && node.type != :softbreak
41
- node.each { |child| render(child) }
42
- else
43
- begin
44
- send(node.type, node)
45
- rescue NoMethodError => e
46
- @warnings.add("WARNING: #{node.type} not implemented.")
47
- raise e
48
- end
49
- end
50
- end
51
-
52
- def document(_node)
53
- out(:children)
54
- end
55
-
56
- def code_block(node)
57
- code_block(node)
58
- end
59
-
60
- def reference_def(_node); end
61
-
62
- def cr
63
- return if @stream.string.empty? || @stream.string[-1] == "\n"
64
-
65
- out("\n")
66
- end
67
-
68
- def blocksep
69
- out("\n")
70
- end
71
-
72
- def containersep
73
- cr unless @in_tight
74
- end
75
-
76
- def block
77
- cr
78
- yield
79
- cr
80
- end
81
-
82
- def container(starter, ender)
83
- out(starter)
84
- yield
85
- out(ender)
86
- end
87
-
88
- def plain
89
- old_in_plain = @in_plain
90
- @in_plain = true
91
- yield
92
- @in_plain = old_in_plain
93
- end
94
-
95
- private
96
-
97
- def escape_href(str)
98
- @node.html_escape_href(str)
99
- end
100
-
101
- def escape_html(str)
102
- @node.html_escape_html(str)
103
- end
104
-
105
- def tagfilter(str)
106
- if @tagfilter
107
- str.gsub(
108
- %r{
109
- <
110
- (
111
- title|textarea|style|xmp|iframe|
112
- noembed|noframes|script|plaintext
113
- )
114
- (?=\s|>|/>)
115
- }xi,
116
- '&lt;\1',
117
- )
118
- else
119
- str
120
- end
121
- end
122
-
123
- def sourcepos(node)
124
- return "" unless option_enabled?(:SOURCEPOS)
125
-
126
- s = node.sourcepos
127
- " data-sourcepos=\"#{s[:start_line]}:#{s[:start_column]}-" \
128
- "#{s[:end_line]}:#{s[:end_column]}\""
129
- end
130
-
131
- def option_enabled?(opt)
132
- (@opts & CommonMarker::Config::OPTS.dig(:render, opt)) != 0
133
- end
134
8
  end
135
9
  end
@@ -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
- module CommonMarker
4
- VERSION = "0.23.10"
3
+ module Commonmarker
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/commonmarker.rb CHANGED
@@ -1,45 +1,30 @@
1
- #!/usr/bin/env ruby
2
1
  # frozen_string_literal: true
3
2
 
4
- require "commonmarker/commonmarker"
3
+ require_relative "commonmarker/extension"
4
+
5
+ require "commonmarker/utils"
5
6
  require "commonmarker/config"
6
- require "commonmarker/node"
7
7
  require "commonmarker/renderer"
8
- require "commonmarker/renderer/html_renderer"
9
8
  require "commonmarker/version"
10
9
 
11
- begin
12
- require "awesome_print"
13
- rescue LoadError; end # rubocop:disable Lint/SuppressedException
14
- module CommonMarker
10
+ module Commonmarker
15
11
  class << self
16
- # Public: Parses a Markdown string into an HTML string.
12
+ # Public: Parses a CommonMark string into an HTML string.
17
13
  #
18
14
  # text - A {String} of text
19
- # option - Either a {Symbol} or {Array of Symbol}s indicating the render options
20
- # extensions - An {Array of Symbol}s indicating the extensions to use
15
+ # options - A {Hash} of render, parse, and extension options to transform the text.
16
+ # plugins - A {Hash} of additional plugins.
21
17
  #
22
18
  # Returns a {String} of converted HTML.
23
- def render_html(text, options = :DEFAULT, extensions = [])
19
+ def to_html(text, options: Commonmarker::Config::OPTIONS, plugins: Commonmarker::Config::PLUGINS)
24
20
  raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
21
+ raise TypeError, "text must be UTF-8 encoded; got #{text.encoding}!" unless text.encoding.name == "UTF-8"
22
+ raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
25
23
 
26
- opts = Config.process_options(options, :render)
27
- Node.markdown_to_html(text.encode("UTF-8"), opts, extensions)
28
- end
24
+ opts = Config.process_options(options)
25
+ plugins = Config.process_plugins(plugins)
29
26
 
30
- # Public: Parses a Markdown string into a `document` node.
31
- #
32
- # string - {String} to be parsed
33
- # option - A {Symbol} or {Array of Symbol}s indicating the parse options
34
- # extensions - An {Array of Symbol}s indicating the extensions to use
35
- #
36
- # Returns the `document` node.
37
- def render_doc(text, options = :DEFAULT, extensions = [])
38
- raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
39
-
40
- opts = Config.process_options(options, :parse)
41
- text = text.encode("UTF-8")
42
- Node.parse_document(text, text.bytesize, opts, extensions)
27
+ commonmark_to_html(text, options: opts, plugins: plugins)
43
28
  end
44
- end
29
+ end
45
30
  end