commonmarker 0.23.10 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1192 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +145 -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 +144 -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 +85 -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 +35 -187
  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,144 @@
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
+ const RENDER_SOURCEPOS: &str = "sourcepos";
37
+
38
+ fn iterate_render_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
39
+ options_hash
40
+ .foreach(|key: Symbol, value: Value| {
41
+ match key.name() {
42
+ Ok(Cow::Borrowed(RENDER_HARDBREAKS)) => {
43
+ comrak_options.render.hardbreaks = TryConvert::try_convert(value)?;
44
+ }
45
+ Ok(Cow::Borrowed(RENDER_GITHUB_PRE_LANG)) => {
46
+ comrak_options.render.github_pre_lang = TryConvert::try_convert(value)?;
47
+ }
48
+ Ok(Cow::Borrowed(RENDER_WIDTH)) => {
49
+ comrak_options.render.width = TryConvert::try_convert(value)?;
50
+ }
51
+ Ok(Cow::Borrowed(RENDER_UNSAFE)) => {
52
+ comrak_options.render.unsafe_ = TryConvert::try_convert(value)?;
53
+ }
54
+ Ok(Cow::Borrowed(RENDER_ESCAPE)) => {
55
+ comrak_options.render.escape = TryConvert::try_convert(value)?;
56
+ }
57
+ Ok(Cow::Borrowed(RENDER_SOURCEPOS)) => {
58
+ comrak_options.render.sourcepos = TryConvert::try_convert(value)?;
59
+ }
60
+ _ => {}
61
+ }
62
+ Ok(ForEach::Continue)
63
+ })
64
+ .unwrap();
65
+ }
66
+
67
+ const EXTENSION_STRIKETHROUGH: &str = "strikethrough";
68
+ const EXTENSION_TAGFILTER: &str = "tagfilter";
69
+ const EXTENSION_TABLE: &str = "table";
70
+ const EXTENSION_AUTOLINK: &str = "autolink";
71
+ const EXTENSION_TASKLIST: &str = "tasklist";
72
+ const EXTENSION_SUPERSCRIPT: &str = "superscript";
73
+ const EXTENSION_HEADER_IDS: &str = "header_ids";
74
+ const EXTENSION_FOOTNOTES: &str = "footnotes";
75
+ const EXTENSION_DESCRIPTION_LISTS: &str = "description_lists";
76
+ const EXTENSION_FRONT_MATTER_DELIMITER: &str = "front_matter_delimiter";
77
+ const EXTENSION_SHORTCODES: &str = "shortcodes";
78
+
79
+ fn iterate_extension_options(comrak_options: &mut ComrakOptions, options_hash: RHash) {
80
+ options_hash
81
+ .foreach(|key: Symbol, value: Value| {
82
+ match key.name() {
83
+ Ok(Cow::Borrowed(EXTENSION_STRIKETHROUGH)) => {
84
+ comrak_options.extension.strikethrough = TryConvert::try_convert(value)?;
85
+ }
86
+ Ok(Cow::Borrowed(EXTENSION_TAGFILTER)) => {
87
+ comrak_options.extension.tagfilter = TryConvert::try_convert(value)?;
88
+ }
89
+ Ok(Cow::Borrowed(EXTENSION_TABLE)) => {
90
+ comrak_options.extension.table = TryConvert::try_convert(value)?;
91
+ }
92
+ Ok(Cow::Borrowed(EXTENSION_AUTOLINK)) => {
93
+ comrak_options.extension.autolink = TryConvert::try_convert(value)?;
94
+ }
95
+ Ok(Cow::Borrowed(EXTENSION_TASKLIST)) => {
96
+ comrak_options.extension.tasklist = TryConvert::try_convert(value)?;
97
+ }
98
+ Ok(Cow::Borrowed(EXTENSION_SUPERSCRIPT)) => {
99
+ comrak_options.extension.superscript = TryConvert::try_convert(value)?;
100
+ }
101
+ Ok(Cow::Borrowed(EXTENSION_HEADER_IDS)) => {
102
+ comrak_options.extension.header_ids = try_convert_string(value);
103
+ }
104
+ Ok(Cow::Borrowed(EXTENSION_FOOTNOTES)) => {
105
+ comrak_options.extension.footnotes = TryConvert::try_convert(value)?;
106
+ }
107
+ Ok(Cow::Borrowed(EXTENSION_DESCRIPTION_LISTS)) => {
108
+ comrak_options.extension.description_lists = TryConvert::try_convert(value)?;
109
+ }
110
+ Ok(Cow::Borrowed(EXTENSION_FRONT_MATTER_DELIMITER)) => {
111
+ if let Some(option) = try_convert_string(value) {
112
+ if !option.is_empty() {
113
+ comrak_options.extension.front_matter_delimiter = Some(option);
114
+ }
115
+ }
116
+ }
117
+ Ok(Cow::Borrowed(EXTENSION_SHORTCODES)) => {
118
+ comrak_options.extension.shortcodes = TryConvert::try_convert(value)?;
119
+ }
120
+ _ => {}
121
+ }
122
+ Ok(ForEach::Continue)
123
+ })
124
+ .unwrap();
125
+ }
126
+
127
+ pub fn iterate_options_hash(
128
+ comrak_options: &mut ComrakOptions,
129
+ key: Symbol,
130
+ value: RHash,
131
+ ) -> Result<ForEach, Error> {
132
+ assert!(value.is_kind_of(class::hash()));
133
+
134
+ if key.name().unwrap() == "parse" {
135
+ iterate_parse_options(comrak_options, value);
136
+ }
137
+ if key.name().unwrap() == "render" {
138
+ iterate_render_options(comrak_options, value);
139
+ }
140
+ if key.name().unwrap() == "extension" {
141
+ iterate_extension_options(comrak_options, value);
142
+ }
143
+ Ok(ForEach::Continue)
144
+ }
@@ -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,99 @@
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,
18
+ sourcepos: false,
32
19
  }.freeze,
33
- format: [:html, :xml, :commonmark, :plaintext].freeze,
20
+ extension: {
21
+ strikethrough: true,
22
+ tagfilter: true,
23
+ table: true,
24
+ autolink: true,
25
+ tasklist: true,
26
+ superscript: false,
27
+ header_ids: "",
28
+ footnotes: false,
29
+ description_lists: false,
30
+ front_matter_delimiter: "",
31
+ shortcodes: true,
32
+ },
33
+ format: [:html].freeze,
34
34
  }.freeze
35
35
 
36
+ PLUGINS = {
37
+ syntax_highlighter: {
38
+ theme: "base16-ocean.dark",
39
+ path: "",
40
+ },
41
+ }
42
+
36
43
  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"
44
+ include Commonmarker::Utils
45
+
46
+ def merged_with_defaults(options)
47
+ Commonmarker::Config::OPTIONS.merge(process_options(options))
48
+ end
49
+
50
+ def process_options(options)
51
+ {
52
+ parse: process_parse_options(options[:parse]),
53
+ render: process_render_options(options[:render]),
54
+ extension: process_extension_options(options[:extension]),
55
+ }
56
+ end
57
+
58
+ def process_plugins(plugins)
59
+ {
60
+ syntax_highlighter: process_syntax_highlighter_plugin(plugins&.fetch(:syntax_highlighter, nil)),
61
+ }
62
+ end
63
+ end
64
+
65
+ [:parse, :render, :extension].each do |type|
66
+ define_singleton_method :"process_#{type}_options" do |option|
67
+ Commonmarker::Config::OPTIONS[type].each_with_object({}) do |(key, value), hash|
68
+ if option.nil? # option not provided, go for the default
69
+ hash[key] = value
70
+ next
71
+ end
72
+
73
+ # option explicitly not included, remove it
74
+ next if option[key].nil?
75
+
76
+ hash[key] = fetch_kv(option, key, value, type)
48
77
  end
49
- rescue KeyError => e
50
- raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
51
78
  end
52
- end
79
+ end
80
+
81
+ [:syntax_highlighter].each do |type|
82
+ define_singleton_method :"process_#{type}_plugin" do |plugin|
83
+ return if plugin.nil? # plugin explicitly nil, remove it
84
+
85
+ Commonmarker::Config::PLUGINS[type].each_with_object({}) do |(key, value), hash|
86
+ if plugin.nil? # option not provided, go for the default
87
+ hash[key] = value
88
+ next
89
+ end
90
+
91
+ # option explicitly not included, remove it
92
+ next if plugin[key].nil?
93
+
94
+ hash[key] = fetch_kv(plugin, key, value, type)
95
+ end
96
+ end
97
+ end
53
98
  end
54
99
  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.3"
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