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.
- checksums.yaml +4 -4
- data/ext/commonmarker/cmark/build/CMakeCache.txt +21 -1
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeCCompiler.cmake +2 -2
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeCXXCompiler.cmake +2 -2
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CompilerIdC/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/2.8.10.1/CompilerIdCXX/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +6 -21
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +114 -100
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/buffer.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark_ctype.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_href_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/references.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/render.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/utf8.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
- data/ext/commonmarker/cmark/src/scanners.c +32 -34
- data/ext/commonmarker/cmark/src/scanners.re +10 -4
- data/ext/commonmarker/cmark/test/normalize.py +11 -1
- data/ext/commonmarker/commonmarker.c +29 -0
- data/lib/commonmarker/version.rb +1 -1
- data/test/fixtures/dingus.md +10 -0
- data/test/test_attributes.rb +101 -0
- metadata +6 -3
- data/ext/commonmarker/commonmarker.c.orig +0 -1012
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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
|
10
|
+
unsigned char zero = '\0';
|
11
11
|
|
12
|
-
ptr
|
13
|
-
|
14
|
-
|
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,
|
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,
|
15128
|
-
230, 230,
|
15129
|
-
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,
|
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,
|
15134
|
-
230,
|
15135
|
-
0,
|
15136
|
-
0,
|
15137
|
-
0,
|
15138
|
-
0,
|
15139
|
-
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,
|
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,
|
15149
|
-
160, 160, 160, 160, 160, 160,
|
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,
|
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,
|
15155
|
-
0,
|
15156
|
-
0,
|
15157
|
-
0,
|
15158
|
-
0,
|
15159
|
-
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
|
-
|
9
|
+
unsigned char zero = '\0';
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
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);
|
data/lib/commonmarker/version.rb
CHANGED
@@ -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
|
+
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-
|
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
|
-
}
|