commonmarker 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of commonmarker might be problematic. Click here for more details.

Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/ext/commonmarker/cmark/build/CMakeCache.txt +21 -1
  3. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeCCompiler.cmake +2 -2
  4. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeCXXCompiler.cmake +2 -2
  5. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeDetermineCompilerABI_C.bin +0 -0
  6. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeDetermineCompilerABI_CXX.bin +0 -0
  7. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CompilerIdC/a.out +0 -0
  8. data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CompilerIdCXX/a.out +0 -0
  9. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +6 -21
  10. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +114 -100
  11. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
  12. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/buffer.c.o +0 -0
  13. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
  14. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark_ctype.c.o +0 -0
  15. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
  16. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_href_e.c.o +0 -0
  17. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_e.c.o +0 -0
  18. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
  19. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
  20. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
  21. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
  22. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
  23. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
  24. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
  25. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/references.c.o +0 -0
  26. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/render.c.o +0 -0
  27. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
  28. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/utf8.c.o +0 -0
  29. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
  30. data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
  31. data/ext/commonmarker/cmark/src/scanners.c +32 -34
  32. data/ext/commonmarker/cmark/src/scanners.re +10 -4
  33. data/ext/commonmarker/cmark/test/normalize.py +11 -1
  34. data/ext/commonmarker/commonmarker.c +29 -0
  35. data/lib/commonmarker/version.rb +1 -1
  36. data/test/fixtures/dingus.md +10 -0
  37. data/test/test_attributes.rb +101 -0
  38. metadata +6 -3
  39. data/ext/commonmarker/commonmarker.c.orig +0 -1012
@@ -7,11 +7,17 @@ bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
7
7
  bufsize_t offset) {
8
8
  bufsize_t res;
9
9
  unsigned char *ptr = (unsigned char *)c->data;
10
- unsigned char lim = ptr[c->len];
10
+ unsigned char zero = '\0';
11
11
 
12
- ptr[c->len] = '\0';
13
- res = scanner(ptr + offset);
14
- ptr[c->len] = lim;
12
+ if (ptr == NULL) {
13
+ res = scanner(&zero);
14
+ } else {
15
+ unsigned char lim = ptr[c->len];
16
+
17
+ ptr[c->len] = '\0';
18
+ res = scanner(ptr + offset);
19
+ ptr[c->len] = lim;
20
+ }
15
21
 
16
22
  return res;
17
23
  }
@@ -15122,45 +15128,37 @@ bufsize_t _scan_html_tag(const unsigned char *p) {
15122
15128
  unsigned char yych;
15123
15129
  static const unsigned char yybm[] = {
15124
15130
  /* table 1 .. 8: 0 */
15125
- 0, 230, 230, 230, 230, 230, 230, 230, 230, 199, 199, 199, 199, 199,
15131
+ 0, 230, 230, 230, 230, 230, 230, 230, 230, 199, 199, 199, 199, 199, 230,
15126
15132
  230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
15127
- 230, 230, 230, 230, 199, 230, 70, 230, 230, 230, 230, 134, 230, 230,
15128
- 230, 230, 230, 254, 246, 230, 254, 254, 254, 254, 254, 254, 254, 254,
15129
- 254, 254, 246, 230, 198, 198, 196, 230, 230, 254, 254, 254, 254, 254,
15133
+ 230, 230, 230, 199, 230, 70, 230, 230, 230, 230, 134, 230, 230, 230,
15134
+ 230, 230, 254, 246, 230, 254, 254, 254, 254, 254, 254, 254, 254, 254,
15135
+ 254, 246, 230, 198, 198, 196, 230, 230, 254, 254, 254, 254, 254, 254,
15130
15136
  254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
15131
- 254, 254, 254, 254, 254, 254, 254, 230, 230, 226, 230, 246, 198, 254,
15137
+ 254, 254, 254, 254, 254, 254, 230, 230, 226, 230, 246, 198, 254, 254,
15132
15138
  254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
15133
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 230, 230, 230,
15134
- 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15135
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15136
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15137
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15138
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15139
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15140
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15141
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15142
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15143
- 0, 0, 0, 0,
15139
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 230, 230, 230, 230,
15140
+ 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15141
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15142
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15143
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15144
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15145
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15144
15146
  /* table 9 .. 11: 256 */
15145
- 0, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15147
+ 0, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15146
15148
  160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15147
15149
  160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15148
- 160, 160, 160, 32, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15149
- 160, 160, 160, 160, 160, 160, 160, 128, 160, 224, 224, 224, 224, 224,
15150
+ 160, 160, 32, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15151
+ 160, 160, 160, 160, 160, 160, 128, 160, 224, 224, 224, 224, 224, 224,
15150
15152
  224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
15151
- 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 160, 160, 160,
15153
+ 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 160, 160, 160, 160,
15152
15154
  160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15153
15155
  160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
15154
- 160, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15155
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15156
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15157
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15158
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15159
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15160
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15161
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15162
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15163
- 0, 0, 0, 0,
15156
+ 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15157
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15158
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15159
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15160
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15161
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15164
15162
  };
15165
15163
  yych = *(marker = p);
15166
15164
  if (yych <= '`') {
@@ -6,11 +6,17 @@ bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
6
6
  {
7
7
  bufsize_t res;
8
8
  unsigned char *ptr = (unsigned char *)c->data;
9
- unsigned char lim = ptr[c->len];
9
+ unsigned char zero = '\0';
10
10
 
11
- ptr[c->len] = '\0';
12
- res = scanner(ptr + offset);
13
- ptr[c->len] = lim;
11
+ if (ptr == NULL) {
12
+ res = scanner(&zero);
13
+ } else {
14
+ unsigned char lim = ptr[c->len];
15
+
16
+ ptr[c->len] = '\0';
17
+ res = scanner(ptr + offset);
18
+ ptr[c->len] = lim;
19
+ }
14
20
 
15
21
  return res;
16
22
  }
@@ -1,5 +1,14 @@
1
1
  # -*- coding: utf-8 -*-
2
- from html.parser import HTMLParser, HTMLParseError
2
+ from html.parser import HTMLParser
3
+
4
+ try:
5
+ from html.parser import HTMLParseError
6
+ except ImportError:
7
+ # HTMLParseError was removed in Python 3.5. It could never be
8
+ # thrown, so we define a placeholder instead.
9
+ class HTMLParseError(Exception):
10
+ pass
11
+
3
12
  from html.entities import name2codepoint
4
13
  import sys
5
14
  import re
@@ -12,6 +21,7 @@ whitespace_re = re.compile('\s+')
12
21
  class MyHTMLParser(HTMLParser):
13
22
  def __init__(self):
14
23
  HTMLParser.__init__(self)
24
+ self.convert_charrefs = False
15
25
  self.last = "starttag"
16
26
  self.in_pre = False
17
27
  self.output = ""
@@ -355,6 +355,34 @@ rb_node_get_type(VALUE self)
355
355
  return symbol;
356
356
  }
357
357
 
358
+ /*
359
+ * Public: Fetches the sourcepos of the node.
360
+ *
361
+ * Returns a {Hash} containing {Symbol} keys of the positions.
362
+ */
363
+ static VALUE
364
+ rb_node_get_sourcepos(VALUE self)
365
+ {
366
+ int start_line, start_column, end_line, end_column;
367
+ VALUE result;
368
+
369
+ cmark_node *node;
370
+ Data_Get_Struct(self, cmark_node, node);
371
+
372
+ start_line = cmark_node_get_start_line(node);
373
+ start_column = cmark_node_get_start_column(node);
374
+ end_line = cmark_node_get_end_line(node);
375
+ end_column = cmark_node_get_end_column(node);
376
+
377
+ result = rb_hash_new();
378
+ rb_hash_aset(result, CSTR2SYM("start_line"), INT2NUM(start_line));
379
+ rb_hash_aset(result, CSTR2SYM("start_column"), INT2NUM(start_column));
380
+ rb_hash_aset(result, CSTR2SYM("end_line"), INT2NUM(end_line));
381
+ rb_hash_aset(result, CSTR2SYM("end_column"), INT2NUM(end_column));
382
+
383
+ return result;
384
+ }
385
+
358
386
  /*
359
387
  * Public: Returns the type of the current pointer as a string.
360
388
  *
@@ -981,6 +1009,7 @@ void Init_commonmarker()
981
1009
  rb_define_method(rb_mNode, "string_content=", rb_node_set_string_content, 1);
982
1010
  rb_define_method(rb_mNode, "type", rb_node_get_type, 0);
983
1011
  rb_define_method(rb_mNode, "type_string", rb_node_get_type_string, 0);
1012
+ rb_define_method(rb_mNode, "sourcepos", rb_node_get_sourcepos, 0);
984
1013
  rb_define_method(rb_mNode, "delete", rb_node_unlink, 0);
985
1014
  rb_define_method(rb_mNode, "first_child", rb_node_first_child, 0);
986
1015
  rb_define_method(rb_mNode, "next", rb_node_next, 0);
@@ -1,3 +1,3 @@
1
1
  module CommonMarker
2
- VERSION = '0.4.1'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -0,0 +1,10 @@
1
+ ## Try CommonMark
2
+
3
+ You can try CommonMark here. This dingus is powered by
4
+ [commonmark.js](https://github.com/jgm/commonmark.js), the
5
+ JavaScript reference implementation.
6
+
7
+ 1. item one
8
+ 2. item two
9
+ - sublist
10
+ - sublist
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ class TestAttributes < Minitest::Test
4
+ def setup
5
+ contents = File.read(File.join(FIXTURES_DIR, 'dingus.md'))
6
+ @doc = CommonMarker.render_doc(contents.strip)
7
+ end
8
+
9
+ def test_sourcepos
10
+ sourcepos = []
11
+
12
+ @doc.walk do |node|
13
+ sourcepos << node.sourcepos
14
+ end
15
+
16
+ sourcepos.delete_if { |h| h.values.all? { |v| v == 0 } }
17
+
18
+ result = [
19
+ {
20
+ :start_line => 1,
21
+ :start_column => 1,
22
+ :end_line => 10,
23
+ :end_column => 12
24
+ },
25
+ {
26
+ :start_line => 1,
27
+ :start_column => 4,
28
+ :end_line => 1,
29
+ :end_column => 17
30
+ },
31
+ {
32
+ :start_line => 3,
33
+ :start_column => 1,
34
+ :end_line => 5,
35
+ :end_column => 36
36
+ },
37
+ {
38
+ :start_line => 7,
39
+ :start_column => 1,
40
+ :end_line => 10,
41
+ :end_column => 12
42
+ },
43
+ {
44
+ :start_line => 7,
45
+ :start_column => 1,
46
+ :end_line => 7,
47
+ :end_column => 11
48
+ },
49
+ {
50
+ :start_line => 7,
51
+ :start_column => 4,
52
+ :end_line => 7,
53
+ :end_column => 11
54
+ },
55
+ {
56
+ :start_line => 8,
57
+ :start_column => 1,
58
+ :end_line => 10,
59
+ :end_column => 12
60
+ },
61
+ {
62
+ :start_line => 8,
63
+ :start_column => 4,
64
+ :end_line => 8,
65
+ :end_column => 11
66
+ },
67
+ {
68
+ :start_line => 9,
69
+ :start_column => 4,
70
+ :end_line => 10,
71
+ :end_column => 12
72
+ },
73
+ {
74
+ :start_line => 9,
75
+ :start_column => 4,
76
+ :end_line => 9,
77
+ :end_column => 12
78
+ },
79
+ {
80
+ :start_line => 9,
81
+ :start_column => 6,
82
+ :end_line => 9,
83
+ :end_column => 12
84
+ },
85
+ {
86
+ :start_line => 10,
87
+ :start_column => 4,
88
+ :end_line => 10,
89
+ :end_column => 12
90
+ },
91
+ {
92
+ :start_line => 10,
93
+ :start_column => 6,
94
+ :end_line => 10,
95
+ :end_column => 12
96
+ }
97
+ ]
98
+
99
+ assert_equal result, sourcepos
100
+ end
101
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commonmarker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-26 00:00:00.000000000 Z
11
+ date: 2015-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-enum
@@ -348,7 +348,6 @@ files:
348
348
  - ext/commonmarker/cmark/wrappers/wrapper.rb
349
349
  - ext/commonmarker/cmark/wrappers/wrapper.rkt
350
350
  - ext/commonmarker/commonmarker.c
351
- - ext/commonmarker/commonmarker.c.orig
352
351
  - ext/commonmarker/commonmarker.h
353
352
  - ext/commonmarker/extconf.rb
354
353
  - lib/commonmarker.rb
@@ -358,6 +357,8 @@ files:
358
357
  - lib/commonmarker/version.rb
359
358
  - test/benchmark.rb
360
359
  - test/fixtures/curly.md
360
+ - test/fixtures/dingus.md
361
+ - test/test_attributes.rb
361
362
  - test/test_basics.rb
362
363
  - test/test_doc.rb
363
364
  - test/test_encoding.rb
@@ -396,6 +397,8 @@ summary: CommonMark parser and renderer. Written in C, wrapped in Ruby.
396
397
  test_files:
397
398
  - test/benchmark.rb
398
399
  - test/fixtures/curly.md
400
+ - test/fixtures/dingus.md
401
+ - test/test_attributes.rb
399
402
  - test/test_basics.rb
400
403
  - test/test_doc.rb
401
404
  - test/test_encoding.rb
@@ -1,1012 +0,0 @@
1
- #include "commonmarker.h"
2
- #include "cmark.h"
3
- #include "node.h"
4
- #include "houdini.h"
5
-
6
- static VALUE rb_mNodeError;
7
- static VALUE rb_mNode;
8
-
9
- static VALUE sym_document;
10
- static VALUE sym_blockquote;
11
- static VALUE sym_list;
12
- static VALUE sym_list_item;
13
- static VALUE sym_code_block;
14
- static VALUE sym_html;
15
- static VALUE sym_paragraph;
16
- static VALUE sym_header;
17
- static VALUE sym_hrule;
18
- static VALUE sym_text;
19
- static VALUE sym_softbreak;
20
- static VALUE sym_linebreak;
21
- static VALUE sym_code;
22
- static VALUE sym_inline_html;
23
- static VALUE sym_emph;
24
- static VALUE sym_strong;
25
- static VALUE sym_link;
26
- static VALUE sym_image;
27
-
28
- static VALUE sym_bullet_list;
29
- static VALUE sym_ordered_list;
30
-
31
- static void
32
- rb_mark_c_struct(void *data)
33
- {
34
- cmark_node *node = data;
35
- cmark_node *child;
36
-
37
- /* Mark the parent to make sure that the tree won't be freed as
38
- long as a child node is referenced. */
39
- cmark_node *parent = cmark_node_parent(node);
40
- if (parent) {
41
- void *user_data = cmark_node_get_user_data(parent);
42
- if (!user_data) {
43
- /* This should never happen. Child can nodes can only
44
- be returned from parents that already are
45
- associated with a Ruby object. */
46
- fprintf(stderr, "parent without user_data\n");
47
- abort();
48
- }
49
- rb_gc_mark((VALUE)user_data);
50
- }
51
-
52
- /* Mark all children to make sure their cached Ruby objects won't
53
- be freed. */
54
- for (child = cmark_node_first_child(node);
55
- child != NULL;
56
- child = cmark_node_next(child)
57
- ) {
58
- void *user_data = cmark_node_get_user_data(child);
59
- if (user_data)
60
- rb_gc_mark((VALUE)user_data);
61
- }
62
- }
63
-
64
- static void
65
- rb_free_c_struct(void *data)
66
- {
67
- /* It's important that the `free` function does not inspect the
68
- node data, as it may be part of a tree that was already freed. */
69
- cmark_node_free(data);
70
- }
71
-
72
- static VALUE
73
- rb_node_to_value(cmark_node *node)
74
- {
75
- void *user_data;
76
- RUBY_DATA_FUNC free_func;
77
- VALUE val;
78
-
79
- if (node == NULL)
80
- return Qnil;
81
-
82
- user_data = cmark_node_get_user_data(node);
83
- if (user_data)
84
- return (VALUE)user_data;
85
-
86
- /* Only free tree roots. */
87
- free_func = cmark_node_parent(node)
88
- ? NULL
89
- : rb_free_c_struct;
90
- val = Data_Wrap_Struct(rb_mNode, rb_mark_c_struct, free_func,
91
- node);
92
- cmark_node_set_user_data(node, (void *)val);
93
-
94
- return val;
95
- }
96
-
97
- /* If the node structure is changed, the finalizers must be updated. */
98
-
99
- static void
100
- rb_parent_added(VALUE val)
101
- {
102
- RDATA(val)->dfree = NULL;
103
- }
104
-
105
- static void
106
- rb_parent_removed(VALUE val)
107
- {
108
- RDATA(val)->dfree = rb_free_c_struct;
109
- }
110
-
111
- /*
112
- * Internal: Parses a Markdown string into an HTML string.
113
- *
114
- */
115
- static VALUE
116
- rb_markdown_to_html(VALUE self, VALUE rb_text, VALUE rb_options)
117
- {
118
- char *str;
119
- int len, options;
120
-
121
- Check_Type(rb_text, T_STRING);
122
- Check_Type(rb_options, T_FIXNUM);
123
-
124
- str = (char *)RSTRING_PTR(rb_text);
125
- len = RSTRING_LEN(rb_text);
126
- options = FIX2INT(rb_options);
127
-
128
- return rb_str_new2(cmark_markdown_to_html(str, len, options));
129
- }
130
-
131
- /*
132
- * Internal: Creates a node based on a node type.
133
- *
134
- * type - A {Symbol} representing the node to be created. Must be one of the following:
135
- * - `:document`
136
- * - `:blockquote`
137
- * - `:list`
138
- * - `:list_item`
139
- * - `:code_block`
140
- * - `:html`
141
- * - `:paragraph`
142
- * - `:header`
143
- * - `:hrule`
144
- * - `:text`
145
- * - `:softbreak`
146
- * - `:linebreak`
147
- * - `:code`
148
- * - `:inline_html`
149
- * - `:emph`
150
- * - `:strong`
151
- * - `:link`
152
- * - `:image`
153
- */
154
- static VALUE
155
- rb_node_new(VALUE self, VALUE type)
156
- {
157
- cmark_node_type node_type = 0;
158
- cmark_node *node;
159
-
160
- Check_Type(type, T_SYMBOL);
161
-
162
- if (type == sym_document)
163
- node_type = CMARK_NODE_DOCUMENT;
164
- else if (type == sym_blockquote)
165
- node_type = CMARK_NODE_BLOCK_QUOTE;
166
- else if (type == sym_list)
167
- node_type = CMARK_NODE_LIST;
168
- else if (type == sym_list_item)
169
- node_type = CMARK_NODE_ITEM;
170
- else if (type == sym_code_block)
171
- node_type = CMARK_NODE_CODE_BLOCK;
172
- else if (type == sym_html)
173
- node_type = CMARK_NODE_HTML;
174
- else if (type == sym_paragraph)
175
- node_type = CMARK_NODE_PARAGRAPH;
176
- else if (type == sym_header)
177
- node_type = CMARK_NODE_HEADER;
178
- else if (type == sym_hrule)
179
- node_type = CMARK_NODE_HRULE;
180
- else if (type == sym_text)
181
- node_type = CMARK_NODE_TEXT;
182
- else if (type == sym_softbreak)
183
- node_type = CMARK_NODE_SOFTBREAK;
184
- else if (type == sym_linebreak)
185
- node_type = CMARK_NODE_LINEBREAK;
186
- else if (type == sym_code)
187
- node_type = CMARK_NODE_CODE;
188
- else if (type == sym_inline_html)
189
- node_type = CMARK_NODE_INLINE_HTML;
190
- else if (type == sym_emph)
191
- node_type = CMARK_NODE_EMPH;
192
- else if (type == sym_strong)
193
- node_type = CMARK_NODE_STRONG;
194
- else if (type == sym_link)
195
- node_type = CMARK_NODE_LINK;
196
- else if (type == sym_image)
197
- node_type = CMARK_NODE_IMAGE;
198
- else
199
- rb_raise(rb_mNodeError, "invalid node of type %d", node_type);
200
-
201
- node = cmark_node_new(node_type);
202
- if (node == NULL) {
203
- rb_raise(rb_mNodeError, "could not create node of type %d", node_type);
204
- }
205
-
206
- return rb_node_to_value(node);
207
- }
208
-
209
- /*
210
- * Internal: Parses a Markdown string into a document.
211
- *
212
- */
213
- static VALUE
214
- rb_parse_document(VALUE self, VALUE rb_text, VALUE rb_len, VALUE rb_options)
215
- {
216
- char *text;
217
- int len, options;
218
- cmark_node *doc;
219
- Check_Type(rb_text, T_STRING);
220
- Check_Type(rb_len, T_FIXNUM);
221
- Check_Type(rb_options, T_FIXNUM);
222
-
223
- text = (char *)RSTRING_PTR(rb_text);
224
- len = FIX2INT(rb_len);
225
- options = FIX2INT(rb_options);
226
-
227
- doc = cmark_parse_document(text, len, options);
228
- if (doc == NULL) {
229
- rb_raise(rb_mNodeError, "error parsing document");
230
- }
231
-
232
- return rb_node_to_value(doc);
233
- }
234
-
235
- /*
236
- * Public: Fetch the string contents of the node.
237
- *
238
- * Returns a {String}.
239
- */
240
- static VALUE
241
- rb_node_get_string_content(VALUE self)
242
- {
243
- const char *text;
244
- cmark_node *node;
245
- Data_Get_Struct(self, cmark_node, node);
246
-
247
- text = cmark_node_get_literal(node);
248
- if (text == NULL) {
249
- rb_raise(rb_mNodeError, "could not get string content");
250
- }
251
-
252
- return rb_str_new2(text);
253
- }
254
-
255
- /*
256
- * Public: Sets the string content of the node.
257
- *
258
- * string - A {String} containing new content.
259
- *
260
- * Raises NodeError if the string content can't be set.
261
- */
262
- static VALUE
263
- rb_node_set_string_content(VALUE self, VALUE s)
264
- {
265
- char *text;
266
- cmark_node *node;
267
- Check_Type(s, T_STRING);
268
-
269
- Data_Get_Struct(self, cmark_node, node);
270
- text = StringValueCStr(s);
271
-
272
- if (!cmark_node_set_literal(node, text)) {
273
- rb_raise(rb_mNodeError, "could not set string content");
274
- }
275
-
276
- return Qnil;
277
- }
278
-
279
- /*
280
- * Public: Fetches the list type of the node.
281
- *
282
- * Returns a {Symbol} representing the node's type.
283
- */
284
- static VALUE
285
- rb_node_get_type(VALUE self)
286
- {
287
- int node_type;
288
- cmark_node *node;
289
- VALUE symbol;
290
-
291
- Data_Get_Struct(self, cmark_node, node);
292
-
293
- node_type = cmark_node_get_type(node);
294
- symbol = Qnil;
295
-
296
- switch (node_type) {
297
- case CMARK_NODE_DOCUMENT:
298
- symbol = sym_document;
299
- break;
300
- case CMARK_NODE_BLOCK_QUOTE:
301
- symbol = sym_blockquote;
302
- break;
303
- case CMARK_NODE_LIST:
304
- symbol = sym_list;
305
- break;
306
- case CMARK_NODE_ITEM:
307
- symbol = sym_list_item;
308
- break;
309
- case CMARK_NODE_CODE_BLOCK:
310
- symbol = sym_code_block;
311
- break;
312
- case CMARK_NODE_HTML:
313
- symbol = sym_html;
314
- break;
315
- case CMARK_NODE_PARAGRAPH:
316
- symbol = sym_paragraph;
317
- break;
318
- case CMARK_NODE_HEADER:
319
- symbol = sym_header;
320
- break;
321
- case CMARK_NODE_HRULE:
322
- symbol = sym_hrule;
323
- break;
324
- case CMARK_NODE_TEXT:
325
- symbol = sym_text;
326
- break;
327
- case CMARK_NODE_SOFTBREAK:
328
- symbol = sym_softbreak;
329
- break;
330
- case CMARK_NODE_LINEBREAK:
331
- symbol = sym_linebreak;
332
- break;
333
- case CMARK_NODE_CODE:
334
- symbol = sym_code;
335
- break;
336
- case CMARK_NODE_INLINE_HTML:
337
- symbol = sym_inline_html;
338
- break;
339
- case CMARK_NODE_EMPH:
340
- symbol = sym_emph;
341
- break;
342
- case CMARK_NODE_STRONG:
343
- symbol = sym_strong;
344
- break;
345
- case CMARK_NODE_LINK:
346
- symbol = sym_link;
347
- break;
348
- case CMARK_NODE_IMAGE:
349
- symbol = sym_image;
350
- break;
351
- default:
352
- rb_raise(rb_mNodeError, "invalid node type %d", node_type);
353
- }
354
-
355
- return symbol;
356
- }
357
-
358
- /*
359
- * Public: Returns the type of the current pointer as a string.
360
- *
361
- * Returns a {String}.
362
- */
363
- static VALUE
364
- rb_node_get_type_string(VALUE self)
365
- {
366
- cmark_node *node;
367
- Data_Get_Struct(self, cmark_node, node);
368
-
369
- return rb_str_new2(cmark_node_get_type_string(node));
370
- }
371
-
372
- /*
373
- * Internal: Unlinks the node from the tree (fixing pointers in
374
- * parents and siblings appropriately).
375
- */
376
- static VALUE
377
- rb_node_unlink(VALUE self)
378
- {
379
- cmark_node *node;
380
- Data_Get_Struct(self, cmark_node, node);
381
-
382
- cmark_node_unlink(node);
383
-
384
- rb_parent_removed(self);
385
-
386
- return Qnil;
387
- }
388
-
389
- /* Public: Fetches the first child of the node.
390
- *
391
- * Returns a {Node} if a child exists, `nil` otherise.
392
- */
393
- static VALUE
394
- rb_node_first_child(VALUE self)
395
- {
396
- cmark_node *node, *child;
397
- Data_Get_Struct(self, cmark_node, node);
398
-
399
- child = cmark_node_first_child(node);
400
-
401
- return rb_node_to_value(child);
402
- }
403
-
404
- /* Public: Fetches the next sibling of the node.
405
- *
406
- * Returns a {Node} if a sibling exists, `nil` otherwise.
407
- */
408
- static VALUE
409
- rb_node_next(VALUE self)
410
- {
411
- cmark_node *node, *next;
412
- Data_Get_Struct(self, cmark_node, node);
413
-
414
- next = cmark_node_next(node);
415
-
416
- return rb_node_to_value(next);
417
- }
418
-
419
- /*
420
- * Public: Inserts a node as a sibling before the current node.
421
- *
422
- * sibling - A sibling {Node} to insert.
423
- *
424
- * Returns `true` if successful.
425
- * Raises NodeError if the node can't be inserted.
426
- */
427
- static VALUE
428
- rb_node_insert_before(VALUE self, VALUE sibling)
429
- {
430
- cmark_node *node1, *node2;
431
- Data_Get_Struct(self, cmark_node, node1);
432
-
433
- Data_Get_Struct(sibling, cmark_node, node2);
434
-
435
- if (!cmark_node_insert_before(node1, node2)) {
436
- rb_raise(rb_mNodeError, "could not insert before");
437
- }
438
-
439
- rb_parent_added(sibling);
440
-
441
- return Qtrue;
442
- }
443
-
444
- /* Internal: Convert the node to an HTML string.
445
- *
446
- * Returns a {String}.
447
- */
448
- static VALUE
449
- rb_render_html(VALUE n, VALUE rb_options)
450
- {
451
- int options;
452
- cmark_node *node;
453
- Check_Type(rb_options, T_FIXNUM);
454
-
455
- options = FIX2INT(rb_options);
456
-
457
- Data_Get_Struct(n, cmark_node, node);
458
-
459
- return rb_str_new2(cmark_render_html(node, options));
460
- }
461
-
462
- /*
463
- * Public: Inserts a node as a sibling after the current node.
464
- *
465
- * sibling - A sibling {Node} to insert.
466
- *
467
- * Returns `true` if successful.
468
- * Raises NodeError if the node can't be inserted.
469
- */
470
- static VALUE
471
- rb_node_insert_after(VALUE self, VALUE sibling)
472
- {
473
- cmark_node *node1, *node2;
474
- Data_Get_Struct(self, cmark_node, node1);
475
-
476
- Data_Get_Struct(sibling, cmark_node, node2);
477
-
478
- if (!cmark_node_insert_after(node1, node2)) {
479
- rb_raise(rb_mNodeError, "could not insert after");
480
- }
481
-
482
- rb_parent_added(sibling);
483
-
484
- return Qtrue;
485
- }
486
-
487
- /*
488
- * Public: Inserts a node as the first child of the current node.
489
- *
490
- * child - A child {Node} to insert.
491
- *
492
- * Returns `true` if successful.
493
- * Raises NodeError if the node can't be inserted.
494
- */
495
- static VALUE
496
- rb_node_prepend_child(VALUE self, VALUE child)
497
- {
498
- cmark_node *node1, *node2;
499
- Data_Get_Struct(self, cmark_node, node1);
500
-
501
- Data_Get_Struct(child, cmark_node, node2);
502
-
503
- if (!cmark_node_prepend_child(node1, node2)) {
504
- rb_raise(rb_mNodeError, "could not prepend child");
505
- }
506
-
507
- rb_parent_added(child);
508
-
509
- return Qtrue;
510
- }
511
-
512
- /*
513
- * Public: Inserts a node as the last child of the current node.
514
- *
515
- * child - A child {Node} to insert.
516
- *
517
- * Returns `true` if successful.
518
- * Raises NodeError if the node can't be inserted.
519
- */
520
- static VALUE
521
- rb_node_append_child(VALUE self, VALUE child)
522
- {
523
- cmark_node *node1, *node2;
524
- Data_Get_Struct(self, cmark_node, node1);
525
-
526
- Data_Get_Struct(child, cmark_node, node2);
527
-
528
- if (!cmark_node_append_child(node1, node2)) {
529
- rb_raise(rb_mNodeError, "could not append child");
530
- }
531
-
532
- rb_parent_added(child);
533
-
534
- return Qtrue;
535
- }
536
-
537
- /* Public: Fetches the first child of the current node.
538
- *
539
- * Returns a {Node} if a child exists, `nil` otherise.
540
- */
541
- static VALUE
542
- rb_node_last_child(VALUE self)
543
- {
544
- cmark_node *node, *child;
545
- Data_Get_Struct(self, cmark_node, node);
546
-
547
- child = cmark_node_last_child(node);
548
-
549
- return rb_node_to_value(child);
550
- }
551
-
552
- /* Public: Fetches the parent of the current node.
553
- *
554
- * Returns a {Node} if a parent exists, `nil` otherise.
555
- */
556
- static VALUE
557
- rb_node_parent(VALUE self)
558
- {
559
- cmark_node *node, *parent;
560
- Data_Get_Struct(self, cmark_node, node);
561
-
562
- parent = cmark_node_parent(node);
563
-
564
- return rb_node_to_value(parent);
565
- }
566
-
567
- /* Public: Fetches the previous sibling of the current node.
568
- *
569
- * Returns a {Node} if a parent exists, `nil` otherise.
570
- */
571
- static VALUE
572
- rb_node_previous(VALUE self)
573
- {
574
- cmark_node *node, *previous;
575
- Data_Get_Struct(self, cmark_node, node);
576
-
577
- previous = cmark_node_previous(node);
578
-
579
- return rb_node_to_value(previous);
580
- }
581
-
582
- /*
583
- * Public: Gets the URL of the current node (must be a `:link` or `:image`).
584
- *
585
- * Returns a {String}.
586
- * Raises a NodeError if the URL can't be retrieved.
587
- */
588
- static VALUE
589
- rb_node_get_url(VALUE self)
590
- {
591
- const char *text;
592
- cmark_node *node;
593
- Data_Get_Struct(self, cmark_node, node);
594
-
595
- text = cmark_node_get_url(node);
596
- if (text == NULL) {
597
- rb_raise(rb_mNodeError, "could not get url");
598
- }
599
-
600
- return rb_str_new2(text);
601
- }
602
-
603
- /*
604
- * Public: Sets the URL of the current node (must be a `:link` or `:image`).
605
- *
606
- * url - A {String} representing the new URL
607
- *
608
- * Raises a NodeError if the URL can't be set.
609
- */
610
- static VALUE
611
- rb_node_set_url(VALUE self, VALUE url)
612
- {
613
- cmark_node *node;
614
- char *text;
615
- Check_Type(url, T_STRING);
616
-
617
- Data_Get_Struct(self, cmark_node, node);
618
- text = StringValueCStr(url);
619
-
620
- if (!cmark_node_set_url(node, text)) {
621
- rb_raise(rb_mNodeError, "could not set url");
622
- }
623
-
624
- return Qnil;
625
- }
626
-
627
- /*
628
- * Public: Gets the title of the current node (must be a `:link` or `:image`).
629
- *
630
- * Returns a {String}.
631
- * Raises a NodeError if the title can't be retrieved.
632
- */
633
- static VALUE
634
- rb_node_get_title(VALUE self)
635
- {
636
- const char *text;
637
- cmark_node *node;
638
- Data_Get_Struct(self, cmark_node, node);
639
-
640
- text = cmark_node_get_title(node);
641
- if (text == NULL) {
642
- rb_raise(rb_mNodeError, "could not get title");
643
- }
644
-
645
- return rb_str_new2(text);
646
- }
647
-
648
- /*
649
- * Public: Sets the title of the current node (must be a `:link` or `:image`).
650
- *
651
- * title - A {String} representing the new title
652
- *
653
- * Raises a NodeError if the title can't be set.
654
- */
655
- static VALUE
656
- rb_node_set_title(VALUE self, VALUE title)
657
- {
658
- char *text;
659
- cmark_node *node;
660
- Check_Type(title, T_STRING);
661
-
662
- Data_Get_Struct(self, cmark_node, node);
663
- text = StringValueCStr(title);
664
-
665
- if (!cmark_node_set_title(node, text)) {
666
- rb_raise(rb_mNodeError, "could not set title");
667
- }
668
-
669
- return Qnil;
670
- }
671
-
672
- /*
673
- * Public: Gets the header level of the current node (must be a `:header`).
674
- *
675
- * Returns a {Number} representing the header level.
676
- * Raises a NodeError if the header level can't be retrieved.
677
- */
678
- static VALUE
679
- rb_node_get_header_level(VALUE self)
680
- {
681
- int header_level;
682
- cmark_node *node;
683
- Data_Get_Struct(self, cmark_node, node);
684
-
685
- header_level = cmark_node_get_header_level(node);
686
-
687
- if (header_level == 0) {
688
- rb_raise(rb_mNodeError, "could not get header_level");
689
- }
690
-
691
- return INT2NUM(header_level);
692
- }
693
-
694
- /*
695
- * Public: Sets the header level of the current node (must be a `:header`).
696
- *
697
- * level - A {Number} representing the new header level
698
- *
699
- * Raises a NodeError if the header level can't be set.
700
- */
701
- static VALUE
702
- rb_node_set_header_level(VALUE self, VALUE level)
703
- {
704
- int l;
705
- cmark_node *node;
706
- Check_Type(level, T_FIXNUM);
707
-
708
- Data_Get_Struct(self, cmark_node, node);
709
- l = FIX2INT(level);
710
-
711
- if (!cmark_node_set_header_level(node, l)) {
712
- rb_raise(rb_mNodeError, "could not set header_level");
713
- }
714
-
715
- return Qnil;
716
- }
717
-
718
- /*
719
- * Public: Gets the list type of the current node (must be a `:list`).
720
- *
721
- * Returns a {Symbol}.
722
- * Raises a NodeError if the title can't be retrieved.
723
- */
724
- static VALUE
725
- rb_node_get_list_type(VALUE self)
726
- {
727
- int list_type;
728
- cmark_node *node;
729
- VALUE symbol;
730
- Data_Get_Struct(self, cmark_node, node);
731
-
732
- list_type = cmark_node_get_list_type(node);
733
-
734
- if (list_type == CMARK_BULLET_LIST) {
735
- symbol = sym_bullet_list;
736
- } else if (list_type == CMARK_ORDERED_LIST) {
737
- symbol = sym_ordered_list;
738
- } else {
739
- rb_raise(rb_mNodeError, "could not get list_type");
740
- }
741
-
742
- return symbol;
743
- }
744
-
745
- /*
746
- * Public: Sets the list type of the current node (must be a `:list`).
747
- *
748
- * level - A {Symbol} representing the new list type
749
- *
750
- * Raises a NodeError if the list type can't be set.
751
- */
752
- static VALUE
753
- rb_node_set_list_type(VALUE self, VALUE list_type)
754
- {
755
- int type = 0;
756
- cmark_node *node;
757
- Check_Type(list_type, T_SYMBOL);
758
-
759
- Data_Get_Struct(self, cmark_node, node);
760
-
761
- if (list_type == sym_bullet_list) {
762
- type = CMARK_BULLET_LIST;
763
- } else if (list_type == sym_ordered_list) {
764
- type = CMARK_ORDERED_LIST;
765
- } else {
766
- rb_raise(rb_mNodeError, "invalid list_type");
767
- }
768
-
769
- if (!cmark_node_set_list_type(node, type)) {
770
- rb_raise(rb_mNodeError, "could not set list_type");
771
- }
772
-
773
- return Qnil;
774
- }
775
-
776
- /*
777
- * Public: Gets the starting number the current node (must be an `:ordered_list`).
778
- *
779
- * Returns a {Number} representing the starting number.
780
- * Raises a NodeError if the starting number can't be retrieved.
781
- */
782
- static VALUE
783
- rb_node_get_list_start(VALUE self)
784
- {
785
- cmark_node *node;
786
- Data_Get_Struct(self, cmark_node, node);
787
-
788
- if (cmark_node_get_type(node) != CMARK_NODE_LIST
789
- || cmark_node_get_list_type(node) != CMARK_ORDERED_LIST) {
790
- rb_raise(rb_mNodeError,
791
- "can't get list_start for non-ordered list %d",
792
- cmark_node_get_list_type(node));
793
- }
794
-
795
- return INT2NUM(cmark_node_get_list_start(node));
796
- }
797
-
798
- /*
799
- * Public: Sets the starting number of the current node (must be an `:ordered_list`).
800
- *
801
- * level - A {Number} representing the new starting number
802
- *
803
- * Raises a NodeError if the starting number can't be set.
804
- */
805
- static VALUE
806
- rb_node_set_list_start(VALUE self, VALUE start)
807
- {
808
- int s;
809
- cmark_node *node;
810
- Check_Type(start, T_FIXNUM);
811
-
812
- Data_Get_Struct(self, cmark_node, node);
813
- s = FIX2INT(start);
814
-
815
- if (!cmark_node_set_list_start(node, s)) {
816
- rb_raise(rb_mNodeError, "could not set list_start");
817
- }
818
-
819
- return Qnil;
820
- }
821
-
822
- /*
823
- * Public: Gets the tight status the current node (must be a `:list`).
824
- *
825
- * Returns a `true` if the list is tight, `false` otherwise.
826
- * Raises a NodeError if the starting number can't be retrieved.
827
- */
828
- static VALUE
829
- rb_node_get_list_tight(VALUE self)
830
- {
831
- int flag;
832
- cmark_node *node;
833
- Data_Get_Struct(self, cmark_node, node);
834
-
835
- if (cmark_node_get_type(node) != CMARK_NODE_LIST) {
836
- rb_raise(rb_mNodeError,
837
- "can't get list_tight for non-list");
838
- }
839
-
840
- flag = cmark_node_get_list_tight(node);
841
-
842
- return flag ? Qtrue : Qfalse;
843
- }
844
-
845
- /*
846
- * Public: Sets the tight status of the current node (must be a `:list`).
847
- *
848
- * tight - A {Boolean} representing the new tightness
849
- *
850
- * Raises a NodeError if the tightness can't be set.
851
- */
852
- static VALUE
853
- rb_node_set_list_tight(VALUE self, VALUE tight)
854
- {
855
- int t;
856
- cmark_node *node;
857
- Data_Get_Struct(self, cmark_node, node);
858
- t = RTEST(tight);
859
-
860
- if (!cmark_node_set_list_tight(node, t)) {
861
- rb_raise(rb_mNodeError, "could not set list_tight");
862
- }
863
-
864
- return Qnil;
865
- }
866
-
867
- /*
868
- * Public: Gets the fence info of the current node (must be a `:code_block`).
869
- *
870
- * Returns a {String} representing the fence info.
871
- * Raises a NodeError if the fence info can't be retrieved.
872
- */
873
- static VALUE
874
- rb_node_get_fence_info(VALUE self)
875
- {
876
- const char *fence_info;
877
- cmark_node *node;
878
- Data_Get_Struct(self, cmark_node, node);
879
-
880
- fence_info = cmark_node_get_fence_info(node);
881
-
882
- if (fence_info == NULL) {
883
- rb_raise(rb_mNodeError, "could not get fence_info");
884
- }
885
-
886
- return rb_str_new2(fence_info);
887
- }
888
-
889
- /*
890
- * Public: Sets the fence info of the current node (must be a `:code_block`).
891
- *
892
- * info - A {String} representing the new fence info
893
- *
894
- * Raises a NodeError if the fence info can't be set.
895
- */
896
- static VALUE
897
- rb_node_set_fence_info(VALUE self, VALUE info)
898
- {
899
- char *text;
900
- cmark_node *node;
901
- Check_Type(info, T_STRING);
902
-
903
- Data_Get_Struct(self, cmark_node, node);
904
- text = StringValueCStr(info);
905
-
906
- if (!cmark_node_set_fence_info(node, text)) {
907
- rb_raise(rb_mNodeError, "could not set fence_info");
908
- }
909
-
910
- return Qnil;
911
- }
912
-
913
- /* Internal: Escapes href URLs safely. */
914
- static VALUE
915
- rb_html_escape_href(VALUE self, VALUE rb_text)
916
- {
917
- VALUE result;
918
- cmark_strbuf buf = GH_BUF_INIT;
919
-
920
- Check_Type(rb_text, T_STRING);
921
-
922
- if (houdini_escape_href(&buf, (const uint8_t *)RSTRING_PTR(rb_text), RSTRING_LEN(rb_text))) {
923
- result = (char *)cmark_strbuf_detach(&buf);
924
- return rb_str_new2(result);
925
- }
926
-
927
- return rb_text;
928
-
929
- }
930
-
931
- /* Internal: Escapes HTML content safely. */
932
- static VALUE
933
- rb_html_escape_html(VALUE self, VALUE rb_text)
934
- {
935
- VALUE result;
936
- cmark_strbuf buf = GH_BUF_INIT;
937
-
938
- Check_Type(rb_text, T_STRING);
939
-
940
- if (houdini_escape_html0(&buf, (const uint8_t *)RSTRING_PTR(rb_text), RSTRING_LEN(rb_text), 0)) {
941
- result = (char *)cmark_strbuf_detach(&buf);
942
- return rb_str_new2(result);
943
- }
944
-
945
- return rb_text;
946
- }
947
-
948
- __attribute__((visibility("default")))
949
- void Init_commonmarker()
950
- {
951
- VALUE module;
952
- sym_document = ID2SYM(rb_intern("document"));
953
- sym_blockquote = ID2SYM(rb_intern("blockquote"));
954
- sym_list = ID2SYM(rb_intern("list"));
955
- sym_list_item = ID2SYM(rb_intern("list_item"));
956
- sym_code_block = ID2SYM(rb_intern("code_block"));
957
- sym_html = ID2SYM(rb_intern("html"));
958
- sym_paragraph = ID2SYM(rb_intern("paragraph"));
959
- sym_header = ID2SYM(rb_intern("header"));
960
- sym_hrule = ID2SYM(rb_intern("hrule"));
961
- sym_text = ID2SYM(rb_intern("text"));
962
- sym_softbreak = ID2SYM(rb_intern("softbreak"));
963
- sym_linebreak = ID2SYM(rb_intern("linebreak"));
964
- sym_code = ID2SYM(rb_intern("code"));
965
- sym_inline_html = ID2SYM(rb_intern("inline_html"));
966
- sym_emph = ID2SYM(rb_intern("emph"));
967
- sym_strong = ID2SYM(rb_intern("strong"));
968
- sym_link = ID2SYM(rb_intern("link"));
969
- sym_image = ID2SYM(rb_intern("image"));
970
-
971
- sym_bullet_list = ID2SYM(rb_intern("bullet_list"));
972
- sym_ordered_list = ID2SYM(rb_intern("ordered_list"));
973
-
974
- module = rb_define_module("CommonMarker");
975
- rb_mNodeError = rb_define_class_under(module, "NodeError", rb_eStandardError);
976
- rb_mNode = rb_define_class_under(module, "Node", rb_cObject);
977
- rb_define_singleton_method(rb_mNode, "markdown_to_html", rb_markdown_to_html, 2);
978
- rb_define_singleton_method(rb_mNode, "new", rb_node_new, 1);
979
- rb_define_singleton_method(rb_mNode, "parse_document", rb_parse_document, 3);
980
- rb_define_method(rb_mNode, "string_content", rb_node_get_string_content, 0);
981
- rb_define_method(rb_mNode, "string_content=", rb_node_set_string_content, 1);
982
- rb_define_method(rb_mNode, "type", rb_node_get_type, 0);
983
- rb_define_method(rb_mNode, "type_string", rb_node_get_type_string, 0);
984
- rb_define_method(rb_mNode, "delete", rb_node_unlink, 0);
985
- rb_define_method(rb_mNode, "first_child", rb_node_first_child, 0);
986
- rb_define_method(rb_mNode, "next", rb_node_next, 0);
987
- rb_define_method(rb_mNode, "insert_before", rb_node_insert_before, 1);
988
- rb_define_method(rb_mNode, "_render_html", rb_render_html, 1);
989
- rb_define_method(rb_mNode, "insert_after", rb_node_insert_after, 1);
990
- rb_define_method(rb_mNode, "prepend_child", rb_node_prepend_child, 1);
991
- rb_define_method(rb_mNode, "append_child", rb_node_append_child, 1);
992
- rb_define_method(rb_mNode, "last_child", rb_node_last_child, 0);
993
- rb_define_method(rb_mNode, "parent", rb_node_parent, 0);
994
- rb_define_method(rb_mNode, "previous", rb_node_previous, 0);
995
- rb_define_method(rb_mNode, "url", rb_node_get_url, 0);
996
- rb_define_method(rb_mNode, "url=", rb_node_set_url, 1);
997
- rb_define_method(rb_mNode, "title", rb_node_get_title, 0);
998
- rb_define_method(rb_mNode, "title=", rb_node_set_title, 1);
999
- rb_define_method(rb_mNode, "header_level", rb_node_get_header_level, 0);
1000
- rb_define_method(rb_mNode, "header_level=", rb_node_set_header_level, 1);
1001
- rb_define_method(rb_mNode, "list_type", rb_node_get_list_type, 0);
1002
- rb_define_method(rb_mNode, "list_type=", rb_node_set_list_type, 1);
1003
- rb_define_method(rb_mNode, "list_start", rb_node_get_list_start, 0);
1004
- rb_define_method(rb_mNode, "list_start=", rb_node_set_list_start, 1);
1005
- rb_define_method(rb_mNode, "list_tight", rb_node_get_list_tight, 0);
1006
- rb_define_method(rb_mNode, "list_tight=", rb_node_set_list_tight, 1);
1007
- rb_define_method(rb_mNode, "fence_info", rb_node_get_fence_info, 0);
1008
- rb_define_method(rb_mNode, "fence_info=", rb_node_set_fence_info, 1);
1009
-
1010
- rb_define_singleton_method(rb_mNode, "html_escape_href", rb_html_escape_href, 1);
1011
- rb_define_singleton_method(rb_mNode, "html_escape_html", rb_html_escape_html, 1);
1012
- }