commonmarker 0.23.10 → 2.0.2

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