commonmarker 0.23.10 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1221 -0
  3. data/Cargo.toml +7 -0
  4. data/README.md +233 -172
  5. data/ext/commonmarker/Cargo.toml +20 -0
  6. data/ext/commonmarker/extconf.rb +3 -6
  7. data/ext/commonmarker/src/lib.rs +103 -0
  8. data/ext/commonmarker/src/node.rs +1160 -0
  9. data/ext/commonmarker/src/options.rs +216 -0
  10. data/ext/commonmarker/src/plugins/syntax_highlighting.rs +166 -0
  11. data/ext/commonmarker/src/plugins.rs +6 -0
  12. data/ext/commonmarker/src/utils.rs +8 -0
  13. data/lib/commonmarker/config.rb +91 -40
  14. data/lib/commonmarker/constants.rb +7 -0
  15. data/lib/commonmarker/extension.rb +14 -0
  16. data/lib/commonmarker/node/ast.rb +8 -0
  17. data/lib/commonmarker/node/inspect.rb +14 -4
  18. data/lib/commonmarker/node.rb +29 -47
  19. data/lib/commonmarker/renderer.rb +1 -127
  20. data/lib/commonmarker/utils.rb +22 -0
  21. data/lib/commonmarker/version.rb +2 -2
  22. data/lib/commonmarker.rb +27 -25
  23. metadata +38 -186
  24. data/Rakefile +0 -109
  25. data/bin/commonmarker +0 -118
  26. data/commonmarker.gemspec +0 -38
  27. data/ext/commonmarker/arena.c +0 -104
  28. data/ext/commonmarker/autolink.c +0 -508
  29. data/ext/commonmarker/autolink.h +0 -8
  30. data/ext/commonmarker/blocks.c +0 -1622
  31. data/ext/commonmarker/buffer.c +0 -278
  32. data/ext/commonmarker/buffer.h +0 -116
  33. data/ext/commonmarker/case_fold_switch.inc +0 -4327
  34. data/ext/commonmarker/chunk.h +0 -135
  35. data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
  36. data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
  37. data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
  38. data/ext/commonmarker/cmark-gfm.h +0 -833
  39. data/ext/commonmarker/cmark-gfm_export.h +0 -42
  40. data/ext/commonmarker/cmark-gfm_version.h +0 -7
  41. data/ext/commonmarker/cmark.c +0 -55
  42. data/ext/commonmarker/cmark_ctype.c +0 -44
  43. data/ext/commonmarker/cmark_ctype.h +0 -33
  44. data/ext/commonmarker/commonmark.c +0 -514
  45. data/ext/commonmarker/commonmarker.c +0 -1308
  46. data/ext/commonmarker/commonmarker.h +0 -16
  47. data/ext/commonmarker/config.h +0 -76
  48. data/ext/commonmarker/core-extensions.c +0 -27
  49. data/ext/commonmarker/entities.inc +0 -2138
  50. data/ext/commonmarker/ext_scanners.c +0 -879
  51. data/ext/commonmarker/ext_scanners.h +0 -24
  52. data/ext/commonmarker/footnotes.c +0 -63
  53. data/ext/commonmarker/footnotes.h +0 -27
  54. data/ext/commonmarker/houdini.h +0 -57
  55. data/ext/commonmarker/houdini_href_e.c +0 -100
  56. data/ext/commonmarker/houdini_html_e.c +0 -66
  57. data/ext/commonmarker/houdini_html_u.c +0 -149
  58. data/ext/commonmarker/html.c +0 -502
  59. data/ext/commonmarker/html.h +0 -27
  60. data/ext/commonmarker/inlines.c +0 -1788
  61. data/ext/commonmarker/inlines.h +0 -29
  62. data/ext/commonmarker/iterator.c +0 -159
  63. data/ext/commonmarker/iterator.h +0 -26
  64. data/ext/commonmarker/latex.c +0 -468
  65. data/ext/commonmarker/linked_list.c +0 -37
  66. data/ext/commonmarker/man.c +0 -274
  67. data/ext/commonmarker/map.c +0 -129
  68. data/ext/commonmarker/map.h +0 -44
  69. data/ext/commonmarker/node.c +0 -1045
  70. data/ext/commonmarker/node.h +0 -167
  71. data/ext/commonmarker/parser.h +0 -59
  72. data/ext/commonmarker/plaintext.c +0 -218
  73. data/ext/commonmarker/plugin.c +0 -36
  74. data/ext/commonmarker/plugin.h +0 -34
  75. data/ext/commonmarker/references.c +0 -43
  76. data/ext/commonmarker/references.h +0 -26
  77. data/ext/commonmarker/registry.c +0 -63
  78. data/ext/commonmarker/registry.h +0 -24
  79. data/ext/commonmarker/render.c +0 -213
  80. data/ext/commonmarker/render.h +0 -62
  81. data/ext/commonmarker/scanners.c +0 -14056
  82. data/ext/commonmarker/scanners.h +0 -70
  83. data/ext/commonmarker/scanners.re +0 -341
  84. data/ext/commonmarker/strikethrough.c +0 -167
  85. data/ext/commonmarker/strikethrough.h +0 -9
  86. data/ext/commonmarker/syntax_extension.c +0 -149
  87. data/ext/commonmarker/syntax_extension.h +0 -34
  88. data/ext/commonmarker/table.c +0 -917
  89. data/ext/commonmarker/table.h +0 -12
  90. data/ext/commonmarker/tagfilter.c +0 -60
  91. data/ext/commonmarker/tagfilter.h +0 -8
  92. data/ext/commonmarker/tasklist.c +0 -156
  93. data/ext/commonmarker/tasklist.h +0 -8
  94. data/ext/commonmarker/utf8.c +0 -317
  95. data/ext/commonmarker/utf8.h +0 -35
  96. data/ext/commonmarker/xml.c +0 -182
  97. data/lib/commonmarker/renderer/html_renderer.rb +0 -256
@@ -0,0 +1,1160 @@
1
+ use comrak::arena_tree::Node as ComrakNode;
2
+ use comrak::nodes::{
3
+ Ast as ComrakAst, AstNode as ComrakAstNode, ListDelimType, ListType, NodeCode, NodeCodeBlock,
4
+ NodeDescriptionItem, NodeFootnoteDefinition, NodeFootnoteReference, NodeHeading, NodeHtmlBlock,
5
+ NodeLink, NodeList, NodeMath, NodeMultilineBlockQuote, NodeShortCode, NodeTable,
6
+ NodeValue as ComrakNodeValue, NodeWikiLink, TableAlignment,
7
+ };
8
+ use magnus::RArray;
9
+ use magnus::{function, method, scan_args, Module, Object, RHash, RModule, Symbol, Value};
10
+ use rctree::Node;
11
+ use typed_arena::Arena;
12
+
13
+ use std::cell::RefCell;
14
+
15
+ use crate::format_options;
16
+
17
+ use crate::plugins::syntax_highlighting::construct_syntax_highlighter_from_plugin;
18
+
19
+ #[derive(Debug, Clone)]
20
+ #[magnus::wrap(class = "Commonmarker::Node::Ast", size, mark)]
21
+ pub struct CommonmarkerAst {
22
+ data: ComrakAst,
23
+ }
24
+
25
+ #[derive(Debug, Clone)]
26
+ #[magnus::wrap(class = "Commonmarker::Node", size, mark)]
27
+ pub struct CommonmarkerNode {
28
+ inner: Node<CommonmarkerAst>,
29
+ }
30
+
31
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
32
+ unsafe impl Send for CommonmarkerNode {}
33
+
34
+ impl CommonmarkerNode {
35
+ pub fn new(args: &[Value]) -> Result<Self, magnus::Error> {
36
+ let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
37
+ let (node_type,): (Symbol,) = args.required;
38
+
39
+ let node = match node_type.to_string().as_str() {
40
+ "document" => ComrakNodeValue::Document,
41
+ "block_quote" => ComrakNodeValue::BlockQuote,
42
+ "footnote_definition" => {
43
+ let kwargs = scan_args::get_kwargs::<_, (String,), (Option<u32>,), ()>(
44
+ args.keywords,
45
+ &["name"],
46
+ &["total_references"],
47
+ )?;
48
+ let (name,) = kwargs.required;
49
+ let (total_reference,) = kwargs.optional;
50
+
51
+ ComrakNodeValue::FootnoteDefinition(NodeFootnoteDefinition {
52
+ // The name of the footnote.
53
+ name,
54
+ // Total number of references to this footnote
55
+ total_references: total_reference.unwrap_or(1),
56
+ })
57
+ }
58
+ "list" => {
59
+ let kwargs = scan_args::get_kwargs::<
60
+ _,
61
+ (Symbol,),
62
+ (
63
+ Option<usize>,
64
+ Option<usize>,
65
+ Option<usize>,
66
+ Option<String>,
67
+ Option<u8>,
68
+ Option<bool>,
69
+ Option<bool>,
70
+ ),
71
+ (),
72
+ >(
73
+ args.keywords,
74
+ &["type"],
75
+ &[
76
+ "marker_offset",
77
+ "padding",
78
+ "start",
79
+ "delimiter",
80
+ "bullet_char",
81
+ "tight",
82
+ "task_list",
83
+ ],
84
+ )?;
85
+
86
+ let (list_type,) = kwargs.required;
87
+ let (marker_offset, padding, start, delimiter, bullet_char, tight, task_list) =
88
+ kwargs.optional;
89
+
90
+ let commonmark_list_type = list_type.to_string();
91
+
92
+ if commonmark_list_type != "bullet" && commonmark_list_type != "ordered" {
93
+ return Err(magnus::Error::new(
94
+ magnus::exception::arg_error(),
95
+ "list type must be `bullet` or `ordered`",
96
+ ));
97
+ }
98
+
99
+ let comrak_list_type = if commonmark_list_type == "ordered" {
100
+ ListType::Ordered
101
+ } else {
102
+ ListType::Bullet
103
+ };
104
+
105
+ let comrak_delimiter = match delimiter.unwrap_or("".to_string()).as_str() {
106
+ ")" => ListDelimType::Paren,
107
+ _ => ListDelimType::Period,
108
+ };
109
+
110
+ ComrakNodeValue::List(NodeList {
111
+ // The kind of list (bullet (unordered) or ordered).
112
+ list_type: comrak_list_type,
113
+ // Number of spaces before the list marker.
114
+ marker_offset: marker_offset.unwrap_or(0),
115
+ // Number of characters between the start of the list marker and the item text (including the list marker(s)).
116
+ padding: padding.unwrap_or(0),
117
+ // For ordered lists, the ordinal the list starts at.
118
+ start: start.unwrap_or(0),
119
+ // For ordered lists, the delimiter after each number.
120
+ delimiter: comrak_delimiter,
121
+ // For bullet lists, the character used for each bullet.
122
+ bullet_char: bullet_char.unwrap_or(0),
123
+ // Whether the list is [tight](https://github.github.com/gfm/#tight), i.e. whether the
124
+ // paragraphs are wrapped in `<p>` tags when formatted as HTML.
125
+ tight: tight.unwrap_or(false),
126
+ is_task_list: task_list.unwrap_or(false),
127
+ })
128
+ }
129
+ "description_list" => ComrakNodeValue::DescriptionList,
130
+ "description_item" => {
131
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<usize>, Option<usize>), ()>(
132
+ args.keywords,
133
+ &[],
134
+ &["marker_offset", "padding"],
135
+ )?;
136
+
137
+ let (marker_offset, padding) = kwargs.optional;
138
+
139
+ ComrakNodeValue::DescriptionItem(NodeDescriptionItem {
140
+ // Number of spaces before the list marker.
141
+ marker_offset: marker_offset.unwrap_or(0),
142
+ // Number of characters between the start of the list marker and the item text (including the list marker(s)).
143
+ padding: padding.unwrap_or(0),
144
+ })
145
+ }
146
+ "description_term" => ComrakNodeValue::DescriptionTerm,
147
+ "description_details" => ComrakNodeValue::DescriptionDetails,
148
+ "code_block" => {
149
+ let kwargs = scan_args::get_kwargs::<
150
+ _,
151
+ (bool,),
152
+ (
153
+ Option<u8>,
154
+ Option<usize>,
155
+ Option<usize>,
156
+ Option<String>,
157
+ Option<String>,
158
+ ),
159
+ (),
160
+ >(
161
+ args.keywords,
162
+ &["fenced"],
163
+ &[
164
+ "fence_char",
165
+ "fence_length",
166
+ "fence_offset",
167
+ "info",
168
+ "literal",
169
+ ],
170
+ )?;
171
+ let (fenced,) = kwargs.required;
172
+ let (fence_char, fence_length, fence_offset, info, literal) = kwargs.optional;
173
+
174
+ ComrakNodeValue::CodeBlock(NodeCodeBlock {
175
+ // Whether the code block is fenced.
176
+ fenced,
177
+ // For fenced code blocks, the fence character itself (`` ` `` or `~`).
178
+ fence_char: fence_char.unwrap_or(b'`'),
179
+ // For fenced code blocks, the length of the fence.
180
+ fence_length: fence_length.unwrap_or(0),
181
+ // For fenced code blocks, the indentation level of the code within the block.
182
+ fence_offset: fence_offset.unwrap_or(0),
183
+
184
+ // For fenced code blocks, the [info string](https://github.github.com/gfm/#info-string) after
185
+ // the opening fence, if any.
186
+ info: info.unwrap_or(String::with_capacity(10)),
187
+
188
+ // The literal contents of the code block. As the contents are not interpreted as Markdown at
189
+ // all, they are contained within this structure, rather than inserted into a child inline of
190
+ // any kind.
191
+ literal: literal.unwrap_or(String::new()),
192
+ })
193
+ }
194
+ "html_block" => {
195
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<u8>, Option<String>), ()>(
196
+ args.keywords,
197
+ &[],
198
+ &["block_type", "literal"],
199
+ )?;
200
+
201
+ let (block_type, literal) = kwargs.optional;
202
+
203
+ ComrakNodeValue::HtmlBlock(NodeHtmlBlock {
204
+ // Number of spaces before the list marker.
205
+ block_type: block_type.unwrap_or(0),
206
+ // Number of characters between the start of the list marker and the item text (including the list marker(s)).
207
+ literal: literal.unwrap_or(String::new()),
208
+ })
209
+ }
210
+ "paragraph" => ComrakNodeValue::Paragraph,
211
+ "heading" => {
212
+ let kwargs = scan_args::get_kwargs::<_, (u8,), (Option<bool>,), ()>(
213
+ args.keywords,
214
+ &["level"],
215
+ &["setext"],
216
+ )?;
217
+
218
+ let (level,) = kwargs.required;
219
+ let (setext,) = kwargs.optional;
220
+
221
+ ComrakNodeValue::Heading(NodeHeading {
222
+ // Number of spaces before the list marker.
223
+ level,
224
+ // Number of characters between the start of the list marker and the item text (including the list marker(s)).
225
+ setext: setext.unwrap_or(false),
226
+ })
227
+ }
228
+ "thematic_break" => ComrakNodeValue::ThematicBreak,
229
+ "table" => {
230
+ let kwargs = scan_args::get_kwargs::<_, (RArray, usize, usize, usize), (), ()>(
231
+ args.keywords,
232
+ &[
233
+ "alignments",
234
+ "num_columns",
235
+ "num_rows",
236
+ "num_nonempty_cells",
237
+ ],
238
+ &[],
239
+ )?;
240
+
241
+ let (alignments, num_columns, num_rows, num_nonempty_cells) = kwargs.required;
242
+
243
+ let mut comrak_alignments = vec![];
244
+ alignments
245
+ .into_iter()
246
+ .for_each(|alignment| match alignment.to_string().as_str() {
247
+ "left" => {
248
+ comrak_alignments.push(TableAlignment::Left);
249
+ }
250
+ "right" => {
251
+ comrak_alignments.push(TableAlignment::Right);
252
+ }
253
+ "center" => {
254
+ comrak_alignments.push(TableAlignment::Center);
255
+ }
256
+ _ => {
257
+ comrak_alignments.push(TableAlignment::None);
258
+ }
259
+ });
260
+ ComrakNodeValue::Table(NodeTable {
261
+ // The table alignments
262
+ alignments: comrak_alignments,
263
+
264
+ // Number of columns of the table
265
+ num_columns,
266
+
267
+ // Number of rows of the table
268
+ num_rows,
269
+
270
+ // Number of non-empty, non-autocompleted cells
271
+ num_nonempty_cells,
272
+ })
273
+ }
274
+ "table_row" => {
275
+ let kwargs =
276
+ scan_args::get_kwargs::<_, (bool,), (), ()>(args.keywords, &["header"], &[])?;
277
+
278
+ let (header,) = kwargs.required;
279
+
280
+ ComrakNodeValue::TableRow(header)
281
+ }
282
+ "table_cell" => ComrakNodeValue::TableCell,
283
+ "text" => {
284
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<String>,), ()>(
285
+ args.keywords,
286
+ &[],
287
+ &["content"],
288
+ )?;
289
+
290
+ let (content,) = kwargs.optional;
291
+
292
+ ComrakNodeValue::Text(content.unwrap_or("".to_string()))
293
+ }
294
+ "taskitem" => {
295
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<char>,), ()>(
296
+ args.keywords,
297
+ &[],
298
+ &["mark"],
299
+ )?;
300
+
301
+ let (mark,) = kwargs.optional;
302
+
303
+ ComrakNodeValue::TaskItem(mark)
304
+ }
305
+ "softbreak" => ComrakNodeValue::SoftBreak,
306
+ "linebreak" => ComrakNodeValue::LineBreak,
307
+ "code" => {
308
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<usize>, Option<String>), ()>(
309
+ args.keywords,
310
+ &[],
311
+ &["num_backticks", "literal"],
312
+ )?;
313
+
314
+ let (num_backticks, literal) = kwargs.optional;
315
+
316
+ ComrakNodeValue::Code(NodeCode {
317
+ // The number of backticks
318
+ num_backticks: num_backticks.unwrap_or(1),
319
+ // The content of the inline code span.
320
+ // As the contents are not interpreted as Markdown at all,
321
+ // they are contained within this structure,
322
+ // rather than inserted into a child inline of any kind
323
+ literal: literal.unwrap_or_default(),
324
+ })
325
+ }
326
+ "html_inline" => {
327
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<String>,), ()>(
328
+ args.keywords,
329
+ &[],
330
+ &["content"],
331
+ )?;
332
+
333
+ let (content,) = kwargs.optional;
334
+
335
+ ComrakNodeValue::HtmlInline(content.unwrap_or_default())
336
+ }
337
+ "emph" => ComrakNodeValue::Emph,
338
+ "strong" => ComrakNodeValue::Strong,
339
+ "strikethrough" => ComrakNodeValue::Strikethrough,
340
+ "superscript" => ComrakNodeValue::Superscript,
341
+ "subscript" => ComrakNodeValue::Subscript,
342
+ "link" => {
343
+ let kwargs = scan_args::get_kwargs::<_, (String,), (Option<String>,), ()>(
344
+ args.keywords,
345
+ &["url"],
346
+ &["title"],
347
+ )?;
348
+
349
+ let (url,) = kwargs.required;
350
+ let (title,) = kwargs.optional;
351
+
352
+ ComrakNodeValue::Link(NodeLink {
353
+ // The URL for the link destination or image source.
354
+ url,
355
+ // The title for the link or image.
356
+ //
357
+ // Note this field is used for the `title` attribute by the HTML formatter even for images;
358
+ // `alt` text is supplied in the image inline text.
359
+ title: title.unwrap_or_default(),
360
+ })
361
+ }
362
+ "image" => {
363
+ let kwargs = scan_args::get_kwargs::<_, (String,), (Option<String>,), ()>(
364
+ args.keywords,
365
+ &["url"],
366
+ &["title"],
367
+ )?;
368
+
369
+ let (url,) = kwargs.required;
370
+ let (title,) = kwargs.optional;
371
+
372
+ ComrakNodeValue::Image(NodeLink {
373
+ // The URL for the link destination or image source.
374
+ url,
375
+ // The title for the link or image.
376
+ //
377
+ // Note this field is used for the `title` attribute by the HTML formatter even for images;
378
+ // `alt` text is supplied in the image inline text.
379
+ title: title.unwrap_or_default(),
380
+ })
381
+ }
382
+ "footnote_reference" => {
383
+ let kwargs = scan_args::get_kwargs::<_, (String,), (Option<u32>, Option<u32>), ()>(
384
+ args.keywords,
385
+ &["name"],
386
+ &["ref_num", "ix"],
387
+ )?;
388
+
389
+ let (name,) = kwargs.required;
390
+ let (ref_num, ix) = kwargs.optional;
391
+
392
+ ComrakNodeValue::FootnoteReference(NodeFootnoteReference {
393
+ // The name of the footnote.
394
+ name,
395
+ // The index of reference to the same footnote
396
+ ref_num: ref_num.unwrap_or(0),
397
+ // The index of the footnote in the document.
398
+ ix: ix.unwrap_or(0),
399
+ })
400
+ }
401
+ // #[cfg(feature = "shortcodes")]
402
+ "shortcode" => {
403
+ let kwargs =
404
+ scan_args::get_kwargs::<_, (String,), (), ()>(args.keywords, &["code"], &[])?;
405
+
406
+ let (code,) = kwargs.required;
407
+
408
+ match NodeShortCode::resolve(code.as_str()) {
409
+ Some(shortcode) => ComrakNodeValue::ShortCode(shortcode),
410
+ None => {
411
+ return Err(magnus::Error::new(
412
+ magnus::exception::arg_error(),
413
+ "could not resolve shortcode",
414
+ ));
415
+ }
416
+ }
417
+ }
418
+ "math" => {
419
+ let kwargs = scan_args::get_kwargs::<_, (bool, bool, String), (), ()>(
420
+ args.keywords,
421
+ &["dollar_math", "display_math", "literal"],
422
+ &[],
423
+ )?;
424
+
425
+ let (dollar_math, display_math, literal) = kwargs.required;
426
+
427
+ ComrakNodeValue::Math(NodeMath {
428
+ // Whether this is dollar math (`$` or `$$`).
429
+ // `false` indicates it is code math
430
+ dollar_math,
431
+
432
+ // Whether this is display math (using `$$`)
433
+ display_math,
434
+
435
+ // The literal contents of the math span.
436
+ // As the contents are not interpreted as Markdown at all,
437
+ // they are contained within this structure,
438
+ // rather than inserted into a child inline of any kind.
439
+ literal,
440
+ })
441
+ }
442
+ "multiline_block_quote" => {
443
+ let kwargs = scan_args::get_kwargs::<_, (usize, usize), (), ()>(
444
+ args.keywords,
445
+ &["fence_length", "fence_offset"],
446
+ &[],
447
+ )?;
448
+
449
+ let (fence_length, fence_offset) = kwargs.required;
450
+
451
+ ComrakNodeValue::MultilineBlockQuote(NodeMultilineBlockQuote {
452
+ // The length of the fence.
453
+ fence_length,
454
+ // The indentation level of the fence marker.
455
+ fence_offset,
456
+ })
457
+ }
458
+
459
+ "escaped" => ComrakNodeValue::Escaped,
460
+
461
+ "wikilink" => {
462
+ let kwargs =
463
+ scan_args::get_kwargs::<_, (String,), (), ()>(args.keywords, &["url"], &[])?;
464
+
465
+ let (url,) = kwargs.required;
466
+
467
+ ComrakNodeValue::WikiLink(NodeWikiLink { url })
468
+ }
469
+
470
+ _ => panic!("unknown node type {}", node_type),
471
+ };
472
+
473
+ Ok(CommonmarkerNode {
474
+ inner: Node::new(CommonmarkerAst {
475
+ data: ComrakAst::new(node, (0, 0).into()),
476
+ }),
477
+ })
478
+ }
479
+
480
+ pub fn new_from_comrak_node<'a>(
481
+ comrak_root_node: &'a ComrakAstNode<'a>,
482
+ ) -> Result<CommonmarkerNode, magnus::Error> {
483
+ let comrak_ast = comrak_root_node.data.clone().into_inner();
484
+
485
+ fn iter_nodes<'a>(comrak_node: &'a ComrakAstNode<'a>) -> CommonmarkerNode {
486
+ let comrak_node_ast = comrak_node.data.clone().into_inner();
487
+ let commonmark_node = CommonmarkerNode {
488
+ inner: Node::new(CommonmarkerAst {
489
+ data: comrak_node_ast,
490
+ }),
491
+ };
492
+
493
+ for c in comrak_node.children() {
494
+ match commonmark_node.append_child_node(&iter_nodes(c)) {
495
+ Ok(_) => {}
496
+ Err(e) => {
497
+ panic!("cannot append node: {}", e);
498
+ }
499
+ }
500
+ }
501
+
502
+ commonmark_node
503
+ }
504
+
505
+ let commonmarker_root_node = CommonmarkerNode {
506
+ inner: Node::new(CommonmarkerAst { data: comrak_ast }),
507
+ };
508
+
509
+ for child in comrak_root_node.children() {
510
+ let new_child = iter_nodes(child);
511
+
512
+ commonmarker_root_node.append_child_node(&new_child)?;
513
+ }
514
+
515
+ Ok(commonmarker_root_node)
516
+ }
517
+
518
+ fn type_to_symbol(&self) -> Symbol {
519
+ let node = self.inner.borrow();
520
+ match node.data.value {
521
+ ComrakNodeValue::Document => Symbol::new("document"),
522
+ ComrakNodeValue::BlockQuote => Symbol::new("block_quote"),
523
+ ComrakNodeValue::FootnoteDefinition(_) => Symbol::new("footnote_definition"),
524
+ ComrakNodeValue::List(..) => Symbol::new("list"),
525
+ ComrakNodeValue::DescriptionList => Symbol::new("description_list"),
526
+ ComrakNodeValue::DescriptionItem(_) => Symbol::new("description_item"),
527
+ ComrakNodeValue::DescriptionTerm => Symbol::new("description_term"),
528
+ ComrakNodeValue::DescriptionDetails => Symbol::new("description_details"),
529
+ ComrakNodeValue::Item(..) => Symbol::new("item"),
530
+ ComrakNodeValue::CodeBlock(..) => Symbol::new("code_block"),
531
+ ComrakNodeValue::HtmlBlock(..) => Symbol::new("html_block"),
532
+ ComrakNodeValue::Paragraph => Symbol::new("paragraph"),
533
+ ComrakNodeValue::Heading(..) => Symbol::new("heading"),
534
+ ComrakNodeValue::ThematicBreak => Symbol::new("thematic_break"),
535
+ ComrakNodeValue::Table(..) => Symbol::new("table"),
536
+ ComrakNodeValue::TableRow(..) => Symbol::new("table_row"),
537
+ ComrakNodeValue::TableCell => Symbol::new("table_cell"),
538
+ ComrakNodeValue::Text(..) => Symbol::new("text"),
539
+ ComrakNodeValue::SoftBreak => Symbol::new("softbreak"),
540
+ ComrakNodeValue::LineBreak => Symbol::new("linebreak"),
541
+ ComrakNodeValue::Image(..) => Symbol::new("image"),
542
+ ComrakNodeValue::Link(..) => Symbol::new("link"),
543
+ ComrakNodeValue::Emph => Symbol::new("emph"),
544
+ ComrakNodeValue::Strong => Symbol::new("strong"),
545
+ ComrakNodeValue::Code(..) => Symbol::new("code"),
546
+ ComrakNodeValue::HtmlInline(..) => Symbol::new("html_inline"),
547
+ ComrakNodeValue::Strikethrough => Symbol::new("strikethrough"),
548
+ ComrakNodeValue::FrontMatter(_) => Symbol::new("frontmatter"),
549
+ ComrakNodeValue::TaskItem { .. } => Symbol::new("taskitem"),
550
+ ComrakNodeValue::Superscript => Symbol::new("superscript"),
551
+ ComrakNodeValue::FootnoteReference(..) => Symbol::new("footnote_reference"),
552
+ ComrakNodeValue::ShortCode(_) => Symbol::new("shortcode"),
553
+ ComrakNodeValue::MultilineBlockQuote(_) => Symbol::new("multiline_block_quote"),
554
+ ComrakNodeValue::Escaped => Symbol::new("escaped"),
555
+ ComrakNodeValue::Math(..) => Symbol::new("math"),
556
+ ComrakNodeValue::WikiLink(..) => Symbol::new("wikilink"),
557
+ ComrakNodeValue::Underline => Symbol::new("underline"),
558
+ ComrakNodeValue::Subscript => Symbol::new("subscript"),
559
+ ComrakNodeValue::SpoileredText => Symbol::new("spoilered_text"),
560
+ ComrakNodeValue::EscapedTag(_) => Symbol::new("escaped_tag"),
561
+ }
562
+ }
563
+
564
+ fn get_parent(&self) -> Option<CommonmarkerNode> {
565
+ self.inner.parent().map(|n| CommonmarkerNode { inner: n })
566
+ }
567
+
568
+ fn get_previous_sibling(&self) -> Option<CommonmarkerNode> {
569
+ self.inner
570
+ .previous_sibling()
571
+ .map(|n| CommonmarkerNode { inner: n })
572
+ }
573
+
574
+ fn get_next_sibling(&self) -> Option<CommonmarkerNode> {
575
+ self.inner
576
+ .next_sibling()
577
+ .map(|n| CommonmarkerNode { inner: n })
578
+ }
579
+
580
+ fn get_first_child(&self) -> Option<CommonmarkerNode> {
581
+ self.inner
582
+ .first_child()
583
+ .map(|n| CommonmarkerNode { inner: n })
584
+ }
585
+
586
+ fn get_last_child(&self) -> Option<CommonmarkerNode> {
587
+ self.inner
588
+ .last_child()
589
+ .map(|n| CommonmarkerNode { inner: n })
590
+ }
591
+
592
+ fn prepend_child_node(&self, new_child: &CommonmarkerNode) -> Result<bool, magnus::Error> {
593
+ let node = new_child.inner.clone();
594
+ node.detach();
595
+ self.inner.prepend(node);
596
+
597
+ Ok(true)
598
+ }
599
+
600
+ fn append_child_node(&self, new_child: &CommonmarkerNode) -> Result<bool, magnus::Error> {
601
+ let node = new_child.inner.clone();
602
+ node.detach();
603
+ self.inner.append(node);
604
+
605
+ Ok(true)
606
+ }
607
+
608
+ fn detach_node(&self) -> Result<CommonmarkerNode, magnus::Error> {
609
+ let node = self.inner.make_copy().borrow().data.clone();
610
+ self.inner.detach();
611
+
612
+ Ok(CommonmarkerNode {
613
+ inner: Node::new(CommonmarkerAst { data: node }),
614
+ })
615
+ }
616
+
617
+ fn get_sourcepos(&self) -> Result<RHash, magnus::Error> {
618
+ let node = self.inner.borrow();
619
+
620
+ let result = RHash::new();
621
+ result.aset(Symbol::new("start_line"), node.data.sourcepos.start.line)?;
622
+ result.aset(
623
+ Symbol::new("start_column"),
624
+ node.data.sourcepos.start.column,
625
+ )?;
626
+ result.aset(Symbol::new("end_line"), node.data.sourcepos.end.line)?;
627
+ result.aset(Symbol::new("end_column"), node.data.sourcepos.end.column)?;
628
+
629
+ Ok(result)
630
+ }
631
+
632
+ fn replace_node(&self, new_node: &CommonmarkerNode) -> Result<bool, magnus::Error> {
633
+ self.insert_node_after(new_node)?;
634
+ match self.detach_node() {
635
+ Ok(_) => Ok(true),
636
+ Err(e) => Err(e),
637
+ }
638
+ }
639
+
640
+ fn insert_node_before(&self, new_sibling: &CommonmarkerNode) -> Result<bool, magnus::Error> {
641
+ let node = new_sibling.inner.clone();
642
+ node.detach();
643
+ self.inner.insert_before(node);
644
+
645
+ Ok(true)
646
+ }
647
+
648
+ fn insert_node_after(&self, new_sibling: &CommonmarkerNode) -> Result<bool, magnus::Error> {
649
+ let node = new_sibling.inner.clone();
650
+ node.detach();
651
+ self.inner.insert_after(node);
652
+
653
+ Ok(true)
654
+ }
655
+
656
+ fn get_url(&self) -> Result<String, magnus::Error> {
657
+ let node = self.inner.borrow();
658
+
659
+ match &node.data.value {
660
+ ComrakNodeValue::Link(link) => Ok(link.url.to_string()),
661
+ ComrakNodeValue::Image(image) => Ok(image.url.to_string()),
662
+ _ => Err(magnus::Error::new(
663
+ magnus::exception::type_error(),
664
+ "node is not an image or link node",
665
+ )),
666
+ }
667
+ }
668
+
669
+ fn set_url(&self, new_url: String) -> Result<bool, magnus::Error> {
670
+ let mut node = self.inner.borrow_mut();
671
+
672
+ match node.data.value {
673
+ ComrakNodeValue::Link(ref mut link) => {
674
+ link.url = new_url;
675
+ Ok(true)
676
+ }
677
+ ComrakNodeValue::Image(ref mut image) => {
678
+ image.url = new_url;
679
+ Ok(true)
680
+ }
681
+ _ => Err(magnus::Error::new(
682
+ magnus::exception::type_error(),
683
+ "node is not an image or link node",
684
+ )),
685
+ }
686
+ }
687
+
688
+ fn get_string_content(&self) -> Result<String, magnus::Error> {
689
+ let node = self.inner.borrow();
690
+
691
+ match node.data.value {
692
+ ComrakNodeValue::Code(ref code) => return Ok(code.literal.to_string()),
693
+ ComrakNodeValue::CodeBlock(ref code_block) => {
694
+ return Ok(code_block.literal.to_string())
695
+ }
696
+ _ => {}
697
+ }
698
+
699
+ match node.data.value.text() {
700
+ Some(s) => Ok(s.to_string()),
701
+ None => Err(magnus::Error::new(
702
+ magnus::exception::type_error(),
703
+ "node does not have string content",
704
+ )),
705
+ }
706
+ }
707
+
708
+ fn set_string_content(&self, new_content: String) -> Result<bool, magnus::Error> {
709
+ let mut node = self.inner.borrow_mut();
710
+
711
+ match node.data.value {
712
+ ComrakNodeValue::Code(ref mut code) => {
713
+ code.literal = new_content;
714
+ return Ok(true);
715
+ }
716
+ ComrakNodeValue::CodeBlock(ref mut code_block) => {
717
+ code_block.literal = new_content;
718
+ return Ok(true);
719
+ }
720
+ _ => {}
721
+ }
722
+
723
+ match node.data.value.text_mut() {
724
+ Some(s) => {
725
+ *s = new_content;
726
+ Ok(true)
727
+ }
728
+ None => Err(magnus::Error::new(
729
+ magnus::exception::type_error(),
730
+ "node does not have string content",
731
+ )),
732
+ }
733
+ }
734
+
735
+ fn get_title(&self) -> Result<String, magnus::Error> {
736
+ let node = self.inner.borrow();
737
+
738
+ match &node.data.value {
739
+ ComrakNodeValue::Link(link) => Ok(link.title.to_string()),
740
+ ComrakNodeValue::Image(image) => Ok(image.title.to_string()),
741
+ _ => Err(magnus::Error::new(
742
+ magnus::exception::type_error(),
743
+ "node is not an image or link node",
744
+ )),
745
+ }
746
+ }
747
+
748
+ fn set_title(&self, new_title: String) -> Result<bool, magnus::Error> {
749
+ let mut node = self.inner.borrow_mut();
750
+
751
+ match node.data.value {
752
+ ComrakNodeValue::Link(ref mut link) => {
753
+ link.title = new_title;
754
+ Ok(true)
755
+ }
756
+ ComrakNodeValue::Image(ref mut image) => {
757
+ image.title = new_title;
758
+ Ok(true)
759
+ }
760
+ _ => Err(magnus::Error::new(
761
+ magnus::exception::type_error(),
762
+ "node is not an image or link node",
763
+ )),
764
+ }
765
+ }
766
+
767
+ fn get_header_level(&self) -> Result<u8, magnus::Error> {
768
+ let node = self.inner.borrow();
769
+
770
+ match &node.data.value {
771
+ ComrakNodeValue::Heading(heading) => Ok(heading.level),
772
+ _ => Err(magnus::Error::new(
773
+ magnus::exception::type_error(),
774
+ "node is not a heading node",
775
+ )),
776
+ }
777
+ }
778
+
779
+ fn set_header_level(&self, new_level: u8) -> Result<bool, magnus::Error> {
780
+ let mut node = self.inner.borrow_mut();
781
+
782
+ match node.data.value {
783
+ ComrakNodeValue::Heading(ref mut heading) => {
784
+ heading.level = new_level;
785
+ Ok(true)
786
+ }
787
+ _ => Err(magnus::Error::new(
788
+ magnus::exception::type_error(),
789
+ "node is not a heading node",
790
+ )),
791
+ }
792
+ }
793
+
794
+ fn get_list_type(&self) -> Result<Symbol, magnus::Error> {
795
+ let node = self.inner.borrow();
796
+
797
+ match &node.data.value {
798
+ ComrakNodeValue::List(list) => match list.list_type {
799
+ comrak::nodes::ListType::Bullet => Ok(Symbol::new("bullet")),
800
+ comrak::nodes::ListType::Ordered => Ok(Symbol::new("ordered")),
801
+ },
802
+ _ => Err(magnus::Error::new(
803
+ magnus::exception::type_error(),
804
+ "node is not a list node",
805
+ )),
806
+ }
807
+ }
808
+
809
+ fn set_list_type(&self, new_type: Symbol) -> Result<bool, magnus::Error> {
810
+ let mut node = self.inner.borrow_mut();
811
+
812
+ match node.data.value {
813
+ ComrakNodeValue::List(ref mut list) => {
814
+ match new_type.to_string().as_str() {
815
+ "bullet" => list.list_type = comrak::nodes::ListType::Bullet,
816
+ "ordered" => list.list_type = comrak::nodes::ListType::Ordered,
817
+ _ => return Ok(false),
818
+ }
819
+ Ok(true)
820
+ }
821
+ _ => Err(magnus::Error::new(
822
+ magnus::exception::type_error(),
823
+ "node is not a list node",
824
+ )),
825
+ }
826
+ }
827
+
828
+ fn get_list_start(&self) -> Result<usize, magnus::Error> {
829
+ let node = self.inner.borrow();
830
+
831
+ match &node.data.value {
832
+ ComrakNodeValue::List(list) => Ok(list.start),
833
+ _ => Err(magnus::Error::new(
834
+ magnus::exception::type_error(),
835
+ "node is not a list node",
836
+ )),
837
+ }
838
+ }
839
+
840
+ fn set_list_start(&self, new_start: usize) -> Result<bool, magnus::Error> {
841
+ let mut node = self.inner.borrow_mut();
842
+
843
+ match node.data.value {
844
+ ComrakNodeValue::List(ref mut list) => {
845
+ list.start = new_start;
846
+ Ok(true)
847
+ }
848
+ _ => Err(magnus::Error::new(
849
+ magnus::exception::type_error(),
850
+ "node is not a list node",
851
+ )),
852
+ }
853
+ }
854
+
855
+ fn get_list_tight(&self) -> Result<bool, magnus::Error> {
856
+ let node = self.inner.borrow();
857
+
858
+ match &node.data.value {
859
+ ComrakNodeValue::List(list) => Ok(list.tight),
860
+ _ => Err(magnus::Error::new(
861
+ magnus::exception::type_error(),
862
+ "node is not a list node",
863
+ )),
864
+ }
865
+ }
866
+
867
+ fn set_list_tight(&self, new_tight: bool) -> Result<bool, magnus::Error> {
868
+ let mut node = self.inner.borrow_mut();
869
+
870
+ match node.data.value {
871
+ ComrakNodeValue::List(ref mut list) => {
872
+ list.tight = new_tight;
873
+ Ok(true)
874
+ }
875
+ _ => Err(magnus::Error::new(
876
+ magnus::exception::type_error(),
877
+ "node is not a list node",
878
+ )),
879
+ }
880
+ }
881
+
882
+ fn get_fence_info(&self) -> Result<String, magnus::Error> {
883
+ let node = self.inner.borrow();
884
+
885
+ match &node.data.value {
886
+ ComrakNodeValue::CodeBlock(code_block) => Ok(code_block.info.to_string()),
887
+ _ => Err(magnus::Error::new(
888
+ magnus::exception::type_error(),
889
+ "node is not a code block node",
890
+ )),
891
+ }
892
+ }
893
+
894
+ fn set_fence_info(&self, new_info: String) -> Result<bool, magnus::Error> {
895
+ let mut node = self.inner.borrow_mut();
896
+
897
+ match node.data.value {
898
+ ComrakNodeValue::CodeBlock(ref mut code_block) => {
899
+ code_block.info = new_info;
900
+ Ok(true)
901
+ }
902
+ _ => Err(magnus::Error::new(
903
+ magnus::exception::type_error(),
904
+ "node is not a code block node",
905
+ )),
906
+ }
907
+ }
908
+
909
+ fn to_html(&self, args: &[Value]) -> Result<String, magnus::Error> {
910
+ let args = scan_args::scan_args::<(), (), (), (), _, ()>(args)?;
911
+
912
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<RHash>, Option<RHash>), ()>(
913
+ args.keywords,
914
+ &[],
915
+ &["options", "plugins"],
916
+ )?;
917
+ let (rb_options, rb_plugins) = kwargs.optional;
918
+
919
+ let comrak_options = match format_options(rb_options) {
920
+ Ok(options) => options,
921
+ Err(err) => return Err(err),
922
+ };
923
+
924
+ let mut comrak_plugins = comrak::Plugins::default();
925
+
926
+ let syntect_adapter = match construct_syntax_highlighter_from_plugin(rb_plugins) {
927
+ Ok(Some(adapter)) => Some(adapter),
928
+ Ok(None) => None,
929
+ Err(err) => return Err(err),
930
+ };
931
+
932
+ match syntect_adapter {
933
+ Some(ref adapter) => comrak_plugins.render.codefence_syntax_highlighter = Some(adapter),
934
+ None => comrak_plugins.render.codefence_syntax_highlighter = None,
935
+ }
936
+
937
+ let arena: Arena<ComrakAstNode> = Arena::new();
938
+ fn iter_nodes<'a>(
939
+ arena: &'a Arena<comrak::arena_tree::Node<'a, RefCell<ComrakAst>>>,
940
+ node: &CommonmarkerNode,
941
+ ) -> &'a comrak::arena_tree::Node<'a, std::cell::RefCell<comrak::nodes::Ast>> {
942
+ let comrak_node: &'a mut ComrakAstNode = arena.alloc(ComrakNode::new(RefCell::new(
943
+ node.inner.borrow().data.clone(),
944
+ )));
945
+
946
+ for c in node.inner.children() {
947
+ let child = CommonmarkerNode { inner: c };
948
+ let child_node = iter_nodes(arena, &child);
949
+ comrak_node.append(child_node);
950
+ }
951
+
952
+ comrak_node
953
+ }
954
+
955
+ let comrak_root_node: ComrakNode<RefCell<ComrakAst>> =
956
+ ComrakNode::new(RefCell::new(self.inner.borrow().data.clone()));
957
+
958
+ for c in self.inner.children() {
959
+ let child = CommonmarkerNode { inner: c };
960
+
961
+ let new_child = iter_nodes(&arena, &child);
962
+
963
+ comrak_root_node.append(new_child);
964
+ }
965
+
966
+ let mut output = vec![];
967
+ match comrak::format_html_with_plugins(
968
+ &comrak_root_node,
969
+ &comrak_options,
970
+ &mut output,
971
+ &comrak_plugins,
972
+ ) {
973
+ Ok(_) => {}
974
+ Err(e) => {
975
+ return Err(magnus::Error::new(
976
+ magnus::exception::runtime_error(),
977
+ format!("cannot convert into html: {}", e),
978
+ ));
979
+ }
980
+ }
981
+
982
+ match std::str::from_utf8(&output) {
983
+ Ok(s) => Ok(s.to_string()),
984
+ Err(_e) => Err(magnus::Error::new(
985
+ magnus::exception::runtime_error(),
986
+ "cannot convert into utf-8",
987
+ )),
988
+ }
989
+ }
990
+
991
+ fn to_commonmark(&self, args: &[Value]) -> Result<String, magnus::Error> {
992
+ let args = scan_args::scan_args::<(), (), (), (), _, ()>(args)?;
993
+
994
+ let kwargs = scan_args::get_kwargs::<_, (), (Option<RHash>, Option<RHash>), ()>(
995
+ args.keywords,
996
+ &[],
997
+ &["options", "plugins"],
998
+ )?;
999
+ let (rb_options, rb_plugins) = kwargs.optional;
1000
+
1001
+ let _comrak_options = format_options(rb_options);
1002
+ let comrak_options = match format_options(rb_options) {
1003
+ Ok(options) => options,
1004
+ Err(err) => return Err(err),
1005
+ };
1006
+
1007
+ let mut comrak_plugins = comrak::Plugins::default();
1008
+
1009
+ let syntect_adapter = match construct_syntax_highlighter_from_plugin(rb_plugins) {
1010
+ Ok(Some(adapter)) => Some(adapter),
1011
+ Ok(None) => None,
1012
+ Err(err) => return Err(err),
1013
+ };
1014
+
1015
+ match syntect_adapter {
1016
+ Some(ref adapter) => comrak_plugins.render.codefence_syntax_highlighter = Some(adapter),
1017
+ None => comrak_plugins.render.codefence_syntax_highlighter = None,
1018
+ }
1019
+
1020
+ let arena: Arena<ComrakAstNode> = Arena::new();
1021
+ fn iter_nodes<'a>(
1022
+ arena: &'a Arena<comrak::arena_tree::Node<'a, RefCell<ComrakAst>>>,
1023
+ node: &CommonmarkerNode,
1024
+ ) -> &'a comrak::arena_tree::Node<'a, std::cell::RefCell<comrak::nodes::Ast>> {
1025
+ let comrak_node: &'a mut ComrakAstNode = arena.alloc(ComrakNode::new(RefCell::new(
1026
+ node.inner.borrow().data.clone(),
1027
+ )));
1028
+
1029
+ for c in node.inner.children() {
1030
+ let child = CommonmarkerNode { inner: c };
1031
+ let child_node = iter_nodes(arena, &child);
1032
+ comrak_node.append(child_node);
1033
+ }
1034
+
1035
+ comrak_node
1036
+ }
1037
+
1038
+ let comrak_root_node: ComrakNode<RefCell<ComrakAst>> =
1039
+ ComrakNode::new(RefCell::new(self.inner.borrow().data.clone()));
1040
+
1041
+ for c in self.inner.children() {
1042
+ let child = CommonmarkerNode { inner: c };
1043
+
1044
+ let new_child = iter_nodes(&arena, &child);
1045
+
1046
+ comrak_root_node.append(new_child);
1047
+ }
1048
+
1049
+ let mut output = vec![];
1050
+ match comrak::format_commonmark_with_plugins(
1051
+ &comrak_root_node,
1052
+ &comrak_options,
1053
+ &mut output,
1054
+ &comrak_plugins,
1055
+ ) {
1056
+ Ok(_) => {}
1057
+ Err(e) => {
1058
+ return Err(magnus::Error::new(
1059
+ magnus::exception::runtime_error(),
1060
+ format!("cannot convert into html: {}", e),
1061
+ ));
1062
+ }
1063
+ }
1064
+
1065
+ match std::str::from_utf8(&output) {
1066
+ Ok(s) => Ok(s.to_string()),
1067
+ Err(_e) => Err(magnus::Error::new(
1068
+ magnus::exception::runtime_error(),
1069
+ "cannot convert into utf-8",
1070
+ )),
1071
+ }
1072
+ }
1073
+ }
1074
+
1075
+ pub fn init(m_commonmarker: RModule) -> Result<(), magnus::Error> {
1076
+ let c_node = m_commonmarker
1077
+ .define_class("Node", magnus::class::object())
1078
+ .expect("cannot define class Commonmarker::Node");
1079
+
1080
+ c_node.define_singleton_method("new", function!(CommonmarkerNode::new, -1))?;
1081
+
1082
+ c_node.define_method("type", method!(CommonmarkerNode::type_to_symbol, 0))?;
1083
+ c_node.define_method("parent", method!(CommonmarkerNode::get_parent, 0))?;
1084
+ c_node.define_method("first_child", method!(CommonmarkerNode::get_first_child, 0))?;
1085
+ c_node.define_method("last_child", method!(CommonmarkerNode::get_last_child, 0))?;
1086
+ c_node.define_method(
1087
+ "previous_sibling",
1088
+ method!(CommonmarkerNode::get_previous_sibling, 0),
1089
+ )?;
1090
+ c_node.define_method(
1091
+ "next_sibling",
1092
+ method!(CommonmarkerNode::get_next_sibling, 0),
1093
+ )?;
1094
+
1095
+ c_node.define_method("node_to_html", method!(CommonmarkerNode::to_html, -1))?;
1096
+ c_node.define_method(
1097
+ "node_to_commonmark",
1098
+ method!(CommonmarkerNode::to_commonmark, -1),
1099
+ )?;
1100
+
1101
+ c_node.define_method("replace", method!(CommonmarkerNode::replace_node, 1))?;
1102
+
1103
+ c_node.define_method(
1104
+ "insert_before",
1105
+ method!(CommonmarkerNode::insert_node_before, 1),
1106
+ )?;
1107
+ c_node.define_method(
1108
+ "insert_after",
1109
+ method!(CommonmarkerNode::insert_node_after, 1),
1110
+ )?;
1111
+
1112
+ c_node.define_method(
1113
+ "prepend_child",
1114
+ method!(CommonmarkerNode::prepend_child_node, 1),
1115
+ )?;
1116
+ c_node.define_method(
1117
+ "append_child",
1118
+ method!(CommonmarkerNode::append_child_node, 1),
1119
+ )?;
1120
+
1121
+ c_node.define_method("delete", method!(CommonmarkerNode::detach_node, 0))?;
1122
+
1123
+ c_node.define_method(
1124
+ "source_position",
1125
+ method!(CommonmarkerNode::get_sourcepos, 0),
1126
+ )?;
1127
+
1128
+ c_node.define_method(
1129
+ "string_content",
1130
+ method!(CommonmarkerNode::get_string_content, 0),
1131
+ )?;
1132
+ c_node.define_method(
1133
+ "string_content=",
1134
+ method!(CommonmarkerNode::set_string_content, 1),
1135
+ )?;
1136
+
1137
+ c_node.define_method("url", method!(CommonmarkerNode::get_url, 0))?;
1138
+ c_node.define_method("url=", method!(CommonmarkerNode::set_url, 1))?;
1139
+ c_node.define_method("title", method!(CommonmarkerNode::get_title, 0))?;
1140
+ c_node.define_method("title=", method!(CommonmarkerNode::set_title, 1))?;
1141
+
1142
+ c_node.define_method(
1143
+ "header_level",
1144
+ method!(CommonmarkerNode::get_header_level, 0),
1145
+ )?;
1146
+ c_node.define_method(
1147
+ "header_level=",
1148
+ method!(CommonmarkerNode::set_header_level, 1),
1149
+ )?;
1150
+ c_node.define_method("list_type", method!(CommonmarkerNode::get_list_type, 0))?;
1151
+ c_node.define_method("list_type=", method!(CommonmarkerNode::set_list_type, 1))?;
1152
+ c_node.define_method("list_start", method!(CommonmarkerNode::get_list_start, 0))?;
1153
+ c_node.define_method("list_start=", method!(CommonmarkerNode::set_list_start, 1))?;
1154
+ c_node.define_method("list_tight", method!(CommonmarkerNode::get_list_tight, 0))?;
1155
+ c_node.define_method("list_tight=", method!(CommonmarkerNode::set_list_tight, 1))?;
1156
+ c_node.define_method("fence_info", method!(CommonmarkerNode::get_fence_info, 0))?;
1157
+ c_node.define_method("fence_info=", method!(CommonmarkerNode::set_fence_info, 1))?;
1158
+
1159
+ Ok(())
1160
+ }